Added support to boot ROS in VirtualBox and KVM. Expanded MPTables scan, fixed IOAPIC...
authorPaul Pearce <pearce@eecs.berkeley.edu>
Sat, 8 Aug 2009 01:31:29 +0000 (18:31 -0700)
committerPaul Pearce <pearce@eecs.berkeley.edu>
Tue, 18 Aug 2009 01:10:25 +0000 (18:10 -0700)
Added another range of memory for mptables.c to scan looking for the mptable. This was required for
VirtualBox. This is also done in BSD.

Fixed a misplaced bit in the IOAPIC that was causing entries to not mask properly when disabling an
IRQ route. This was revealed by VirtualBox's behavior with routing IRQ's.

Increased the wait time in smp_boot() to detect how many cores we have. This was needed as
VirtualBox was occasionally getting the wrong number of cores.

Reworked ioapic pit test. Fixed the name, and changed the timer divisor to be within range.

Both PCI and ISA interrupts are now working inside KVM. Slight note: We can't route IRQ 0
to any core by 0 inside KVM. This is due to a hard coded check inside the kvm kernel module
that was inserted to deal with some TSC instability encountered by the linux guys.

To deal with the KVM situation, I added a check in ioapic_route_irq() that throws a warning
should you try to reroute irq 0 to a core other than 0. This was signed off on by Barret.

.gitignore
kern/arch/i386/ioapic.h
kern/arch/i386/smp_boot.c
kern/include/mptables.h
kern/include/testing.h
kern/src/ioapic.c
kern/src/mptables.c
kern/src/ne2k.c
kern/src/rl8168.c
kern/src/testing.c

index c49f8b7..156b5b5 100644 (file)
@@ -9,6 +9,7 @@ run_bochs.sh
 update*
 cscope.out
 hdd.img
+hdd.vdi
 *.*~
 Makelocal
 .textmate*
index 5033041..aa4a88d 100644 (file)
@@ -24,8 +24,8 @@
 
 #define IOAPIC_MAX_ID                          256
 
-#define IOAPIC_UNROUTE_LOW                     0x00000000
-#define IOAPIC_UNROUTE_HIGH                    0x00000001
+#define IOAPIC_UNROUTE_LOW                     0x00010000
+#define IOAPIC_UNROUTE_HIGH                    0x00000000
 
 
 void ioapic_init();
index 1c27a44..1e3729e 100644 (file)
@@ -85,7 +85,7 @@ void smp_boot(void)
        udelay(200);
        send_startup_ipi(0x01);
        */
-       udelay(100000);
+       udelay(500000);
 
        // Each core will also increment smp_semaphore, and decrement when it is done,
        // all in smp_entry.  It's purpose is to keep Core0 from competing for the
index f9a8e69..5562fc8 100644 (file)
@@ -20,6 +20,8 @@
 #define TOPOFMEM_POINTER       0x0413          /* BIOS: base memory size */
 #define IMCRP_MASK             0x80
 
