diff --git a/kernel/Makefile b/kernel/Makefile index 8fc99a5..f78c1cc 100644 --- a/kernel/Makefile +++ b/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 diff --git a/kernel/acpi/power.c b/kernel/acpi/power.c index d1f9331..aae08fe 100644 --- a/kernel/acpi/power.c +++ b/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; diff --git a/kernel/drivers/pcie/pcie.c b/kernel/drivers/pcie/pcie.c index 5105b48..2d841c6 100644 --- a/kernel/drivers/pcie/pcie.c +++ b/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); } diff --git a/kernel/drivers/pcie/scan.c b/kernel/drivers/pcie/scan.c index ae65d5b..3488491 100644 --- a/kernel/drivers/pcie/scan.c +++ b/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; + } diff --git a/kernel/drivers/pcie/scan.h b/kernel/drivers/pcie/scan.h index 6fa6426..09d9647 100644 --- a/kernel/drivers/pcie/scan.h +++ b/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); diff --git a/kernel/entry.c b/kernel/entry.c index 8917b52..b30f92f 100644 --- a/kernel/entry.c +++ b/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); diff --git a/kernel/int/isr.c b/kernel/int/isr.c index 7de6e00..5d85f86 100644 --- a/kernel/int/isr.c +++ b/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) { diff --git a/kernel/int/pic.c b/kernel/int/pic.c index 90cb3bb..22dda63 100644 --- a/kernel/int/pic.c +++ b/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(); diff --git a/kernel/lib/panic.c b/kernel/lib/panic.c index bfcea45..8dda3c4 100644 --- a/kernel/lib/panic.c +++ b/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"); diff --git a/kernel/lib/string.c b/kernel/lib/string.c index b0d046f..bbb5652 100644 --- a/kernel/lib/string.c +++ b/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) diff --git a/kernel/memory/heap.c b/kernel/memory/heap.c index 4d4b7ca..a51c307 100644 --- a/kernel/memory/heap.c +++ b/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); } diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index a7433ff..f27ef60 100644 --- a/kernel/memory/paging.c +++ b/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); + } + */ } } diff --git a/kernel/memory/physical_allocator.c b/kernel/memory/physical_allocator.c index 37ce626..0bb5c2a 100644 --- a/kernel/memory/physical_allocator.c +++ b/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);