APIC notes / wakeup fixes
authorJack Miller <jack@codezen.org>
Thu, 24 Mar 2016 18:40:45 +0000 (13:40 -0500)
committerJack Miller <jack@codezen.org>
Fri, 25 Mar 2016 21:59:17 +0000 (16:59 -0500)
Wakeup still incomplete, but now doesn't cause confusing faults.

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

index 5b6f53c..2caa9be 100644 (file)
@@ -53,19 +53,29 @@ main:
     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
 
 BITS 32
 host_local_gdt:
 
-    mov eax, [cs:gdtr + REALMODE_PA]
+    mov ax, DATASEL_32
+    mov ss, ax
+    mov ds, ax
+    mov es, ax
+    mov fs, ax
+    mov gs, ax
+
+    mov eax, [gdtr + REALMODE_PA]
     lgdt [eax]
 
     jmp CODESEL_32:kernel_gdt + REALMODE_PA
 kernel_gdt:
     /* We now share a GDT with the rest of the kernel */
 
-    /* Initialize all of our selectors */
     mov ax, DATASEL_32
     mov ss, ax
     mov ds, ax
@@ -73,7 +83,7 @@ kernel_gdt:
     mov fs, ax
     mov gs, ax
 
-    jmp kernel_gdt
+    jmp $
 
 ALIGN 8
 builtin_gdtr:
index d9e09b8..4cea9ba 100644 (file)
@@ -4,11 +4,17 @@
  * PIC except to disable it because xAPIC is a foundation technology of the
  * AMD64 arch.
  *
- * While I'm reticent to implement too much "old" hardware, QEMU implements
- * xapic, whereas if you turn on KVM you get x2apic. This is too fundamental to
- * break either environment.  Fortunately, programming either is very similar,
- * pretty much only differing in interface xapic is done via MMIO, x2apic via
- * MSR.
+ * While I'm reticent to implement too much "old" hardware, the interfaces here
+ * are very similar, and since xAPIC was present on all early x86_64 hardware
+ * we might as well support it as a baseline.
+ *
+ * Extant differences:
+ *
+ * - x2APIC used via MSRs, not MMIO (although offsets are related)
+ * - x2APIC has a full 32 bit ID, instead of 8 bits
+ * - x2APIC ICR is written as a single 64 bit MSR, instead of 2x 32 bit MMIOs
+ * - x2APIC ICR with expanded ID destination
+ * - x2APIC ICR has no busy bit, will accept writes in order
  */
 
 #include <console.h>
@@ -38,6 +44,8 @@
 #define APIC_SVR                                       0xf
 #define                SVR_APIC_EN                             (1 << 8)
 
+#define APIC_ESR                                       0x28
+
 #define APIC_ICRL                                      0x30
 #define                ICRL_DSH(x)                             ((x & 0x3) << 18)
 #define                        DSH_ALL_EX_SELF         0x3
@@ -111,6 +119,8 @@ static struct rm_header *realboot = NULL;
 
 static void apic_wake_secondary(u8 apic_id)
 {
+       u32 lo;
+
        if (!realboot) {
                map_page(0x2000, 0x2000);
                realboot = (void *) 0x2000;
@@ -119,7 +129,7 @@ static void apic_wake_secondary(u8 apic_id)
                unmap_pages(0x2000, 1);
        }
 
-       u32 lo = ICRL_MT(MT_INIT) | ICRL_ASSERT | ICRL_TRIGGER_LEVEL;
+       lo = ICRL_MT(MT_INIT) | ICRL_ASSERT | ICRL_TRIGGER_LEVEL;
 
        apic->write_icr(apic_id, lo);