+#define DEFAULT_TOPOFMEM       0xa0000
+
 #define NUM_ENTRY_TYPES 5
 
 enum interrupt_modes {
index 89ba6ed..11c18af 100644 (file)
@@ -10,7 +10,7 @@
 
 void test_ipi_sending(void);
 void test_pic_reception(void);
-void test_ioapic_pic_reroute(void);
+void test_ioapic_pit_reroute(void);
 void test_print_info(void);
 void test_barrier(void);
 void test_interrupts_irqsave(void);
index b4218c8..4c7ddff 100644 (file)
@@ -126,7 +126,10 @@ void ioapic_route_irq(uint8_t irq, uint8_t dest) {
        if (dest >= num_cpus)
                panic("TRYING TO REROUTE TO AN INVALID DESTINATION!");
        
-       // This is ugly. Fix it. I just gave up because i need sleep and I wanted it working so I can commit.
+       if (irq == 0 && dest != 0)
+               cprintf("WARNING: Rerouting IRQ to core != 0 may cause undefined behavior!\n");
+
+       // Bit pack our redirection entry       
        uint32_t redirect_low = KERNEL_IRQ_OFFSET + irq;
        redirect_low = redirect_low | (ioapic_redirects[irq].ioapic_flags << 8);
        uint32_t redirect_high = dest << 24;
index 391e3e9..318fb85 100644 (file)
@@ -129,6 +129,24 @@ void mptables_parse() {
                        mpfps = find_floating_pointer(top_of_mem, top_of_mem + 1024 - sizeof(mpfps_t));
                }
        }
+       
+       if (mpfps == NULL) {
+               // Search the last KB of system memory based on a 640K limited, due to CMOS lying
+               
+               // Note: Will only be there if it not in the EBDA. So this must be called after the EBDA check.
+                               
+               physaddr_t top_of_mem = DEFAULT_TOPOFMEM;
+               
+               if (top_of_mem) {
+                               
+                       top_of_mem = top_of_mem - 1024;
+                       
+                       top_of_mem = (physaddr_t)KADDR(top_of_mem);
+               
+               mptables_dump("-->Searching top of (real mode) Ram 640K cap, incase CMOS lied...\n");
+                       mpfps = find_floating_pointer(top_of_mem, top_of_mem + 1024 - sizeof(mpfps_t));
+               }
+       }
 
        // If we can't find the pointer, it means we are running on a non-mp compliant machine.
        // This is bad. We can't do interrupts the way we want.
@@ -195,7 +213,7 @@ void mptables_parse() {
 // Does not esure base/bounds are sane.
 mpfps_t *find_floating_pointer(physaddr_t base, physaddr_t bound) {
 
-       mpfps_t* mpfps = (mpfps_t*)base;        
+       mpfps_t* mpfps = (mpfps_t*)base;
 
        // Loop over the entire range looking for the signature. The signature is ascii _MP_, which is
        //  stored in the given MP_SIG
index 6d334fc..a80ed68 100644 (file)
@@ -46,7 +46,7 @@ int ne2k_scan_pci() {
        extern pci_dev_entry pci_dev_map[PCI_MAX_BUS][PCI_MAX_DEV][PCI_MAX_FUNC];
        extern uint16_t pci_irq_map[PCI_MAX_BUS][PCI_MAX_DEV][PCI_MAX_FUNC];
 
-       cprintf("Searching for NE2000 Network device......");
+       cprintf("Searching for NE2000 Network device...");
 
        for (int i = 0; i < PCI_MAX_BUS; i++)
                for (int j = 0; j < PCI_MAX_DEV; j++)
@@ -118,7 +118,7 @@ void ne2k_configure_nic() {
        outb(ne2k_io_base_addr + 0x0F, 0xFF);
 
         uint8_t isr = inb(ne2k_io_base_addr + 0x07);
-        cprintf("isr: %x\n", isr);
+        //cprintf("isr: %x\n", isr);
 
 
        cprintf("Generating Interrupt...\n");
index a302436..3521f98 100644 (file)
@@ -101,7 +101,7 @@ int rl8168_scan_pci() {
        extern pci_dev_entry pci_dev_map[PCI_MAX_BUS][PCI_MAX_DEV][PCI_MAX_FUNC];
        extern uint16_t pci_irq_map[PCI_MAX_BUS][PCI_MAX_DEV][PCI_MAX_FUNC];
 
-       cprintf("Searching for RealTek 8168 Network device......");
+       cprintf("Searching for RealTek 8168 Network device...");
 
        for (int i = 0; i < PCI_MAX_BUS; i++)
                for (int j = 0; j < PCI_MAX_DEV; j++)
index b9b900c..0f58ab8 100644 (file)
@@ -77,7 +77,7 @@ void test_pic_reception(void)
 }
 #endif
 
-void test_ioapic_pic_reroute(void) 
+void test_ioapic_pit_reroute(void) 
 {
        extern handler_t interrupt_handlers[];
        register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, 0);
@@ -85,13 +85,13 @@ void test_ioapic_pic_reroute(void)
 
        cprintf("Starting pit on core 3....\n");
        udelay(3000000);
-       pit_set_timer(100000,TIMER_RATEGEN); // totally arbitrary time
+       pit_set_timer(0xFFFE,TIMER_RATEGEN); // totally arbitrary time
        
        udelay(3000000);
        ioapic_unroute_irq(0);
        udelay(300000);
        cprintf("Masked pit. Waiting before return...\n");
-       udelay(30000000);
+       udelay(3000000);
 }
 
 void test_print_info(void)