From 2062e7070710989abf7271838efb99cbfbe511d0 Mon Sep 17 00:00:00 2001 From: Brett Weiland Date: Sun, 12 Sep 2021 12:53:33 -0500 Subject: SMP fixed for CPUs with defective cores modified: README.md modified: src/.gdb_history modified: src/bootloader/enter_kernel.asm modified: src/bootloader/gdt.asm modified: src/debug/gdbinit.gdb modified: src/include/int.h modified: src/include/paging.h modified: src/include/smp.h modified: src/include/smp_sync.h modified: src/indigo_os modified: src/kernel/int.c modified: src/kernel/kernel.c modified: src/kernel/klog.c modified: src/kernel/madt.c modified: src/kernel/page.c modified: src/kernel/panic.c modified: src/kernel/printf.c modified: src/kernel/smp.c modified: src/kernel/smp_trampoline.asm modified: .gitignore deleted: src/.gdb_history --- src/kernel/int.c | 4 +++- src/kernel/kernel.c | 11 ++++++--- src/kernel/klog.c | 4 ++-- src/kernel/madt.c | 2 +- src/kernel/page.c | 4 ++-- src/kernel/panic.c | 3 ++- src/kernel/printf.c | 3 ++- src/kernel/smp.c | 47 ++++++++++++++++++++++++++---------- src/kernel/smp_trampoline.asm | 56 +++++++++++++++++++++++++++++-------------- 9 files changed, 93 insertions(+), 41 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/int.c b/src/kernel/int.c index 5901a90..5db0b9a 100644 --- a/src/kernel/int.c +++ b/src/kernel/int.c @@ -199,8 +199,10 @@ void init_exceptions() { for(e = 10; e < 15; e++) idt[e] = KERNEL_IDT_DESC_GATE(fatal_hwexception_errcode); for(e = 18; e < 21; e++) idt[e] = KERNEL_IDT_DESC_GATE(fatal_hwexception); } -//void new_idt +void smp_load_idt() { + asm("lidt [%0]\n"::"m"(idtr)); +} void init_interrupts_bsp() { init_madt(); diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 11df1f1..ab60f18 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -15,16 +15,19 @@ #include #include #include +#include //testing headers -#include +//#include + void kmain() { PANIC(KERNEL_PANIC_KERNEL_RETURNED); } void smp_kinit() { - printf("\nKernal started on core\n"); //TODO get lapic working, then print core number + printf("Kernal started on core <<<<< \n"); + smp_load_idt(); kmain(); } @@ -47,8 +50,10 @@ void kernel_init() { randinit(); + clear_screen(); + debug_pzone(); smp_boot(); fix_stack(); - //unmap_lowmem(); + unmap_lowmem(); kmain(); } diff --git a/src/kernel/klog.c b/src/kernel/klog.c index c62c4d3..431c09b 100644 --- a/src/kernel/klog.c +++ b/src/kernel/klog.c @@ -109,10 +109,10 @@ static unsigned int on_line = 0; void clear_screen() { - char *screen_buffer = (void *)VIDEO_BUFFER; - for(unsigned int i = 0; i <= (80 * 25); i++) screen_buffer[i * 2] = ' '; on_char = 0; on_line = 0; + char *screen_buffer = (void *)VIDEO_BUFFER; + for(unsigned int i = 0; i <= (80 * 25); i++) screen_buffer[i * 2] = ' '; } void next_line() { diff --git a/src/kernel/madt.c b/src/kernel/madt.c index adeb547..25302f6 100644 --- a/src/kernel/madt.c +++ b/src/kernel/madt.c @@ -171,7 +171,7 @@ void get_coreinfo(struct cores_info *cores) { if(entry->type == LOCAL_APIC) { ap_info = (void *)entry + 2; if(ap_info->flags & 1) { - cores->apic_id[cores->corecount] = ap_info->processor_id; + cores->apic_id[cores->corecount] = ap_info->apic_id; cores->corecount++; } } diff --git a/src/kernel/page.c b/src/kernel/page.c index 3f6c4a8..dea3941 100644 --- a/src/kernel/page.c +++ b/src/kernel/page.c @@ -101,7 +101,7 @@ void unmap_lowmem() { entry[0].present = 0; } -void debug_print_memory() { +void debug_pzone() { struct memory_table *memtable = (void *)ZONE_MAP; printf(" __________________________________________________________________________\n"); printf("| type\tstart\t\t\tend\t\t\tsize\t\t |\n"); @@ -441,7 +441,7 @@ pmap_t *init_pmap(size_t pagetable_size) { pmap_size = (uint64_t)(pmap->buddy[pmap->max_buddy] + pmap->bsize[pmap->max_buddy]) - (uint64_t)pmap; first_pmap = pmap; //we spoof palloc into allocating from the specific required pmap. - palloc(pmap_size); + palloc(pmap_size); //TODO (MAJOR BUG) something isn't right, I don't think } } return pmap; diff --git a/src/kernel/panic.c b/src/kernel/panic.c index d17c185..06b37da 100644 --- a/src/kernel/panic.c +++ b/src/kernel/panic.c @@ -4,12 +4,13 @@ #include #include #include -#include +#include static uint8_t panic_lock = 0; void panic(int reason, void *eframe_p, struct registers *regs) { // will fill with debugging info latter lock(&panic_lock); + clear_screen(); #ifdef EASTEREGG_BLOATWARE printf("\nKernel PANIC!!!!!!!\n"); diff --git a/src/kernel/printf.c b/src/kernel/printf.c index b496bce..62261ec 100644 --- a/src/kernel/printf.c +++ b/src/kernel/printf.c @@ -33,6 +33,8 @@ #include #include +#include + #include "printf.h" @@ -870,7 +872,6 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const /////////////////////////////////////////////////////////////////////////////// -#include static uint8_t printf_lock = 0; int printf_(const char* format, ...) diff --git a/src/kernel/smp.c b/src/kernel/smp.c index 9714c91..ff08f93 100644 --- a/src/kernel/smp.c +++ b/src/kernel/smp.c @@ -16,8 +16,10 @@ extern lapic_t lapic; extern char __load_start_smp_bootloader, __load_stop_smp_bootloader; extern uint8_t *smp_bootstrap_corecount; extern uint8_t smp_bootstrap_bsp; -extern uint64_t *smp_bootstrap_stackarray; -extern char final_gdt_descriptor; +extern struct gdt_descriptor final_gdt_descriptor; +extern struct cpu_info *smp_stackarray_ptr; + +uint8_t corecount; //total corecount struct icr_reg { uint8_t vector; @@ -43,12 +45,21 @@ struct gdt_descriptor { void *offset; } __attribute__((packed)); +struct cpu_info { + uint8_t apic_id; + uint8_t secondary_bsp; //force 8 bits for alignment and consistency purposes + void *stack; +} __attribute__((packed)); + + static struct gdt_descriptor gdtr; void smp_boot() { uint8_t cores_active = 1; + uint8_t stack_i = 0, core_i; struct cores_info cores; struct icr_reg icr; + struct cpu_info *stackarray; get_coreinfo(&cores); if(cores.corecount == 1) { asm("sgdt [%0]"::"m"(gdtr)); @@ -58,16 +69,28 @@ void smp_boot() { } bzero(&icr, sizeof(icr)); - void **core_stacks = malloc(sizeof(void *) * (cores.corecount - 1)); - for(unsigned int s = 0; s < (cores.corecount - 1); s++) { - core_stacks[s] = palloc(0x1000); + corecount = cores.corecount; + + stackarray = malloc(sizeof(struct cpu_info) * (cores.corecount - 1)); + for(core_i = 0; core_i < cores.corecount; core_i++) { + if(cores.apic_id[core_i] == cores.bsp) continue; + stackarray[stack_i].apic_id = cores.apic_id[core_i]; + stackarray[stack_i].stack = palloc(0x1000); + stackarray[stack_i].secondary_bsp = (stack_i)? false : true; + stack_i++; + } + for(stack_i = 0; stack_i < (cores.corecount - 1); stack_i++) { + printf("%i's stack: %lx\n", stackarray[stack_i].apic_id, stackarray[stack_i].stack); } memcpy(PHYS_TO_VIRT((void *)0x8000), PHYS_TO_VIRT(&__load_start_smp_bootloader), &__load_stop_smp_bootloader - &__load_start_smp_bootloader); - smp_bootstrap_corecount = &cores_active; - smp_bootstrap_bsp = cores.bsp; - smp_bootstrap_stackarray = (void *)core_stacks; + + //we have to use the virtual address, even though lowmem is still mapped, + //so GCC doesn't complain about the mcmodel + *(uint8_t *)PHYS_TO_VIRT(&smp_bootstrap_bsp) = cores.bsp; + *(uint8_t **)PHYS_TO_VIRT(&smp_bootstrap_corecount) = &cores_active; + *(struct cpu_info **)PHYS_TO_VIRT(&smp_stackarray_ptr) = stackarray; icr.deliv_mode = 0b101; icr.dest_shorthand = 0b11; @@ -82,9 +105,9 @@ void smp_boot() { if(cores_active != cores.corecount) write_icr(0, *(uint32_t *)&icr); usleep(200); if(cores_active != cores.corecount) { - printf("Only %i cores online (expected %i)\n", cores_active, cores.corecount); //maybe add a panic - PANIC(KERNEL_PANIC_SMP_FAILED); + printf("Only %i cores online (expected %i)\n", cores_active, cores.corecount); + PANIC(KERNEL_PANIC_SMP_FAILED); //will replace this with warning once we push public } - printf("%i \n", cores_active); - //asm("lgdt [%0]\n"::"r"(PHYS_TO_VIRT(&final_gdt_descriptor))); TODO NOW + printf("All detected %i cores have booted\n", cores_active); + asm("lgdt [%0]\n"::"r"(PHYS_TO_VIRT(&final_gdt_descriptor))); //note that segment registers are not reloaded } diff --git a/src/kernel/smp_trampoline.asm b/src/kernel/smp_trampoline.asm index 78303a3..20c971e 100644 --- a/src/kernel/smp_trampoline.asm +++ b/src/kernel/smp_trampoline.asm @@ -1,10 +1,11 @@ -global smp_bootstrap_stackarray +global smp_stackarray_ptr global smp_bootstrap_bsp global smp_bootstrap_corecount global final_gdt_descriptor extern smp_kinit extern _pmem_vaddr +extern temp_debug_2 [bits 16] smp_trampoline: @@ -61,6 +62,7 @@ smp_protected: bits 32 mov ax, SMP_PROTECTED_DATA_SEGMENT +mov es, ax mov ds, ax mov ss, ax mov es, ax @@ -88,7 +90,6 @@ shr ebx, 9 mov ecx, 0xc0000080 rdmsr or eax, 1 << 8 -fuckyou: or eax, ebx wrmsr @@ -107,6 +108,7 @@ jmp SMP_LONG_CODE_SEGMENT:smp_longsetup ;________________________________________________________________________________________ bits 64 +align 8 final_gdt: .start: ;and now we set up a temporary GDT creating a 1:1 mapping @@ -136,7 +138,6 @@ db 0 .end: ; later calculates offset in defs below - final_gdt_descriptor: dw final_gdt.end - final_gdt.start - 1 .offset: @@ -149,33 +150,52 @@ smp_longsetup: mov eax, 1 cpuid shr ebx, 24 -cmp bl, BYTE [smp_bootstrap_bsp] -jl .apic_below_bsp -sub bl, 1 - -.apic_below_bsp: -mov rax, QWORD [smp_bootstrap_stackarray] -mov rsp, QWORD [rax + rbx * 8] - -mov rax, 0xffff800000000000 -;or QWORD [final_gdt_descriptor.offset], rax -;lgdt [final_gdt_descriptor] -.inc_corecounter: +mov rsi, [smp_stackarray_ptr] +.search_for_cpuinfo: +mov al, [rsi] +cmp al, bl +je smp_longsetup.cpuinfo_found +add rsi, 10 +jmp .search_for_cpuinfo +.cpuinfo_found: +mov bl, [rsi + 1] +mov rsp, QWORD [rsi + 2] ;core_stack.stack mov rax, [smp_bootstrap_corecount] lock inc BYTE [rax] - smp_enter_kernel: +test bl, bl +jz .wait_for_gdt + +; setting gdt +mov rax, 0xffff800000000000 +or QWORD [final_gdt_descriptor.offset], rax +mov QWORD [smp_lock], 0 + + +.wait_for_gdt: + +mov al, [smp_lock] +test al, al +pause +jnz .wait_for_gdt +lgdt [final_gdt_descriptor] + mov rax, smp_kinit jmp rax +cli +hlt +jmp $ + align 8 -smp_bootstrap_stackarray: dq 0 -smp_lock: dq 0 +smp_stackarray_ptr: dq 0 +smp_lock: dq 1 +screen_debug_pos: dq 0 smp_bootstrap_bsp: db 0 smp_bootstrap_corecount: db 0 -- cgit v1.2.3