Bochs compatible SMP
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 23 Mar 2009 08:50:25 +0000 (01:50 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 23 Mar 2009 08:50:25 +0000 (01:50 -0700)
PSE is set in assembly for APs, the LAPIC timer wait is cranked down,
and the PIC is masked.  KVM didn't need to mask the PIC - masking LINT0
was enough to block the ExtINT, but Bochs was still getting the PIT
interrupt.

kern/apic.c
kern/init.c
kern/smp_entry.S

index d8ba292..54f7ab3 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <inc/mmu.h>
 #include <inc/x86.h>
+#include <inc/assert.h>
 
 #include <kern/apic.h>
 
@@ -26,9 +27,9 @@ void remap_pic()
        // other stuff (put in 8086/88 mode, or whatever)
        outb(PIC1_DATA, 0x01);
        outb(PIC2_DATA, 0x01);
-       // set masks, defaulting to all unmasked for now
-       outb(PIC1_DATA, 0x0);
-       outb(PIC2_DATA, 0x0);
+       // set masks, defaulting to all masked for now
+       outb(PIC1_DATA, 0xff);
+       outb(PIC2_DATA, 0xff);
 }
 
 /*
@@ -46,6 +47,7 @@ void lapic_set_timer(uint32_t ticks, uint8_t vector, bool periodic)
        write_mmreg32(LAPIC_LVT_TIMER, vector | (periodic << 17));
        write_mmreg32(LAPIC_TIMER_INIT, ticks);
        // For debugging when we expand this
+       //cprintf("LAPIC LVT Timer: 0x%08x\n", read_mmreg32(LAPIC_LVT_TIMER));
        //cprintf("LAPIC Init Count: 0x%08x\n", read_mmreg32(LAPIC_TIMER_INIT));
        //cprintf("LAPIC Current Count: 0x%08x\n", read_mmreg32(LAPIC_TIMER_CURRENT));
 }
index 859949a..25354d0 100644 (file)
@@ -89,7 +89,7 @@ void smp_boot(void)
 
        // set up the local APIC timer to fire 0x21 once.  hardcoded to break
        // out of the spinloop on waiting.  really just want to wait a little
-       lapic_set_timer(0xffffffff, 0x21, 0);
+       lapic_set_timer(0x0000ffff, 0x21, 0);
        cprintf("Num_Cpus: %d\n", num_cpus);
        send_init_ipi();
        asm volatile("sti"); // LAPIC timer will fire, extINTs are blocked at LINT0 now
@@ -115,9 +115,8 @@ void smp_main(void)
 {
        cprintf("Good morning Vietnam!\n");
 
-       enable_pse();
-    cprintf("This core's Default APIC ID: 0x%08x\n", lapic_get_default_id());
-    cprintf("This core's Current APIC ID: 0x%08x\n", lapic_get_id());
+       cprintf("This core's Default APIC ID: 0x%08x\n", lapic_get_default_id());
+       cprintf("This core's Current APIC ID: 0x%08x\n", lapic_get_id());
        
        if (read_msr(IA32_APIC_BASE) & 0x00000100)
                cprintf("I am the Boot Strap Processor\n");
index bc1d72d..a82fbd7 100644 (file)
@@ -3,6 +3,7 @@
 #include <inc/trap.h>
 
 #define        RELOC(x) ((x) - KERNBASE)
+#define        CPUID_PSE_SUPPORT       0x00000008
 
 .globl                 smp_entry
 smp_entry:             .code16
@@ -37,6 +38,15 @@ protcseg:    .code32
        # Turn on Paging
        movl    RELOC(boot_cr3), %eax
        movl    %eax, %cr3
+       # Enable PSE, if available
+       movl    $1, %eax
+       cpuid
+       test    $CPUID_PSE_SUPPORT, %edx
+       jz              past_pse
+       movl    %cr4, %eax
+       orl             $CR4_PSE, %eax
+       movl    %eax, %cr4
+past_pse:
        movl    %cr0, %eax      
        # These cr0 flags are the same as in pmap.c.  Keep them in sync
        orl             $(CR0_PE|CR0_PG|CR0_AM|CR0_WP|CR0_NE|CR0_MP), %eax  
@@ -68,7 +78,7 @@ spin_start:                                   # grab lock for smp_main
        call    smp_main
        movl    $0, smp_boot_lock       # release lock
 
-       hlt                                             # does not work on kvm, so spin
+       hlt                                             # hlts, and PC advances to the spinwait
 spinwait:
        jmp             spinwait