Get secondary threads into long mode, our GDT
authorJack Miller <jack@codezen.org>
Fri, 25 Mar 2016 03:56:07 +0000 (22:56 -0500)
committerJack Miller <jack@codezen.org>
Fri, 25 Mar 2016 21:59:17 +0000 (16:59 -0500)
Next step is to get the separate CPU stacks setup.

asm/realmode.asm-bin
include/asm/realmode.h
kernel/apic.c

index 2caa9be..4ec661f 100644 (file)
 #define DATASEL_32  0x10
 
 BITS 16
+ORG 0x2000
 
     jmp main /* Skip our header data */
 
 gdtr:
-    DD 0
+    DQ 0
 crthree:
     DD 0
 kernel_entry:
     DQ 0
 
 main:
-    lgdt [cs:builtin_gdtr]
+    lgdt [cs:builtin_gdtr - REALMODE_PA]
 
     mov eax, cr0
     or eax, 1
     mov cr0, eax
 
-    /* From here all of our references will be off by REALMODE_PA since we've
-     * moved to a 0x0 based selector
-     */
-
-    jmp 0x8:host_local_gdt + REALMODE_PA
+    jmp 0x8:host_local_gdt
 
 BITS 32
 host_local_gdt:
@@ -69,10 +66,38 @@ host_local_gdt:
     mov fs, ax
     mov gs, ax
 
-    mov eax, [gdtr + REALMODE_PA]
-    lgdt [eax]
+    /* This init is taken from head.asm */
+
+    /* PAE */
+    mov eax, cr4
+    or  eax, (1 << 5)
+    mov cr4, eax
+
+    /* CR3 */
+    mov eax, [crthree]
+    mov cr3, eax
+
+    /* Long Mode */
+    mov ecx, 0xc0000080
+    rdmsr
+    or  eax, (1 << 8)
+    wrmsr
+
+    /* paging */
+    mov eax, cr0
+    or  eax, (1 << 31)
+    mov cr0, eax
+
+    jmp        0x18:go_64
+go_64:
+
+BITS 64
+
+    mov rax, [gdtr]
+    lgdt [rax]
+
+    jmp kernel_gdt
 
-    jmp CODESEL_32:kernel_gdt + REALMODE_PA
 kernel_gdt:
     /* We now share a GDT with the rest of the kernel */
 
@@ -88,10 +113,11 @@ kernel_gdt:
 ALIGN 8
 builtin_gdtr:
 DW (builtin_gdt_end - builtin_gdt) - 1
-DQ builtin_gdt + REALMODE_PA
+DQ builtin_gdt
 
 builtin_gdt:
 GDTENTRY    0, 0x0, 0x0
 GDTENTRY    FLAGS_CODE_32, 0, 0xFFFFF
 GDTENTRY    FLAGS_DATA_32, 0, 0xFFFFF
+GDTENTRY    FLAGS_CODE_64, 0, 0xFFFFF
 builtin_gdt_end:
index a29487d..5d8e4c5 100644 (file)
@@ -7,9 +7,9 @@ extern u64 end_realmode_bin;
 
 struct rm_header {
        u8   jmp[2]; /* Two bytes for the jump over data */
-       u32  gdtr_pa;
+       u64  gdtr;
        u32  cr3;
        u64  kernel_entry;
 } __attribute__((packed));
 
-extern u32 GDTR_32;
+extern u64 GDTR_64;
index 16cc57f..0a87108 100644 (file)
@@ -125,8 +125,8 @@ static void apic_wake_secondary(u8 apic_id)
                map_page(0x2000, 0x2000);
                realboot = (void *) 0x2000;
                memcpy(realboot, &realmode_bin, REALMODE_BIN_LEN);
-               realboot->gdtr_pa = (u64) &GDTR_32;
-               unmap_pages(0x2000, 1);
+               realboot->gdtr = (VIRT_BASE + (u64) &GDTR_64);
+               realboot->cr3 = get_cr3();
        }
 
        lo = ICRL_MT(MT_INIT) | ICRL_ASSERT | ICRL_TRIGGER_LEVEL;