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/.gdb_history | 256 ---------------------------------------- src/bootloader/enter_kernel.asm | 6 +- src/bootloader/gdt.asm | 2 +- src/debug/gdbinit.gdb | 3 - src/include/int.h | 1 + src/include/paging.h | 2 +- src/include/smp.h | 22 ++++ src/include/smp_sync.h | 6 + src/indigo_os | Bin 42912 -> 43488 bytes 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 ++++++--- 18 files changed, 128 insertions(+), 304 deletions(-) delete mode 100644 src/.gdb_history (limited to 'src') diff --git a/src/.gdb_history b/src/.gdb_history deleted file mode 100644 index b48fd09..0000000 --- a/src/.gdb_history +++ /dev/null @@ -1,256 +0,0 @@ -thread 0 -thread 2 -print cores_active -context -thread 1 -next -c -print cores_active -print &cores_active -thread 2 -info reg rax -info reg rax -x 0x1000bf -quit -c -print smp_bootstrap_stackarray -print smp_bootstrap_corecount -print smp_bootstrap_bsp -quit -c -x smp_bootstrap_bsp -next -print smp_bootstrap_bsp -print smp_bootstrap_stackarray -print smp_bootstrap_bsp -print smp_bootstrap_bsp -info reg rax -x smp_bootstrap_corecount -print smp_bootstrap_corecount -quit -c -c -c -c -quit -c -c -c -c -quit -b panic -c -thread -threads -info thread -thread 2 -thread 3 -thread 4 -quit -c -c -c -c -quit -quit -print final_gdt_descriptor -print gdt -quit -quit -quit -nexti -thread 1 -thread 23 -thread 2 -print final_gdt_descriptor.offset -qut -quit -context -disassemble -x/i 0x80dd -quit -c -c -c -quit -next -print gdt -print gdtr -next -print gdtr -print/x (void *)&gdtr -print/x *(void *)&gdtr -hexdump &gdtr -print/x gdtr -quit -c -quit -next -stepi -info reg rax -info reg rdx -print final_gdt_descriptor -print &final_gdt_descriptor -quit -quit -c -quit -c -thread 2 -next -quit -c -thread -threads -info threads -thread 1 -c -c -quit -c -quit -c -quit -hb klog.c -hb klog -hb klog_init -c -quit -hb init_klog -c -print sizeof(serial_ports) -print sizeof(serial_ports) / sizeof(uint16_t) -quit -c -quit -c -quit -c -quit -hb smp_trampoline.asm:163 -c -print smp_kinit -x smp_kinit -next -info reg rax -x smp_kinit -nexti -x smp_kinit -info reg rax -quit -c -quit -c -quit -c -quit -c -quit -nexti -stepi -stepi -next -quit -b _putchar -c -stepi -next -c -c -quit -hb _putchar -c -c -next -step -print screen_buffer -x 0xffff8000000b80a0 -0xffff800000000000 -x 0xffff800000000000 -quit -c -quit -b _putchar -c -c -step -print screen_buffer -stepi -c -d -c -quit -next -quit -b init_klog -c -next -print serial_ports[0] -print/x serial_ports[0] -next -quit -quit -c -quit -c -quit -c -quit -c -quit -c -quit -b init_klog -c -print sizeof(serial_ports) / sizeof(uint16_t) -next -print p -next -make -quit -b init_klog -c -next -step -b _putchar -c -step -step -print (char *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2))) -print (char *)((uint64_t)0xb8000 + ((on_line * 160) + (on_char * 2))) -quit -c -quit -hb test_shit -c -c -c -c -c -c -c -c -c -c -c -c -quit -c -quit -quit -next -quit -quit -quit -info reg edx -nexti -info reg edx -quit -next -info reg ebx -quit -hb fuckyou -quit -c -info reg ebx -quit diff --git a/src/bootloader/enter_kernel.asm b/src/bootloader/enter_kernel.asm index bdf0a71..475e288 100644 --- a/src/bootloader/enter_kernel.asm +++ b/src/bootloader/enter_kernel.asm @@ -92,7 +92,9 @@ bits 64 mov rbp, 0 mov rsp, _kernel_stack_loc mov rax, QWORD kernel_init -;push QWORD 0 jmp rax -jmp $ +full_stop: +cli +hlt +jmp full_stop ret diff --git a/src/bootloader/gdt.asm b/src/bootloader/gdt.asm index 0e6d89b..a1d61e2 100644 --- a/src/bootloader/gdt.asm +++ b/src/bootloader/gdt.asm @@ -29,7 +29,7 @@ dq .gdt_start PROTECTED_CODE_SEGMENT equ .gdt_code - .gdt_start PROTECTED_DATA_SEGMENT equ .gdt_data - .gdt_start - +align 8 long_gdt: .gdt_start: ;and now we set up a temporary GDT creating a 1:1 mapping diff --git a/src/debug/gdbinit.gdb b/src/debug/gdbinit.gdb index 1a96557..a658ba4 100644 --- a/src/debug/gdbinit.gdb +++ b/src/debug/gdbinit.gdb @@ -1,9 +1,6 @@ target remote localhost:1234 symbol-file debug/debug_syms.o -hb fuckyou -hb kernel_init - define cs2bs print (1 << (5 + $arg0)) diff --git a/src/include/int.h b/src/include/int.h index 32313bd..6f1857b 100644 --- a/src/include/int.h +++ b/src/include/int.h @@ -79,6 +79,7 @@ void clear_int(); unsigned int alloc_idt(struct idt_entry *entry); void free_idt(unsigned int entry); void modify_idt(struct idt_entry *entry, unsigned int vector); +void smp_load_idt(); #endif diff --git a/src/include/paging.h b/src/include/paging.h index 302e567..5d33ca5 100644 --- a/src/include/paging.h +++ b/src/include/paging.h @@ -9,7 +9,7 @@ void unmap_lowmem(); size_t map_complete_physical(); -void debug_print_memory(); +void debug_pzone(); struct phys_map *init_pmap(size_t pagetable_size); diff --git a/src/include/smp.h b/src/include/smp.h index c4a675a..f4e3aa8 100644 --- a/src/include/smp.h +++ b/src/include/smp.h @@ -1,4 +1,26 @@ #ifndef SMP_INCLUDED #define SMP_INCLUDED +#include void smp_boot(); +extern uint8_t corecount; + +static inline void lock(uint8_t *lock) { + asm("mov al, 1\n" + "spinlock:\n" + "lock xchgb [%0], al\n" + "test al, al\n" + "pause\n" + "jnz spinlock\n" + ::"r"(lock):"al"); +} + +static inline void unlock(uint8_t *lock) { + asm("lock andb [%0], 0"::"r"(lock)); +} + +static inline void waitup(uint8_t *loto) { +} + +#define CREATE_LOTO(name) + #endif diff --git a/src/include/smp_sync.h b/src/include/smp_sync.h index 92784b8..93aac35 100644 --- a/src/include/smp_sync.h +++ b/src/include/smp_sync.h @@ -6,6 +6,7 @@ static inline void lock(uint8_t *lock) { "spinlock:\n" "lock xchgb [%0], al\n" "test al, al\n" + "pause\n" "jnz spinlock\n" ::"r"(lock):"al"); } @@ -14,4 +15,9 @@ static inline void unlock(uint8_t *lock) { asm("lock andb [%0], 0"::"r"(lock)); } +static inline void waitup(uint8_t *loto) { +} + +#define CREATE_LOTO(name) + #endif diff --git a/src/indigo_os b/src/indigo_os index 3fe850b..5f119d0 100755 Binary files a/src/indigo_os and b/src/indigo_os differ 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