Browse Source

nothing works

master
Mathieu Serandour 1 year ago
parent
commit
9af898a72e
  1. 2
      kernel/Makefile
  2. 1
      kernel/acpi/power.c
  3. 10
      kernel/drivers/pcie/pcie.c
  4. 278
      kernel/drivers/pcie/scan.c
  5. 2
      kernel/drivers/pcie/scan.h
  6. 8
      kernel/entry.c
  7. 6
      kernel/int/isr.c
  8. 12
      kernel/int/pic.c
  9. 16
      kernel/lib/panic.c
  10. 4
      kernel/lib/string.c
  11. 7
      kernel/memory/heap.c
  12. 33
      kernel/memory/paging.c
  13. 8
      kernel/memory/physical_allocator.c

2
kernel/Makefile

@ -25,7 +25,7 @@ INTERNALCFLAGS := -mgeneral-regs-only \
-I/opt/cross/include/ \
-I../lai/include \
-fpie \
-D BIGGER_FONT
# -D BIGGER_FONT
LAI_FILE := ../lai/lai.elf

1
kernel/acpi/power.c

@ -1,6 +1,7 @@
#include "power.h"
#include "../lib/assert.h"
#include "../drivers/ps2kb.h"
#include "../int/idt.h"
static void (*funcs[MAX_SHUTDOWN_FUNCS])(void);
static int n_funcs = 0;

10
kernel/drivers/pcie/pcie.c

@ -1,16 +1,16 @@
#include "pcie.h"
#include "scan.h"
#include "../../lib/logging.h"
#include "../../lib/dump.h"
#include "../../lib/assert.h"
#include "../../memory/heap.h"
#include "../../memory/paging.h"
#include "../../lib/string.h"
static struct pcie_device* devices = NULL;
static struct pcie_dev* devices = NULL;
static unsigned n_devices = 0;
void pcie_init(void) {
devices = pcie_scan();
devices = pcie_scan(&n_devices);
}

278
kernel/drivers/pcie/scan.c

