:: commit 8b37fe66818a77b4f5721cc606f8261453f1065b

mintsuki <mintsuki@protonmail.com> — 2020-09-18 17:02

parents: 845889d7e1

Finish implementing SMP

diff --git a/STIVALE2.md b/STIVALE2.md
index 552a52ce..fef82551 100644
--- a/STIVALE2.md
+++ b/STIVALE2.md
@@ -392,7 +392,7 @@ struct stivale2_smp_info {
                                 // This MUST point to a valid stack of at least
                                 // 256 bytes in size, and 16-byte aligned.
     uint64_t goto_address;      // This address is polled by the started APs
-                                // until the kernel on the BSP performs an
+                                // until the kernel on another CPU performs an
                                 // atomic write to this field.
                                 // When that happens, bootloader code will
                                 // load up ESP/RSP with the stack value as
diff --git a/limine.bin b/limine.bin
index 2c3fdc74..2848241b 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2/lib/blib.h b/stage2/lib/blib.h
index 54e858b7..0510de67 100644
--- a/stage2/lib/blib.h
+++ b/stage2/lib/blib.h
@@ -11,7 +11,6 @@ int cpuid(uint32_t leaf, uint32_t subleaf,
 
 __attribute__((noreturn)) void panic(const char *fmt, ...);
 
-void pit_sleep(uint32_t pit_ticks);
 int pit_sleep_and_quit_on_keypress(uint32_t pit_ticks);
 
 void brewind(size_t count);
diff --git a/stage2/lib/sleep.asm b/stage2/lib/sleep.asm
index 75faad21..c0463e32 100644
--- a/stage2/lib/sleep.asm
+++ b/stage2/lib/sleep.asm
@@ -9,83 +9,6 @@ int_08_isr:
     iret
     bits 32
 
-global pit_sleep
-pit_sleep:
-    ; Hook int 0x08
-    mov edx, dword [0x08*4]
-    mov dword [0x80*4], edx
-    mov edx, int_08_isr
-    mov dword [0x08*4], int_08_isr
-
-    ; pit_ticks in edx
-    mov edx, dword [esp+4]
-
-    mov dword [int_08_ticks_counter], 0
-
-    ; Save non-scratch GPRs
-    push ebx
-    push esi
-    push edi
-    push ebp
-
-    ; Jump to real mode
-    jmp 0x08:.bits16
-  .bits16:
-    bits 16
-    mov ax, 0x10
-    mov ds, ax
-    mov es, ax
-    mov fs, ax
-    mov gs, ax
-    mov ss, ax
-    mov eax, cr0
-    and al, 0xfe
-    mov cr0, eax
-    jmp 0x00:.cszero
-  .cszero:
-    xor ax, ax
-    mov ds, ax
-    mov es, ax
-    mov fs, ax
-    mov gs, ax
-    mov ss, ax
-
-    sti
-
-  .loop:
-    cmp dword [int_08_ticks_counter], edx
-    je .done
-    jmp .loop
-
-  .done:
-    cli
-
-    ; Jump back to pmode
-    mov eax, cr0
-    or al, 1
-    mov cr0, eax
-    jmp 0x18:.bits32
-  .bits32:
-    bits 32
-    mov ax, 0x20
-    mov ds, ax
-    mov es, ax
-    mov fs, ax
-    mov gs, ax
-    mov ss, ax
-
-    ; Restore non-scratch GPRs
-    pop ebp
-    pop edi
-    pop esi
-    pop ebx
-
-    ; Dehook int 0x08
-    mov edx, dword [0x80*4]
-    mov dword [0x08*4], edx
-
-    ret
-
 global pit_sleep_and_quit_on_keypress
 pit_sleep_and_quit_on_keypress:
     ; Hook int 0x08
diff --git a/stage2/lib/smp.c b/stage2/lib/smp.c
index 072fbd5e..f9f23f74 100644
--- a/stage2/lib/smp.c
+++ b/stage2/lib/smp.c
@@ -4,6 +4,7 @@
 #include <lib/acpi.h>
 #include <lib/cio.h>
 #include <lib/blib.h>
+#include <lib/print.h>
 #include <lib/smp.h>
 #include <drivers/lapic.h>
 #include <mm/vmm64.h>
@@ -32,6 +33,11 @@ struct gdtr {
     uint32_t ptr;
 } __attribute__((packed));
 
+static void delay(uint32_t cycles) {
+    for (uint32_t i = 0; i < cycles; i++)
+        port_in_b(0x80);
+}
+
 void     smp_trampoline(void);
 extern   struct gdtr smp_tpl_gdt;
 struct   smp_information *smp_tpl_info_struct;
@@ -52,17 +58,17 @@ static bool smp_start_ap(uint8_t lapic_id, struct gdtr *gdtr,
     // Send the INIT IPI
     lapic_write(LAPIC_REG_ICR1, lapic_id << 24);
     lapic_write(LAPIC_REG_ICR0, 0x500);
-    pit_sleep(1);
+    delay(5000);
 
     // Send the Startup IPI
     lapic_write(LAPIC_REG_ICR1, lapic_id << 24);
     lapic_write(LAPIC_REG_ICR0, ((size_t)smp_trampoline / 4096) | 0x600);
 
-    for (int i = 0; i < 20; i++) {
-        pit_sleep(1);
+    for (int i = 0; i < 100; i++) {
         if (locked_read(&smp_tpl_booted_flag) == 1) {
             return true;
         }
+        delay(10000);
     }
 
     return false;
diff --git a/stage2/lib/smp.h b/stage2/lib/smp.h
index d0dcd143..0c96b2a3 100644
--- a/stage2/lib/smp.h
+++ b/stage2/lib/smp.h
@@ -9,6 +9,7 @@
 struct smp_information {
     uint32_t processor_id;
     uint32_t lapic_id;
+    uint64_t stack_addr;
     uint64_t goto_address;
 } __attribute__((packed));
 
diff --git a/stage2/lib/smp_trampoline.asm b/stage2/lib/smp_trampoline.asm
index 8fd0abef..fc467fd2 100644
--- a/stage2/lib/smp_trampoline.asm
+++ b/stage2/lib/smp_trampoline.asm
@@ -77,16 +77,62 @@ section .text
 
 bits 32
 parking32:
-    mov ecx, dword [smp_tpl_info_struct]
+    mov edi, dword [smp_tpl_info_struct]
     mov eax, 1
     lock xchg dword [smp_tpl_booted_flag], eax
-    mov eax, 0xcafebabe
-    jmp $
+
+    xor eax, eax
+  .loop:
+    lock xadd dword [edi + 16], eax
+    test eax, eax
+    jnz .out
+    pause
+    jmp .loop
+
+  .out:
+    mov esp, dword [edi + 8]
+    push 0
+    push eax
+    push edi
+    xor eax, eax
+    xor ebx, ebx
+    xor ecx, ecx
+    xor edx, edx
+    xor esi, esi
+    xor edi, edi
+    xor ebp, ebp
+    ret
 
 bits 64
 parking64:
-    mov ecx, dword [smp_tpl_info_struct]
+    mov edi, dword [smp_tpl_info_struct]
     mov eax, 1
     lock xchg dword [smp_tpl_booted_flag], eax
-    mov eax, 0xdeadbeef
-    jmp $
+
+    xor eax, eax
+  .loop:
+    lock xadd qword [rdi + 16], rax
+    test rax, rax
+    jnz .out
+    pause
+    jmp .loop
+
+  .out:
+    mov rsp, qword [rdi + 8]
+    push 0
+    push rax
+    xor rax, rax
+    xor rbx, rbx
+    xor rcx, rcx
+    xor rdx, rdx
+    xor rsi, rsi
+    xor rbp, rbp
+    xor r8,  r8
+    xor r9,  r9
+    xor r10, r10
+    xor r11, r11
+    xor r12, r12
+    xor r13, r13
+    xor r14, r14
+    xor r15, r15
+    ret
diff --git a/stage2/limine.h b/stage2/limine.h
index 6f9e2c11..ce1136b9 100644
--- a/stage2/limine.h
+++ b/stage2/limine.h
@@ -1,6 +1,6 @@
 #ifndef __LIMINE_H__
 #define __LIMINE_H__
 
-#define LIMINE_VERSION "0.4"
+#define LIMINE_VERSION "0.5"
 
 #endif
tab: 248 wrap: offon