From 1f71b9576db536af84155363e14fc49e92de2eef Mon Sep 17 00:00:00 2001 From: Brett Weiland Date: Sun, 29 Aug 2021 02:52:48 -0500 Subject: backup 8.29.21 --- src/.gdb_history | 326 ++++++++++++++++++++-------------------- src/bootloader/bootloader.asm | 1 - src/bootloader/enter_kernel.asm | 13 +- src/debug/gdbinit.gdb | 4 +- src/include/addr.h | 11 ++ src/include/int.h | 2 +- src/include/kernel.h | 10 +- src/include/klog.h | 20 +++ src/include/panic.h | 3 + src/include/printf.h | 1 + src/include/serial.h | 27 ---- src/include/smp_sync.h | 17 +++ src/indigo_os | Bin 42016 -> 42912 bytes src/kernel/acpi.c | 4 +- src/kernel/int.c | 22 +-- src/kernel/kernel.c | 33 ++-- src/kernel/klog.c | 180 ++++++++++++++++------ src/kernel/madt.c | 2 +- src/kernel/page.c | 2 +- src/kernel/panic.c | 12 +- src/kernel/printf.c | 17 ++- src/kernel/smp.c | 37 +++-- src/kernel/smp_trampoline.asm | 76 ++++++---- src/kernel/timer.c | 6 +- src/link.ld | 5 +- src/makefile | 14 -- 26 files changed, 487 insertions(+), 358 deletions(-) create mode 100644 src/include/addr.h create mode 100644 src/include/klog.h delete mode 100644 src/include/serial.h create mode 100644 src/include/smp_sync.h (limited to 'src') diff --git a/src/.gdb_history b/src/.gdb_history index df12f20..b48fd09 100644 --- a/src/.gdb_history +++ b/src/.gdb_history @@ -1,256 +1,256 @@ +thread 0 +thread 2 +print cores_active +context thread 1 next -thread 1 -step -print core_stacks -print core_stacks[0] -print core_stacks[1] -print core_stacks[2] -print core_stacks[3] -quit -c c +print cores_active +print &cores_active +thread 2 +info reg rax +info reg rax +x 0x1000bf quit -hb debug 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 -thread 1 -thread 2 -info reg rax -print smp_bootstrap_stackarray -print *smp_bootstrap_stackarray -print/x *smp_bootstrap_stackarray -inf ore g rax -print smp_bootstrap_array +x smp_bootstrap_corecount +print smp_bootstrap_corecount quit -hb debug c c -quit -hb debug c c -nexti -info reg ebx -info reg ebx quit -hb debug +c +c c c quit -hb debug +b panic +c +thread +threads +info thread +thread 2 +thread 3 +thread 4 +quit +c +c c c -stepi -info reg ebx -stepi -stepi -info reg rsp -stepi -info reg esp -info reg rsp -x rbx -info reg rbx -print smp_bootstrap_stackarray -print/x *smp_bootstrap_stackarray -info reg ebx quit quit -stepi -info reg cl -info reg ecx +print final_gdt_descriptor +print gdt +quit quit -next quit nexti -info reg ecx -stepi -info reg ebx +thread 1 +thread 23 +thread 2 +print final_gdt_descriptor.offset +qut +quit +context +disassemble +x/i 0x80dd quit c +c +c quit -stepi -info reg ebx -stepi -info reg bl -print smp_bootstrap_bsp -info reg bl -stepi -info reg bl -info reg ebx -x 0x80f0 -print (uint64_t *)0x80f0 -print (uint64_t*)0x80f0 -x 0x80f9 -stepi -stepi -info reg rsp -print smp_bootstrap_stackarray -print/x *smp_bootstrap_stackarray +next +print gdt +print gdtr +next +print gdtr +print/x (void *)&gdtr +print/x *(void *)&gdtr +hexdump &gdtr +print/x gdtr quit -info reg rax -info reg rax -x 0xbffde058 -print smp_bootstrap_bsp -print &smp_bootstrap_bsp -print smp_bootstrap_bsp -x 0x80f1 -print (uint64_t)*0x80f1 -x smp_bootstrap_bsp -smp_bootstrap_bsp -print smp_bootstrap_bsp -smp_bootstrap_stackarray -print smp_bootstrap_stackarray -print *smp_bootstrap_stackarray -print smp_bootstrap_stackarray[0] -print/x smp_bootstrap_stackarray[0] -print/x smp_bootstrap_stackarray[1] -print/x smp_bootstrap_stackarray[0] -info reg rax -print smp_bootstrap_stackarray +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 -stepi quit c +thread +threads +info threads +thread 1 +c +c quit c -stepi quit -hb smp_trampoline c -next -hb debug +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 -stepi quit c quit +hb smp_trampoline.asm:163 c +print smp_kinit +x smp_kinit next -info reg rsp -thread 2 -context +info reg rax +x smp_kinit +nexti +x smp_kinit +info reg rax quit +c quit c -info reg cl -info reg ecx quit c +quit +c +quit +nexti +stepi +stepi next quit -info reg rax +b _putchar c -info reg rax stepi -info rax -inf oreg rax -info reg rax -info reg rbx -x 0xffff8000bffde058 -x *0xffff8000bffde058 -print *0xffff8000bffde058 -print/x *0xffff8000bffde058 -print/x (uint64_t)*0xffff8000bffde058 -print/x (uint64_t)0xffff8000bffde058 -print/x (uint64_t)*0xffff8000bffde058 -print/x (uint64_t)0xffff8000bffde058 -print/x (uint64_t)0xffff8000bffde058[1] -print ((uint64_t)0xffff8000bffde058)[1] -print ((uint64_t *)0xffff8000bffde058)[1] -print ((uint64_t *)0xffff8000bffde058)[0] -print ((uint64_t *)0xffff8000bffde058)[1] -print/x ((uint64_t *)0xffff8000bffde058)[1] +next +c +c quit +hb _putchar c -nexti +c +next +step +print screen_buffer +x 0xffff8000000b80a0 +0xffff800000000000 +x 0xffff800000000000 quit c +quit +b _putchar +c +c +step +print screen_buffer stepi -stepi -info thread 0 -thread 1 +c +d c quit next -print cores_active -print cores.corecount +quit +b init_klog +c next -print cores.corecount -print cores_active +print serial_ports[0] +print/x serial_ports[0] next +quit +quit c -print cores_active -thread 0 -print cores_active -thread 1 -print cores_active quit c -stepi -info reg rax -thread 0 -thread 2 -print cores_active -context -thread 1 -next +quit 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 +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 -quit -b panic c -thread -threads -info thread -thread 2 -thread 3 -thread 4 -quit 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/bootloader.asm b/src/bootloader/bootloader.asm index 8e5fbeb..fcb39a7 100644 --- a/src/bootloader/bootloader.asm +++ b/src/bootloader/bootloader.asm @@ -1,7 +1,6 @@ [bits 16] [extern _kernel_sector_size] [extern _bootloader_stage1_size] -[extern _kernel_s1_loc] jmp stage0 times 3-($-$$) db 0x90 diff --git a/src/bootloader/enter_kernel.asm b/src/bootloader/enter_kernel.asm index ef2cd71..bdf0a71 100644 --- a/src/bootloader/enter_kernel.asm +++ b/src/bootloader/enter_kernel.asm @@ -1,4 +1,4 @@ -[extern main] +[extern kernel_init] [extern _kernel_stack_loc] [extern _kernel_page_size] enter_longmode: @@ -68,13 +68,14 @@ mov cr4, eax ;If it's not and we enable it, it will cause pagefaults on read mov eax, 0x80000001 cpuid -and edx, 1 << 20 -shr edx, 9 +mov ebx, edx +and ebx, 1 << 20 +shr ebx, 9 mov ecx, 0xc0000080 rdmsr -or eax, 1 << 8 | 1 << 11 -or eax, edx +or eax, 1 << 8 +or eax, ebx wrmsr mov eax, cr0 @@ -90,7 +91,7 @@ enter_kernel: bits 64 mov rbp, 0 mov rsp, _kernel_stack_loc -mov rax, QWORD main +mov rax, QWORD kernel_init ;push QWORD 0 jmp rax jmp $ diff --git a/src/debug/gdbinit.gdb b/src/debug/gdbinit.gdb index b6ad20a..1a96557 100644 --- a/src/debug/gdbinit.gdb +++ b/src/debug/gdbinit.gdb @@ -1,8 +1,8 @@ target remote localhost:1234 symbol-file debug/debug_syms.o -hb debug -hb smp_boot +hb fuckyou +hb kernel_init define cs2bs diff --git a/src/include/addr.h b/src/include/addr.h new file mode 100644 index 0000000..039d11d --- /dev/null +++ b/src/include/addr.h @@ -0,0 +1,11 @@ +#ifndef ADDR_INCLUDED +#define ADDR_INCLUDED + +#include + +//couldn't get symbols working, fix later +#define PA_OFFSET 0xffff800000000000 +#define TXT_OFFSET 0xffffffff80000000 +#define PHYS_TO_VIRT(addr) ((void *)((uintptr_t)(addr) | PA_OFFSET)) + +#endif diff --git a/src/include/int.h b/src/include/int.h index 8cc6a88..32313bd 100644 --- a/src/include/int.h +++ b/src/include/int.h @@ -7,7 +7,7 @@ void usleep(unsigned int us); -void init_interrupts(); +void init_interrupts_bsp(); typedef uint32_t *lapic_t; diff --git a/src/include/kernel.h b/src/include/kernel.h index db0f049..ea1223a 100644 --- a/src/include/kernel.h +++ b/src/include/kernel.h @@ -2,14 +2,10 @@ #define KERNEL -#define PA_OFFSET 0xffff800000000000 -#define TXT_OFFSET 0xffffffff80000000 -#define PHYS_TO_VIRT(addr) ((void *)(addr) + PA_OFFSET) - -#define DEV_EMAIL "brett_weiland@bpcspace.com" - -void multicore_main(); +void smp_kinit(); +void kernel_init(); +void kmain(); #endif diff --git a/src/include/klog.h b/src/include/klog.h new file mode 100644 index 0000000..1a6d3af --- /dev/null +++ b/src/include/klog.h @@ -0,0 +1,20 @@ +#ifndef _SERIAL_H_ +#define _SERIAL_H_ + +#include +#include + + + + + +void init_klog(); +void serial_out(uint16_t port, char *string); +void _putchar_serial(uint16_t port, char character); +void move_cursor(unsigned int x, unsigned int y); + + +void clear_screen(); + + +#endif diff --git a/src/include/panic.h b/src/include/panic.h index 6a987f4..43712a2 100644 --- a/src/include/panic.h +++ b/src/include/panic.h @@ -52,6 +52,9 @@ void panic(int reason, void *frame_p, struct registers *regs); #define KERNEL_PANIC_INVALID_RSDT 35 #define KERNEL_PANIC_INVALID_IOAPIC_VEC 36 #define KERNEL_PANIC_HPET_REQUIRED 37 +#define KERNEL_PANIC_SMP_FAILED 38 + +#define DEV_EMAIL "brett_weiland@bpcspace.com" diff --git a/src/include/printf.h b/src/include/printf.h index 6104ccf..0733f55 100644 --- a/src/include/printf.h +++ b/src/include/printf.h @@ -61,6 +61,7 @@ void _putchar(char character); int printf_(const char* format, ...); + /** * Tiny sprintf implementation * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! diff --git a/src/include/serial.h b/src/include/serial.h deleted file mode 100644 index ef5eecf..0000000 --- a/src/include/serial.h +++ /dev/null @@ -1,27 +0,0 @@ -//these com values are just guesses! Figure out how to find em later if you want -#ifndef _SERIAL_H_ -#define _SERIAL_H_ - -#include -#include - -#define COM1 0x3f8 -#define COM2 0x2f8 -#define COM3 0x3e8 -#define COM4 0x2e8 - - - -bool init_serial(uint16_t port); -void serial_out(uint16_t port, char *string); -void _putchar_serial(uint16_t port, char character); -void move_cursor(unsigned int x, unsigned int y); - - -//TODO fix shitty header -void _putchar_screen(char character); - -void clear_screen(); - - -#endif diff --git a/src/include/smp_sync.h b/src/include/smp_sync.h new file mode 100644 index 0000000..92784b8 --- /dev/null +++ b/src/include/smp_sync.h @@ -0,0 +1,17 @@ +#ifndef SMP_SYNC_INCLUDED +#define SMP_SYNC_INCLUDED + +static inline void lock(uint8_t *lock) { + asm("mov al, 1\n" + "spinlock:\n" + "lock xchgb [%0], al\n" + "test al, al\n" + "jnz spinlock\n" + ::"r"(lock):"al"); +} + +static inline void unlock(uint8_t *lock) { + asm("lock andb [%0], 0"::"r"(lock)); +} + +#endif diff --git a/src/indigo_os b/src/indigo_os index ca0db98..3fe850b 100755 Binary files a/src/indigo_os and b/src/indigo_os differ diff --git a/src/kernel/acpi.c b/src/kernel/acpi.c index e5a6e4d..0696e58 100644 --- a/src/kernel/acpi.c +++ b/src/kernel/acpi.c @@ -1,13 +1,13 @@ #include #include #include -#include #include -#include +#include #include #include #include #include +#include //finding rsdp diff --git a/src/kernel/int.c b/src/kernel/int.c index 34f1c78..5901a90 100644 --- a/src/kernel/int.c +++ b/src/kernel/int.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -44,7 +44,6 @@ .present = 1 \ }) -#define GDT_ADDR (uint64_t)PHYS_TO_VIRT(0x7e22) #define IOAPICR_VER 1 @@ -74,18 +73,10 @@ struct idt_reg { uint64_t offset; } __attribute__((packed)); -struct gdt_reg { - uint16_t size; - uint64_t offset; -} __attribute__((packed)); - struct idt_descriptor *idt; static struct idt_reg idtr; -struct gdt_reg gdtr = { - .size = 0x17, - .offset = GDT_ADDR -}; + lapic_t lapic; //would make this static but it's needed by timer.c @@ -211,7 +202,7 @@ void init_exceptions() { //void new_idt -void init_interrupts() { +void init_interrupts_bsp() { init_madt(); debug_madt(); lapic = get_lapic(); @@ -232,9 +223,7 @@ void init_interrupts() { bzero(&isr_bitmap, sizeof(isr_bitmap)); isr_bitmap[0] = (((uint64_t)1 << 32) - 1); - //set idt and new gdt - asm("lgdt [%0]\n" - "lidt [%1]\n":: "m"(gdtr), "m"(idtr)); + asm("lidt [%0]\n"::"m"(idtr)); //Spurrious Interrupt (permanent, required for APIC) @@ -251,3 +240,6 @@ void init_interrupts() { init_timer(); asm("sti\n"); } + +void smp_init_interrupts() { +} diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index d550e37..11df1f1 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,12 +1,12 @@ #include #include -#include +#include #include #include #include #include #include -#include +#include #include #include #include @@ -19,31 +19,36 @@ //testing headers #include +void kmain() { + PANIC(KERNEL_PANIC_KERNEL_RETURNED); +} -void multicore_main() { - printf("\nKernal started\n"); - asm("cli\nhlt"); +void smp_kinit() { + printf("\nKernal started on core\n"); //TODO get lapic working, then print core number + kmain(); } -void main() { -#ifndef SCREEN_OUTPUT - if(init_serial(COM1)) printf("\nKernal started on CPU 1!\n"); -#endif +//TODO move to global constructors +void kernel_init() { + size_t pmap_size; + get_mem_capabilities(); - init_pmap(map_complete_physical()); + pmap_size = map_complete_physical(); + init_klog(); + init_pmap(pmap_size); + printf("\nKernal started on CPU 1!\n"); find_root_sdp(); debug_acpi(); - init_interrupts(); + init_interrupts_bsp(); randinit(); smp_boot(); fix_stack(); - unmap_lowmem(); - - PANIC(KERNEL_PANIC_KERNEL_RETURNED); + //unmap_lowmem(); + kmain(); } diff --git a/src/kernel/klog.c b/src/kernel/klog.c index 52444b1..c62c4d3 100644 --- a/src/kernel/klog.c +++ b/src/kernel/klog.c @@ -1,57 +1,104 @@ #include -#include #include #include -#include +#include #include #include +#include -//README -//this file has some temporary workarounds until I get further into development -//this isn't going to be the serial driver I end up keeping +//right now, this program is simply for debuging. +//Later in development, we will hook it up to a TTY, impliment FCS, etc #define VIDEO_BUFFER PHYS_TO_VIRT(0xb8000) #define MAX_LOOPBACK_ATTEMPTS 20 -//later we'll set it up for interrupting instead of polling -bool init_serial(uint16_t port) { - outb_wait(port + 1, 0x00); - outb_wait(port + 2, 0x00); - outb_wait(port + 3, 0x80); - outb_wait(port + 0, 0x01); //here - outb_wait(port + 1, 0x00); - outb_wait(port + 3, 0x03); - outb_wait(port + 2, 0xc7); - outb_wait(port + 4, 0x0b); - outb_wait(port + 4, 0x1e); - - - //we shouldn't accept this as a loopback success. - //I'm making an exception because my dell desktop has a faulty serial port - //that requires some extra effort. - - uint8_t loopback_byte; - for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) { - outb_wait(port + 0, 0xae); // test char - loopback_byte = inb(port); - if(loopback_byte == 0xae) break; - } +#define KLOG_COM1 0 +#define KLOG_COM2 1 +#define KLOG_COM3 2 +#define KLOG_COM4 3 +#define KLOG_SCREEN 4 + +static int debug_output = KLOG_SCREEN; + +#define SERIAL_THR 0 //transmitter holding buffer +#define SERIAL_RBR 1 //receiving holding buffer +#define SERIAL_DLL 0 //divisor latch low byte +#define SERIAL_DLH 1 //divisor latch high byte +#define SERIAL_FCR 2 +#define SERIAL_IIR 2 +#define SERIAL_LCR 3 +#define SERIAL_MCR 4 +#define SERIAL_LSR 5 +#define SERIAL_MSR 6 +#define SERIAL_SR 7 + +#define COM1 0x3f8 +#define COM2 0x2f8 +#define COM3 0x3e8 +#define COM4 0x2e8 + +uint16_t serial_ports[4] = {COM1, COM2, COM3, COM4}; + +/** +enum com_ports { + COM1 = 0x3f8, + COM2 = 0x2f8, + COM3 = 0x3e8, + COM4 = 0x2e8 +}; +**/ + + +static bool detect_serial(uint16_t port) { + outb(port + SERIAL_FCR, 0xe7); + outb(port + SERIAL_SR, 0xba); + if((inb(port + SERIAL_IIR) & (1 << 6)) && (inb(port + SERIAL_SR) == 0xba)) { + outb_wait(port + 1, 0x00); + outb_wait(port + 2, 0x00); + outb_wait(port + 3, 0x80); + outb_wait(port + 0, 0x01); + outb_wait(port + 1, 0x00); + outb_wait(port + 3, 0x03); + outb_wait(port + 2, 0xc7); + outb_wait(port + 4, 0x0b); + outb_wait(port + 4, 0x1e); - if(loopback_byte != 0xae) { - //I'm sorry if these next few lines give you a stroke. They gave me one. + + uint8_t loopback_byte; + for(int attempts = 0; attempts < MAX_LOOPBACK_ATTEMPTS; attempts++) { + outb_wait(port + 0, 0xae); + loopback_byte = inb(port); + if(loopback_byte == 0xae) break; + } + + if(loopback_byte != 0xae) { + //you better delete this once you get tty drivers working... + int a = 0 / 0; + } - //My old Dell test desktop has disfunctional serial hardware that only works after a reboot. - //Seeing we don't have ACPI set up yet, we can't reboot without crashing. - //IM GOING TO REMOVE THIS ONCE I DEVELOP THE "REAL" SERIAL DRIVER!!!! - asm("mov rax, 0\n" - "div rax\n"); - return false; + outb_wait(port + 4, 0x0f); + return true; } - - outb_wait(port + 4, 0x0f); - return true; + return false; } + +//this function is going to be teleted after ttys work. +//but, for now, if a serial port is detected, it'll set debug_output to 0-3 (com port #). +//debug_output == 4 is for screen output. +void init_klog() { + for(unsigned int p = 0; p < (sizeof(serial_ports) / sizeof(uint16_t)); p++) { + if(detect_serial(serial_ports[p])) { + debug_output = p; + return; + } + } + debug_output = KLOG_SCREEN; + _putchar('\n'); +} + + + void _putchar_serial(uint16_t port, char msg) { while(!(inb(port + 5) & 0x20)); //wait for transmit to be done outb_wait(port, msg); @@ -80,13 +127,10 @@ void next_line() { } void move_cursor(unsigned int x, unsigned int y) { - //yeah yeah yeah, it doens't test for overflows... I'm gonna delete this once i get serial working - //on my second desktop on_char = x; on_line = y; } -//until we get serial working on hp void _putchar_screen(char msg) { if(on_char >= 80) { next_line(); @@ -94,7 +138,55 @@ void _putchar_screen(char msg) { next_line(); return; } - char *screen_buffer = (void *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2))); - *screen_buffer = msg; + *(char *)((uint64_t)VIDEO_BUFFER + ((on_line * 160) + (on_char * 2))) = msg; on_char++; } + + + +void _putchar(char character) { + if(debug_output < (sizeof(serial_ports) / sizeof(uint16_t))) { + _putchar_serial(serial_ports[debug_output], character); + } + else { + _putchar_screen(character); + } +} + + + + +/** + * Set the value "0xE7" to the FCR to test the status of the FIFO flags. +Read the value of the IIR to test for what flags actually got set. +If Bit 6 is set Then + If Bit 7 is set Then + If Bit 5 is set Then + UART is 16750 (64 bit fifo) + Else + UART is 16550A (idk why this matters, 16 bit fifo) + End If + Else + UART is 16550 (16 bit fifo) + End If +Else you know the chip doesn't use FIFO, so we need to check the scratch register + Set some arbitrary value like 0x2A to the Scratch Register. + If the arbitrary value comes back identical + UART is 16450 (idk why this matters, 1 byte at a time) + Else + UART is 8250 (one byte at a time) + End If +End If + +#define UART_16750 0 +#define UART_16550A 1 +#define UART_16550 2 +#define UART_16450 3 +#define UART_8250 4 + +#define KLOG_COM1 0 +#define KLOG_COM2 1 +#define KLOG_COM3 2 +#define KLOG_COM4 3 +#define KLOG_SCREEN 4 * 5 // 5 leaves enough space for com ports +**/ diff --git a/src/kernel/madt.c b/src/kernel/madt.c index 62e0535..adeb547 100644 --- a/src/kernel/madt.c +++ b/src/kernel/madt.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/kernel/page.c b/src/kernel/page.c index 734194c..3f6c4a8 100644 --- a/src/kernel/page.c +++ b/src/kernel/page.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/kernel/panic.c b/src/kernel/panic.c index 82a761f..d17c185 100644 --- a/src/kernel/panic.c +++ b/src/kernel/panic.c @@ -1,12 +1,15 @@ #include #include #include -#include -#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); #ifdef EASTEREGG_BLOATWARE printf("\nKernel PANIC!!!!!!!\n"); @@ -49,6 +52,9 @@ void panic(int reason, void *eframe_p, struct registers *regs) { // will fill wi break; case KERNEL_PANIC_HPET_REQUIRED: printf("\nHPET is required. \nIf you get this error, let know;\nif enough people share this issue, I'll impliment PIT usage.\n"); + case KERNEL_PANIC_SMP_FAILED: + printf("\nNot all cores booted successfully (see text before panic).\n"); + break; default: printf("\nUnknown panic code %i\n.", reason); break; diff --git a/src/kernel/printf.c b/src/kernel/printf.c index 8267755..b496bce 100644 --- a/src/kernel/printf.c +++ b/src/kernel/printf.c @@ -33,10 +33,11 @@ #include #include + #include "printf.h" //this is my own ugly library -#include +#include //and my options /** @@ -161,12 +162,7 @@ static inline void _out_char(char character, void* buffer, size_t idx, size_t ma { (void)buffer; (void)idx; (void)maxlen; if (character) { -#ifdef SCREEN_OUTPUT - _putchar_screen(character); -#else - _putchar_serial(COM1, character); // later we should figure out a way to not specifify exclusively com1 -#endif - + _putchar(character); } } @@ -874,17 +870,24 @@ 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, ...) { + //BRETT modification + lock(&printf_lock); va_list va; va_start(va, format); char buffer[1]; const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va); va_end(va); + unlock(&printf_lock); return ret; } +/////////////////////////////////////////////////////////////////////////////// + int sprintf_(char* buffer, const char* format, ...) { diff --git a/src/kernel/smp.c b/src/kernel/smp.c index 5796ab9..9714c91 100644 --- a/src/kernel/smp.c +++ b/src/kernel/smp.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -7,6 +7,7 @@ #include #include #include +#include #define LAPIC_ICR_LOW 192 #define LAPIC_ICR_HIGH 196 @@ -16,6 +17,7 @@ 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; struct icr_reg { uint8_t vector; @@ -30,22 +32,30 @@ struct icr_reg { unsigned int reserved_2:12; }__attribute__((packed)); -//1: get bsp number 2 -//2: get list of lapics 3 -//3: copy code 1 -//4: - static inline void write_icr(uint8_t dest, uint32_t message) { lapic[LAPIC_ICR_HIGH] = (uint32_t)dest << 24; lapic[LAPIC_ICR_LOW] = message; } +struct gdt_descriptor { + uint16_t size; + void *offset; +} __attribute__((packed)); + +static struct gdt_descriptor gdtr; + void smp_boot() { - uint8_t cores_active = 1; //TODO change in asm + uint8_t cores_active = 1; struct cores_info cores; struct icr_reg icr; get_coreinfo(&cores); + if(cores.corecount == 1) { + asm("sgdt [%0]"::"m"(gdtr)); + gdtr.offset = PHYS_TO_VIRT(gdtr.offset); + asm("lgdt [%0]"::"m"(gdtr)); + return; + } bzero(&icr, sizeof(icr)); void **core_stacks = malloc(sizeof(void *) * (cores.corecount - 1)); @@ -57,9 +67,7 @@ void smp_boot() { &__load_stop_smp_bootloader - &__load_start_smp_bootloader); smp_bootstrap_corecount = &cores_active; smp_bootstrap_bsp = cores.bsp; - smp_bootstrap_stackarray = (uint64_t)core_stacks; - - + smp_bootstrap_stackarray = (void *)core_stacks; icr.deliv_mode = 0b101; icr.dest_shorthand = 0b11; @@ -74,10 +82,9 @@ void smp_boot() { if(cores_active != cores.corecount) write_icr(0, *(uint32_t *)&icr); usleep(200); if(cores_active != cores.corecount) { - printf("NOT ALL CORES ONLINE\n"); - asm("cli\nhlt"); - } - else { - printf("%i!!!!!!\n", cores_active); + printf("Only %i cores online (expected %i)\n", cores_active, cores.corecount); //maybe add a panic + PANIC(KERNEL_PANIC_SMP_FAILED); } + printf("%i \n", cores_active); + //asm("lgdt [%0]\n"::"r"(PHYS_TO_VIRT(&final_gdt_descriptor))); TODO NOW } diff --git a/src/kernel/smp_trampoline.asm b/src/kernel/smp_trampoline.asm index 15b85e2..78303a3 100644 --- a/src/kernel/smp_trampoline.asm +++ b/src/kernel/smp_trampoline.asm @@ -1,13 +1,19 @@ global smp_bootstrap_stackarray global smp_bootstrap_bsp global smp_bootstrap_corecount +global final_gdt_descriptor -extern multicore_main +extern smp_kinit +extern _pmem_vaddr [bits 16] smp_trampoline: cli +in al, 0x92 +or al, 2 +out 0x92, al + xor ax, ax mov ds, ax lgdt [.gdt_descriptor_p] @@ -15,12 +21,11 @@ mov eax, cr0 or eax, 0x1 mov cr0, eax ; now in long mode -jmp 0x8:.smp_protected +jmp 0x8:smp_protected ;________________________________________________________________________________________ -;TODO find how to use old gdt .gdt_start_p: ; we need to start with a null gdt dd 0 dd 0 @@ -52,9 +57,9 @@ SMP_PROTECTED_DATA_SEGMENT equ .gdt_data_p - .gdt_start_p ;________________________________________________________________________________________ -.smp_protected: +smp_protected: -[bits 32] +bits 32 mov ax, SMP_PROTECTED_DATA_SEGMENT mov ds, ax mov ss, ax @@ -62,10 +67,8 @@ mov es, ax mov fs, ax mov gs, ax -lgdt [.gdt_descriptor_l] - -mov eax, 0x10000 ;TODO clarify _why_ this is a thing +mov eax, 0x10000 mov cr3, eax ;setting up misc features @@ -78,13 +81,15 @@ mov cr4, eax ;set NX and LME mov eax, 0x80000001 cpuid -and edx, 1 << 20 -shr edx, 9 +mov ebx, edx +and ebx, 1 << 20 +shr ebx, 9 mov ecx, 0xc0000080 rdmsr -or eax, 1 << 8 | 1 << 11 -or eax, edx +or eax, 1 << 8 +fuckyou: +or eax, ebx wrmsr @@ -94,14 +99,16 @@ or eax, 1 << 31 | 1 << 0; and ax, ~(1 << 2) mov cr0, eax +lgdt [final_gdt_descriptor] + -jmp SMP_LONG_CODE_SEGMENT:.counter +jmp SMP_LONG_CODE_SEGMENT:smp_longsetup ;________________________________________________________________________________________ -[bits 64] -;TODO do we really need all this? -.gdt_start_l: +bits 64 +final_gdt: +.start: ;and now we set up a temporary GDT creating a 1:1 mapping dw 0xffff dw 0 @@ -111,7 +118,7 @@ db 1 db 0 ;now for the code GDT: -.gdt_code_l: +.code: dw 0 ; segment limit 15:00 (I don't think this matters in 64 bit mode!) dw 0 ; base address 15:00 db 0 ; base address 23:16 @@ -119,7 +126,7 @@ db 10011010b db 00100000b db 0 -.gdt_data_l: +.data: dw 0 dw 0 db 0 @@ -127,17 +134,18 @@ db 10010010b db 00100000b db 0 -.gdt_end_l: ; later calculates offset in defs below +.end: ; later calculates offset in defs below -.gdt_descriptor_l: - dw .gdt_end_l - .gdt_start_l - 1 -dq .gdt_start_l +final_gdt_descriptor: + dw final_gdt.end - final_gdt.start - 1 +.offset: +dq final_gdt.start -SMP_LONG_CODE_SEGMENT equ .gdt_code_l - .gdt_start_l -SMP_LONG_DATA_SEGMENT equ .gdt_data_l - .gdt_start_l +SMP_LONG_CODE_SEGMENT equ final_gdt.code - final_gdt.start +SMP_LONG_DATA_SEGMENT equ final_gdt.data - final_gdt.start -.counter: +smp_longsetup: mov eax, 1 cpuid shr ebx, 24 @@ -146,19 +154,29 @@ jl .apic_below_bsp sub bl, 1 .apic_below_bsp: - mov rax, QWORD [smp_bootstrap_stackarray] -debug: mov rsp, QWORD [rax + rbx * 8] +mov rax, 0xffff800000000000 +;or QWORD [final_gdt_descriptor.offset], rax +;lgdt [final_gdt_descriptor] + +.inc_corecounter: + + mov rax, [smp_bootstrap_corecount] -inc BYTE [rax] +lock inc BYTE [rax] + -mov rax, multicore_main + +smp_enter_kernel: +mov rax, smp_kinit jmp rax align 8 smp_bootstrap_stackarray: dq 0 +smp_lock: dq 0 smp_bootstrap_bsp: db 0 smp_bootstrap_corecount: db 0 + times 512 - ($ - $$) db 0 diff --git a/src/kernel/timer.c b/src/kernel/timer.c index aed42ba..295abe2 100644 --- a/src/kernel/timer.c +++ b/src/kernel/timer.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include @@ -204,10 +204,8 @@ void init_timer() { uint32_t unused, cpuid_reg; __get_cpuid(0x80000007, &unused, &unused, &unused, &cpuid_reg); - //goto debug_tsc; if((cpuid_reg >> 8) & 1) { printf("Detected invariant TSC\n"); - //.1 second to calibrate, TODO do we need to check if the register is big enough? uint64_t hpet_ticks = (100000000000000 * (1 / (double)hpet_info.hpet_period)) + 0.5; printf("Starting TSC calibration...\n"); uint64_t volatile start_tsc, end_tsc; @@ -274,7 +272,7 @@ void init_timer() { apic_div = (((apic_div & 0b100) << 1) | (apic_div * 0b1011)); } - lapic_timer_lvt.vector = SPURRIOUS_VECTOR; //TODO CHANGE ME + lapic_timer_lvt.vector = SPURRIOUS_VECTOR; lapic_timer_lvt.timer_mode = LAPIC_TIMER_MODE_PERIODIC; lapic_timer_lvt.delivery_status = 0; lapic_timer_lvt.mask = 1; diff --git a/src/link.ld b/src/link.ld index 9d707b4..35c404a 100644 --- a/src/link.ld +++ b/src/link.ld @@ -1,6 +1,7 @@ SEARCH_DIR(objects) -_kernel_s1_loc = 0xffffffff80000000; +_txt_vaddr = 0xffffffff80000000; +_pmem_vaddr = 0xffff800000000000; _meminfo = 0x7000; _vbe_infoblock = 0x500; @@ -15,7 +16,7 @@ SECTIONS { smp_trampoline.o(.text) } - kernel _kernel_s1_loc : + kernel _txt_vaddr : AT (0 + SIZEOF(smp_bootloader) + SIZEOF(bootloader)) { EXCLUDE_FILE (*bootloader.o *smp_trampoline.o) *(.text .data .bss .rodata .comment .eh_frame) diff --git a/src/makefile b/src/makefile index 83876c2..03984ec 100644 --- a/src/makefile +++ b/src/makefile @@ -44,20 +44,6 @@ all: $(ASM_OBJFILES) $(C_OBJFILES) $(MISC_OBJFILES) bootloader.o smp_trampoline. isv.o: kernel/isv.c $(CC) $(CFLAGS) $(INC) -mgeneral-regs-only -MMD -MP -c kernel/isv.c -o objects/$@ -printf.o: kernel/printf.c -ifdef screen - $(CC) $(CFLAGS) $(INC) -MMD -MP -DSCREEN_OUTPUT -c kernel/printf.c -o objects/$@ -else - $(CC) $(CFLAGS) $(INC) -MMD -MP -c kernel/printf.c -o objects/$@ -endif - -kernel.o: kernel/kernel.c -ifdef screen - $(CC) $(CFLAGS) $(INC) -MMD -MP -DSCREEN_OUTPUT -c kernel/kernel.c -o objects/$@ -else - $(CC) $(CFLAGS) $(INC) -MMD -MP -c kernel/kernel.c -o objects/$@ -endif - %.o: kernel/%.c makefile $(CC) $(CFLAGS) $(INC) -MMD -MP -c $< -o objects/$@ -- cgit v1.2.3