@ -32,24 +32,36 @@ struct PCIE_config_space {
};
// higher bus number: could be 0xff
// if there is only one bus group
static size_t max_bus = 0;
struct PCIE_Descriptor pcie_descriptor = {0};
// 0 | group | bus | 0 | slot | 0 | func |
// | 2 | 8 | 1 | 3 | 1 | 3 |
// 16 8
__attribute__((pure))
// array of all installed devices' functions
static struct pcie_dev* found_devices = NULL;
static size_t n_found_devices = 0;
// we construct a linked list first
// so we need a node struct
struct early_device_desc {
uint16_t bus, device, function, domain;
struct PCIE_config_space* config_space;
struct early_device_desc* next;
};
// used to iterate over devices when scanning
struct early_device_desc head_node = {.next = NULL};
struct early_device_desc* current = &head_node;
////__attribute__((pure))
static struct resource get_bar_resource(
struct PCIE_config_space* cs,
unsigned i)
{
volatile uint32_t* bar_reg = (uint32_t*)&cs->bar[i];
uint32_t val = *bar_reg;
volatile uint64_t* bar_reg = (uint64_t*)&cs->bar[i];
uint64_t val = *bar_reg;
*bar_reg = ~1;
*bar_reg = ~0llu;
unsigned size = ~ *bar_reg + 1;
@ -57,13 +69,13 @@ static struct resource get_bar_resource(
return (struct resource) {
.addr = val,
.addr = (void *)val,
.size = size,
};
}
__attribute__((pure))
//__attribute__((pure))
static struct PCIE_config_space*
get_config_space_base(unsigned bus_group,
unsigned bus,
@ -72,12 +84,15 @@ static struct PCIE_config_space*
)
{
assert(bus_group < pcie_descriptor.size);
assert(bus_group == 0);
struct PCIE_busgroup* group_desc = &pcie_descriptor.array[bus_group];
return 0;
/*
return group_desc->address + (
(bus - group_desc->start_bus) << 20
| device << 15
| func << 12);
*/
}
@ -87,22 +102,86 @@ static int __attribute__((pure))
unsigned device,
unsigned func)
{
// struct PCIE_config_space* config_space =
// get_config_space_base(bus_group, bus,device,func);
return 8086;
//return config_space->vendorID;
}
static void insert(
unsigned bus_group,
unsigned bus,
unsigned device,
unsigned func)
{
/*
struct PCIE_config_space* config_space =
get_config_space_base(bus_group, bus,device,func);
return config_space->vendorID;
get_config_space_base(bus_group,
bus,
device,
func)
/*
->next = malloc(sizeof(struct early_device_desc));
current = current->next;
current->next = NULL;
// fill the new node
current->domain = bus_group;
current->bus = bus;
current->device = device;
current->function = func;
current->config_space = config_space;
*/
asm volatile("nop");
//printf("%2x:%2x:%2x.%2x - %lx", bus_group, bus, device, func);
//n_found_devices++;
}
struct early_device_descriptor {
uint16_t bus, device, function, domain;
struct PCIE_config_space* config_space;
};
// scan a single device
// adds its functions in the linked list
// if it finds some
static void scan_device(unsigned bus_group,
unsigned bus,
unsigned device)
{
// array of all installed devices' functions
static struct pcie_dev* found_devices = NULL;
static size_t n_found_devices = 0;
// if the first function doesn't exist, so
// does the device
uint16_t vendorID = get_vendorID(bus_group,
bus,
device,
0);
//return;
// no device!
if(vendorID == 0xFFFF)
return;
// a device is there!
insert(bus_group,
bus,
device,
0
);
// check for additionnal functions for this
// device
for(unsigned func = 1; func < 8; func++) {
if(get_vendorID(bus_group,
bus,
device,
func) != vendorID)
continue;
insert(bus_group,
bus,
device,
func
);
}
}
/**
* constructs the found_devices array
@ -111,36 +190,9 @@ static void scan_devices(void) {
// first create a linked list
// as we dont know how many devices are present
struct device_desc_node {
struct early_device_descriptor e;
struct device_desc_node* next;
};
// head of the list
struct device_desc_node ghost_node = {.next = NULL};
struct device_desc_node* current = &ghost_node;
// count the number of devices
void insert(
unsigned bus,
unsigned device,
unsigned func,
struct PCIE_config_space* config_space
)
{
current->next = malloc(sizeof(struct device_desc_node));
current = current->next;
current->next = NULL;
// fill the new node
current->e.bus = bus;
current->e.device = device;
current->e.function = func;
current->e.config_space = config_space;
n_found_devices++;
}
// count the number of devices
for(unsigned bus_group_i = 0;
bus_group_i < pcie_descriptor.size;
@ -157,67 +209,41 @@ static void scan_devices(void) {
{
for(unsigned device = 0; device < 32; device++) {
// if the first function doesn't exist, so does
// the device
uint16_t vendorID = get_vendorID(bus_group,
bus,
device,
0);
if(vendorID == 0xFFFF)
continue;
insert(bus,
device,
0,
get_config_space_base(bus_group,
bus,
device,
0)
);
for(unsigned func = 1; func < 8; func++) {
if(get_vendorID(bus_group,
bus,
device,
func) != vendorID)
continue;
insert(bus,
device,
func,
get_config_space_base(bus_group,
bus,
device,
func)
);
}
scan_device(bus_group,bus,device);
}
}
}
}
// create the output array
// with the
static void create_array(void) {
// now create the final array
found_devices = malloc(
n_found_devices
* sizeof(struct early_device_descriptor));
* sizeof(struct pcie_dev));
// now fill it and free the devices structure
struct pcie_dev* ptr = found_devices;
for(struct device_desc_node* device = ghost_node.next;
device != NULL;
) {
struct early_device_descriptor* early_desc = &device->e;
struct PCIE_config_space* cs = early_desc->config_space;
unsigned i = 0;
for(struct early_device_desc* device = head_node.next;
device != NULL;
device = device->next)
{
struct PCIE_config_space* cs = device->config_space;
*ptr = (struct pcie_dev) {
assert(i++ < n_found_devices);
*ptr++ = (struct pcie_dev) {
.bars = {
get_bar_resource(cs, 0),
get_bar_resource(cs, 1),
get_bar_resource(cs, 2),
0,//get_bar_resource(cs, 0),
0,//get_bar_resource(cs, 1),
0,//get_bar_resource(cs, 2),
},
.config_space = cs,
.driver = NULL,
@ -230,29 +256,20 @@ static void scan_devices(void) {
.revID = cs->revID,
},
.path = (pcie_path_t) {
.domain = early_desc->domain,
.bus = early_desc->bus,
.device = early_desc->device,
.func = early_desc->function,
}
.domain = device->domain,
.bus = device->bus,
.device = device->device,
.func = device->function,
},
};
struct resource bars[3];
struct dev_info info;
void* config_space;
pcie_path_t path;
struct driver* driver;
memcpy(ptr++, &device->e, sizeof(struct early_device_descriptor));
struct device_desc_node* next = device->next;
free(device);
device = next;
}
}
// identity map every page that might be a config space
static void identity_map_possible_config_spaces(void) {
for(unsigned i = 0; i < pcie_descriptor.size; i++) {
@ -273,7 +290,10 @@ static void identity_map_possible_config_spaces(void) {
static void identity_unmap_possible_config_spaces(void) {
for(unsigned i = 0; i < pcie_descriptor.size; i++)
unmap_pages((uint64_t)pcie_descriptor.array[i].address, 256 * 32 * 8);
unmap_pages(
(uint64_t)pcie_descriptor.array[i].address,
256 * 32 * 8
);
}
/**
@ -281,24 +301,23 @@ static void identity_unmap_possible_config_spaces(void) {
* we identity map the pcie configuration spaces
*
*/
struct pcie_device* pcie_scan(void) {
struct pcie_dev* pcie_scan(unsigned* size) {
log_debug("scanning pcie devices...");
// calculate the highest bus number
for(unsigned i = 0; i < pcie_descriptor.size; i++) {
// map the corresponding pages
if(pcie_descriptor.array[i].end_bus > max_bus)
max_bus = pcie_descriptor.array[i].end_bus;
}
log_debug("%u PCIE bus groups found", pcie_descriptor.size);
identity_map_possible_config_spaces();
log_debug("identity_map_possible_config_spaces()", pcie_descriptor.size);
//scan_devices();
log_debug("devices scanned", pcie_descriptor.size);
scan_devices();
//create_array();
//log_debug("memory shit done", pcie_descriptor.size);
for(unsigned i = 0; i < n_found_devices; i++) {
@ -318,8 +337,13 @@ struct pcie_device* pcie_scan(void) {
found_devices[i].info.vendorID
);
}
identity_unmap_possible_config_spaces();
// identity_unmap_possible_config_spaces();
log_info("found %u PCI Express devices", n_found_devices);
*size = n_found_devices;
return found_devices;
}

2
kernel/drivers/pcie/scan.h

@ -31,6 +31,6 @@ struct PCIE_Descriptor {
extern struct PCIE_Descriptor pcie_descriptor;
struct pcie_device* pcie_scan(void);
struct pcie_dev* pcie_scan(unsigned* size);

8
kernel/entry.c

@ -204,20 +204,24 @@ void _start(struct stivale2_struct *stivale2_struct) {
puts(&_binary_bootmessage_txt);
asm volatile("hlt");
printf("boot logs:\n");
puts(log_get());
log_flush();
pcie_init();
pic_init();
ps2kb_init();
void kbhandler(const struct kbevent* ev) {
if(ev->type == KEYRELEASED && ev->scancode == PS2KB_ESCAPE) {
shutdown();
__builtin_unreachable();
}
if(ev->type == KEYPRESSED && ev->keycode != 0) {
printf("%c", ev->keycode);
}
};
ps2kb_set_event_callback(kbhandler);

6
kernel/int/isr.c

@ -13,7 +13,7 @@ static void print_frame(char* buff, struct IFrame* interrupt_frame) {
sprintf(buff,
"RIP: %16lx\n"
"RSP: %16lx\n"
"CS: %16lx SS: %16lx\n"
"CS: %4lx SS: %4lx\n"
"\n"
"RFLAGS: %8lx\n",
interrupt_frame->RIP,
@ -38,7 +38,7 @@ __attribute__((interrupt)) void ISR_general_handler(struct IFrame* interrupt_fra
}
__attribute__((interrupt)) void ISR_error_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
(void) error_code;
printf("ERROR CODE: %lu\n", error_code);
printf("ERROR CODE: 0x%lx\n", error_code);
panic_handler("ISR_error_handler", interrupt_frame);
}
__attribute__((interrupt)) void ISR_div_by_zero_handler(struct IFrame* interrupt_frame) {
@ -89,7 +89,7 @@ __attribute__((interrupt)) void ISR_stack_segment_fault_handler(struct IFrame* i
}
__attribute__((interrupt)) void ISR_general_protection_fault_handler(struct IFrame* interrupt_frame, uint64_t error_code) {
(void) error_code;
printf("ERROR CODE: %lu\n", error_code);
printf("ERROR CODE: 0x%lx\n", error_code);
panic_handler("ISR_general_protection_fault_handler", interrupt_frame);
}
__attribute__((interrupt)) void ISR_page_fault_handler(struct IFrame* interrupt_frame, uint64_t error_code) {

12
kernel/int/pic.c

@ -1,5 +1,6 @@
#include "../lib/registers.h"
#include "../lib/assert.h"
#include "../lib/logging.h"
#include "pic.h"
@ -38,9 +39,17 @@ static void io_wait(void) {
static uint16_t mask = 0xff;
void pic_init(void) {
log_debug("init PIC...");
outb(0x80, 0);
// 0x343
// 34*2=68
// mask all interrupts
// if already initialized
outb(PIC1_DATA, 0xff);
outb(PIC2_DATA, 0xff);
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
// starts the initialization sequence (in cascade mode)
io_wait();
@ -50,6 +59,7 @@ void pic_init(void) {
// ICW2: Master PIC vector offset
io_wait();
outb(PIC2_DATA, 24);
// ICW2: Slave PIC vector offset
io_wait();

16
kernel/lib/panic.c

@ -3,6 +3,7 @@
#include "../drivers/terminal/terminal.h"
#include "../drivers/ps2kb.h"
#include "../acpi/power.h"
#include "../memory/vmap.h"
int zero = 0;
@ -17,16 +18,28 @@ static inline __attribute__((always_inline)) void stack_trace(void) {
puts("backtrace:\n");
for(unsigned i = 0; i < MAX_STACK_TRACE; i++) {
//printf("oui. %lx ", ptr);
if(*ptr == 0) // reached the top
break;
printf("\t%llx \n", *(ptr+1));
void* rip = *(ptr+1);
if(!is_kernel_memory(rip)) {
//maybe it is an exception error code
rip = *(ptr+2);
printf(" %llx - EXCEPTION\n", rip);
}
else
printf(" %llx\n", rip);
ptr = *ptr;
}
}
__attribute__((noreturn)) void panic(const char* panic_string) {
// checks if video is operationnal
if(get_terminal_handler() != NULL) {
terminal_set_colors(0xfff0a0, 0x400000);
@ -52,7 +65,6 @@ __attribute__((noreturn)) void panic(const char* panic_string) {
ps2kb_poll_wait_for_key(PS2KB_ESCAPE);
shutdown();
}
asm volatile("cli");
asm volatile("hlt");

4
kernel/lib/string.c

@ -223,6 +223,10 @@ void * memcpy (void* restrict _dest,
void * memset (void * _buf, int _ch, size_t n) {
uint8_t ch = *(uint8_t*)(&_ch);
uint8_t* buf = _buf;
for(;n > 0; --n)
*(buf++) = ch;
return buf;
// first unaligned bytes
for(;n > 0 && (uint64_t)buf % 8 != 0; --n)

7
kernel/memory/heap.c

@ -260,9 +260,6 @@ void heap_init(void) {
void* __attribute__((noinline)) malloc(size_t size) {
// align the size to assure that
// the whole structure is alligned
printf("malloc(%x)", size);
size = ((size + 7 ) / 8) * 8;
if(size < MIN_SEGMENT_SIZE)
size = MIN_SEGMENT_SIZE;
@ -425,9 +422,9 @@ void malloc_test(void) {
uint64_t size = 5;
for(int j = 0; j < 100; j++) {
for(int j = 0; j < 4000; j++) {
for(int i = 0; i < 128; i++) {
arr[i] = malloc(size % 1024);
arr[i] = malloc(size % (1024*1024));
size = (16807 * size) % ((1lu << 31) - 1);
}

33
kernel/memory/paging.c

@ -558,16 +558,18 @@ void map_pages(uint64_t physical_addr,
internal_map_pages(physical_addr, virtual_addr, count, flags);
}
// return 1 if any of the page entries is present
int is_range_unmapped(pte* page_table, unsigned begin, unsigned end) {
// return 1 iif the no entry is present in the range
static int is_table_empty(pte* page_table, unsigned begin, unsigned end) {
assert(begin <= end);
assert(end <= 512);
pte* translated = translate_address(page_table);
for(unsigned i = begin; i < end; i++) {
if(present_entry(translated[i]))
return 1;
return 0;
}
return 0;
return 1;
}
void unmap_pages(uint64_t virtual_addr, size_t count) {
@ -607,22 +609,23 @@ void unmap_pages(uint64_t virtual_addr, size_t count) {
panic(buff);
}
// actually erase the entry
*entry_ptr = 0;
pti++;
count--;
virtual_addr += 0x1000;
}
/*
unsigned end = pti;
// unmap the page map if empty
if(is_range_unmapped(pdentry, 0, begin))
continue;
if(is_range_unmapped(pdentry, end, 512))
continue;
// the page table contains no entry
// let's free it
physfree(pdentry);
if(is_table_empty(pdentry, 0, begin) &&
is_table_empty(pdentry, end, 512))
{
// the page table contains no entry
// let's free it
// physfree(pdentry);
}
*/
}
}

8
kernel/memory/physical_allocator.c

@ -107,6 +107,9 @@ static void init_memory_range(struct memory_range* range, uint64_t addr, size_t
// zero all the bit maps
memset(header->bitmap_level3, 0, 128+256+512+2048);
memset(addr+0x1000,
0xff,
range->length);
// we use one page per region for the header
header->available[0] = (length-1);
@ -137,11 +140,10 @@ void init_physical_allocator(const struct stivale2_struct_tag_memmap* memmap) {
for(unsigned i = 0; i < memmap->entries; i++) {
const struct stivale2_mmap_entry e = memmap->memmap[i];
// memory ranges in account
// dont take kernel & modules or acpi reclaimable
// memory ranges in account
if(e.type == STIVALE2_MMAP_USABLE) {
// ceil the size to the number of pages
@ -160,6 +162,7 @@ void init_physical_allocator(const struct stivale2_struct_tag_memmap* memmap) {
while(size > 0) {
size_t s;// the actual size of the current
if(size > MAX_SIZE)
@ -169,6 +172,7 @@ void init_physical_allocator(const struct stivale2_struct_tag_memmap* memmap) {
else
s = size;
struct memory_range* range = &memory_ranges_buffer[j++];
init_memory_range(range, base, s);

Loading…
Cancel
Save