From 175f5d3a0053665f7f318d595fd83386eb0f8213 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 modified: .gitignore modified: README.md deleted: 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: README.md --- src/kernel/smp.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'src/kernel/smp.c') 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 } -- cgit v1.2.3