Moved IOAPIC functionality into ioapic.c, added support for ISA IRQs (pit keyboard...
authorPaul Pearce <pearce@eecs.berkeley.edu>
Sat, 25 Jul 2009 02:40:01 +0000 (19:40 -0700)
committerPaul Pearce <pearce@eecs.berkeley.edu>
Sat, 25 Jul 2009 02:40:01 +0000 (19:40 -0700)
Net result is we can now reroute any IRQ on the PCI or ISA bus, this includes
anything that is listed on the ISA bus (in mptables), such as the PIT,
Keyboard, etc.

Moved ioapic_reroute_irq() into ioapic.c. Also added an ioapic_init() function
that runs through the PIC and ISA structures (discussed below) and creates an
IRQ->IOAPIC mapping, so there is a single source of truth as far as the route
functions are concerned.

Added an ioapic_unroute_irq() that basically masks an irq.

Added ISA IRQ related parsing to MPTables that allows for things like the PIT
to be routed via the IOAPIC. This creates a structure like the one found for
pci that maps IRQ's to ioapic entries. This is used in ioapic_init()

Added ioapic_init() to the init process after pci_init.

12 files changed:
include/arch/apic.h
include/arch/ioapic.h [new file with mode: 0644]
include/mptables.h
include/rl8168.h
kern/src/Makefrag
kern/src/apic.c
kern/src/init.c
kern/src/ioapic.c [new file with mode: 0644]
kern/src/mptables.c
kern/src/pci.c
kern/src/rl8168.c
kern/src/trap.c

index 922db84..9289cfd 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <arch/mmu.h>
 #include <arch/x86.h>
+#include <arch/ioapic.h>
 
 // PIC
 #define PIC1_CMD                                       0x20
@@ -50,9 +51,6 @@
 #define LAPIC_IPI_ICR_LOWER                    (LAPIC_BASE + 0x300)
 #define LAPIC_IPI_ICR_UPPER                    (LAPIC_BASE + 0x310)
 
-// IOAPIC
-#define IOAPIC_BASE                                    0xfec00000 // this is the default, can be changed
-
 // PIT (Programmable Interval Timer)
 #define        TIMER_REG_CNTR0 0       /* timer 0 counter port */
 #define        TIMER_REG_CNTR1 1       /* timer 1 counter port */
@@ -93,7 +91,6 @@ extern system_timing_t system_timing;
 void pic_remap(void);
 void pic_mask_irq(uint8_t irq);
 void pic_unmask_irq(uint8_t irq);
-void ioapic_route_irq(uint8_t irq, uint8_t dest);
 void __lapic_set_timer(uint32_t ticks, uint8_t vec, bool periodic, uint8_t div);
 void lapic_set_timer(uint32_t usec, bool periodic);
 uint32_t lapic_get_default_id(void);
diff --git a/include/arch/ioapic.h b/include/arch/ioapic.h
new file mode 100644 (file)
index 0000000..4e4ea1b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2009 The Regents of the University of California
+ * See LICENSE for details.
+ */
+
+#ifndef ROS_KERN_IOAPIC_H
+#define ROS_KERN_IOAPIC_H
+
+#include <arch/mmu.h>
+#include <arch/x86.h>
+#include <arch/apic.h>
+
+// IOAPIC
+// Paul wants this next constant to go away. its only still used
+//  for the top of memory calculations
+#define IOAPIC_BASE                                    0xfec00000 // this is the default, can be changed
+
+// These are things like level sensitive, edge triggered, fixed, nmi, extint, etc
+// I should elaborate upon these.
+#define IOAPIC_PCI_FLAGS                       0xa0
+#define IOAPIC_ISA_FLAGS                       0x00
+#define IOAPIC_PIC_FLAGS                       0x07 // Not used. 
+
+#define IOAPIC_MAX_ID                          256
+
+#define IOAPIC_UNROUTE_LOW                     0x00000000
+#define IOAPIC_UNROUTE_HIGH                    0x00000001
+
+
+void ioapic_init();
+void ioapic_route_irq(uint8_t irq, uint8_t dest);
+void ioapic_unroute_irq(uint8_t irq);
+
+#endif /* ROS_KERN_IOAPIC_H */
index dc2210f..53041c8 100644 (file)
@@ -20,8 +20,6 @@
 #define TOPOFMEM_POINTER       0x0413          /* BIOS: base memory size */
 #define IMCRP_MASK             0x8000
 
-#define IOAPIC_MAX_ID  256
-
 #define NUM_ENTRY_TYPES 5
 
 enum interrupt_modes {
@@ -156,6 +154,8 @@ typedef struct PCIINTENTRY {
     uint8_t            dstApicINT;
 } pci_int_entry;
 
+typedef pci_int_entry isa_int_entry;
+
 typedef struct PCIINTGROUP {
        pci_int_entry intn[4];
 } pci_int_group;
index 9e6856a..c5d9a63 100644 (file)
@@ -5,10 +5,12 @@
 #include <trap.h>
 #include <pmap.h>
 
-#define nic_debug(...)  cprintf(__VA_ARGS__)  
+#define nic_debug(...)  //cprintf(__VA_ARGS__)  
 #define nic_interrupt_debug(...) cprintf(__VA_ARGS__)  
 #define nic_frame_debug(...)  //cprintf(__VA_ARGS__)  
 
+#define NIC_IRQ_CPU                    5
+
 // Macro for formatting PCI Configuration Address queries
 #define MK_CONFIG_ADDR(BUS, DEV, FUNC, REG) (unsigned long)( (BUS << 16) | (DEV << 11) | \
                                                              (FUNC << 8) | REG  | \
index f9cb775..55f64d5 100644 (file)
@@ -32,6 +32,7 @@ KERN_SRCFILES := $(KERN_SRC_DIR)/entry.S \
                  $(KERN_SRC_DIR)/manager.c \
                  $(KERN_SRC_DIR)/mptables.c \
                  $(KERN_SRC_DIR)/pci.c \
+                 $(KERN_SRC_DIR)/ioapic.c \
                  $(KERN_SRC_DIR)/atomic.c \
                  $(KERN_SRC_DIR)/smp.c \
                  $(KERN_SRC_DIR)/printfmt.c \
index 8cf2a96..b862527 100644 (file)
@@ -8,8 +8,6 @@
 #include <arch/apic.h>
 #include <arch/timer.h>
 #include <assert.h>
-#include <mptables.h>
-#include <pci.h>
 
 system_timing_t system_timing = {0, 0, 0xffff, 0};
 
@@ -57,55 +55,6 @@ void pic_unmask_irq(uint8_t irq)
                outb(PIC1_DATA, inb(PIC1_DATA) & ~(1 << irq));
 }
 
-// MUST NOT BE CALLED BEFORE THE MPTABLES ARE PARSED
-void ioapic_route_irq(uint8_t irq, uint8_t dest) {
-       
-       extern pci_irq_entry irq_pci_map[NUM_IRQS];
-       extern uint8_t num_cpus;
-       extern pci_int_group pci_int_groups[PCI_MAX_BUS][PCI_MAX_DEV];
-       extern ioapic_entry ioapic_entries[IOAPIC_MAX_ID];
-       
-       // Need special check for PCI vs non PCI interrupts.
-
-       uint16_t bus = irq_pci_map[irq].bus;
-       uint8_t dev = irq_pci_map[irq].dev;
-       uint8_t intn = irq_pci_map[irq].intn;
-       
-       if (bus == INVALID_BUS)
-               panic("TRYING TO REROUTE TO AN INVALID IRQ!");
-       
-       // THIS IS A TEMP CHECK. IF WE USE LOGICAL PARTITIONS THIS MUST BE REMOVED
-       // Since we rely on SMP_BOOT to set the num_cpus, and we currently setup interrupt redirection BEFORE bootup. This is a problem
-//     if (dest >= num_cpus)
-//             panic("TRYING TO REROUTE TO AN INVALID DESTINATION!");
-               
-       uint16_t dstApicID = pci_int_groups[bus][dev].intn[intn].dstApicID;
-       uint8_t dstApicINT = pci_int_groups[bus][dev].intn[intn].dstApicINT;
-       
-       // MP Tables uses 8 bits to store the apic id. If our value is larger, is invalid entry
-       if (dstApicID == 0xFFFF)
-               panic("IRQ->PCI map and PCI->IOAPIC map are out of sync");
-       
-       if ((ioapic_entries[dstApicID].apicFlags & 0x1) == 0) 
-               panic("TRYING TO ROUTE TO AN INVALID DESTINATION");
-               
-       uint32_t ioapic_base = (uint32_t)ioapic_entries[dstApicID].apicAddress;
-       
-       cprintf("ioapic_addr: %x\n", ioapic_base);
-       
-       // This is ugly. Fix it. I just gave up because i need sleep and I wanted it working so I can commit.
-       uint32_t redirect_low = KERNEL_IRQ_OFFSET + irq;
-       redirect_low = redirect_low | 0xa000;
-       uint32_t redirect_high = dest << 24;
-       
-       write_mmreg32(ioapic_base, 0x10 + 2*dstApicINT);
-       write_mmreg32(ioapic_base + 0x10, redirect_low);
-       write_mmreg32(ioapic_base, 0x10 + 2*dstApicINT + 1);
-       write_mmreg32(ioapic_base + 0x10, redirect_high);
-
-}
-
-
 /*
  * Sets the LAPIC timer to go off after a certain number of ticks.  The primary
  * clock freq is actually the bus clock, which we figure out during timer_init
index c8e5f7f..dd00fc1 100644 (file)
@@ -31,6 +31,7 @@
 #include <rl8168.h>
 #include <mptables.h>
 #include <pci.h>
+#include <arch/ioapic.h>
 
 static void print_cpuinfo(void);
 
@@ -61,12 +62,11 @@ void kernel_init(multiboot_info_t *mboot_info)
        timer_init();
        mptables_parse();
        pci_init();
+       ioapic_init(); // MUST BE AFTER PCI/ISA INIT!
        // this returns when all other cores are done and ready to receive IPIs
        smp_boot();
        
-       nic_init();
-
-               
+       nic_init();             
        /*
        test_smp_call_functions();
        test_checklists();
diff --git a/kern/src/ioapic.c b/kern/src/ioapic.c
new file mode 100644 (file)
index 0000000..5bb938e
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009 The Regents of the University of California
+ * See LICENSE for details.
+ */
+
+#include <arch/mmu.h>
+#include <arch/x86.h>
+#include <arch/apic.h>
+#include <arch/timer.h>
+#include <assert.h>
+#include <mptables.h>
+#include <pci.h>
+
+/* IOAPIC ?Driver?
+ *
+ * Written by Paul Pearce.
+ *
+ * Insight into functionality goes here
+ *
+ * TODO: Clean up array bounds checking (leaving it to ivy is lame, no offense to ivy, its just not good practice)
+ */
+
+typedef struct IOAPICREDIRECT {
+    void*                      ioapic_address; // NULL means invalid (duh)
+       uint8_t                 ioapic_flags;
+       uint8_t                 ioapic_int;
+} ioapic_redirect;
+
+ioapic_redirect ioapic_redirects[NUM_IRQS];
+
+void ioapic_init() {
+       // Set all entires invalid.
+       memset(ioapic_redirects, 0x0, sizeof(ioapic_redirects));
+       
+       extern uint8_t num_cpus;
+       
+       // Pull in all the stuff we need from mptables and the pci parsing
+       extern pci_irq_entry irq_pci_map[NUM_IRQS];
+       extern pci_int_group pci_int_groups[PCI_MAX_BUS][PCI_MAX_DEV];
+       extern ioapic_entry ioapic_entries[IOAPIC_MAX_ID];
+       extern isa_int_entry isa_int_entries[NUM_IRQS];
+       
+       // Setup the PCI entries
+       for (int i = 0; i < NUM_IRQS; i++) {
+               uint16_t bus = irq_pci_map[i].bus;
+               uint8_t dev = irq_pci_map[i].dev;
+               uint8_t intn = irq_pci_map[i].intn;
+               
+               if (bus == INVALID_BUS)
+                       continue;
+
+               uint16_t dstApicID = pci_int_groups[bus][dev].intn[intn].dstApicID;
+               uint8_t dstApicINT = pci_int_groups[bus][dev].intn[intn].dstApicINT;
+               
+               // MP Tables uses 8 bits to store the apic id. If our value is larger, is invalid entry
+               // If we have a valid bus in the irq->pci map, and the pic->int entry doesnt exist, we have a major problem
+               if (dstApicID == 0xFFFF)
+                       panic("IRQ->PCI map and PCI->IOAPIC map are out of sync");
+               
+               // If the lowest bit of the apic flags is set to 0, it means the ioapic is not usable.
+               // We also use this to denote non-existent ioapics in our map
+               if ((ioapic_entries[dstApicID].apicFlags & 0x1) == 0) 
+                       panic("IRQ SAYS ITS GOING TO AN IOAPIC LISTED AS INVALID, THATS BAD.");
+                                       
+               ioapic_redirects[i].ioapic_address = ioapic_entries[dstApicID].apicAddress;
+               ioapic_redirects[i].ioapic_int = dstApicINT;
+               ioapic_redirects[i].ioapic_flags = IOAPIC_PCI_FLAGS;
+       }
+       
+       // Setup the ISA entries
+       for (int i = 0; i < NUM_IRQS; i++) {
+               
+               uint16_t dstApicID = isa_int_entries[i].dstApicID;
+               uint8_t dstApicINT = isa_int_entries[i].dstApicINT;
+               
+               
+               // Skip invalid entries
+               if (dstApicID == 0xFFFF)
+                       continue;
+                       
+               if (ioapic_redirects[i].ioapic_address != NULL) {
+                       // We could handle this so long as they would route to the same place. But we will say we cant
+                       //  because this shouldnt really happen
+                       panic("BOTH PCI AND ISA CLAIM TO SHARE AN IRQ. BAD");
+               }
+
+               ioapic_redirects[i].ioapic_address = ioapic_entries[dstApicID].apicAddress;
+               ioapic_redirects[i].ioapic_int = dstApicINT;
+               ioapic_redirects[i].ioapic_flags = IOAPIC_ISA_FLAGS;
+       }
+       
+       // Support for other type of IRQ's goes here.
+}
+
+// MUST NOT BE CALLED BEFORE THE MPTABLES ARE PARSED
+// INPUT IS NON-KERNEL-OFFSETTED. IE IRQ0 is Pit, not divide by 0.
+void ioapic_route_irq(uint8_t irq, uint8_t dest) {
+       
+       if (((irq + KERNEL_IRQ_OFFSET) >= NUM_IRQS) || (ioapic_redirects[irq].ioapic_address == NULL)) {
+               panic("TRYING TO REROUTE AN INVALID IRQ!");
+       }
+
+       // THIS IS A TEMP CHECK. IF WE USE LOGICAL PARTITIONS THIS MUST BE REMOVED
+       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.
+       uint32_t redirect_low = KERNEL_IRQ_OFFSET + irq;
+       redirect_low = redirect_low | (ioapic_redirects[irq].ioapic_flags << 8);
+       uint32_t redirect_high = dest << 24;
+       
+       // YOU MUST MUST MUST MUST MUST MUST MUST write the high bits first. Ask Paul about that afternoon of his life.
+       write_mmreg32((uint32_t)ioapic_redirects[irq].ioapic_address , 0x10 + 2*ioapic_redirects[irq].ioapic_int + 1);
+       write_mmreg32((uint32_t)ioapic_redirects[irq].ioapic_address  + 0x10, redirect_high);
+       write_mmreg32((uint32_t)ioapic_redirects[irq].ioapic_address , 0x10 + 2*ioapic_redirects[irq].ioapic_int);
+       write_mmreg32((uint32_t)ioapic_redirects[irq].ioapic_address  + 0x10, redirect_low);
+}
+
+void ioapic_unroute_irq(uint8_t irq) {
+
+       if (((irq + KERNEL_IRQ_OFFSET) >= NUM_IRQS) || (ioapic_redirects[irq].ioapic_address == NULL)) {
+               panic("TRYING TO REROUTE AN INVALID IRQ!");
+       }
+       
+       // Must write low first, else we will reroute to a wrong core before turning off
+       write_mmreg32((uint32_t)ioapic_redirects[irq].ioapic_address , 0x10 + 2*ioapic_redirects[irq].ioapic_int);
+       write_mmreg32((uint32_t)ioapic_redirects[irq].ioapic_address  + 0x10, IOAPIC_UNROUTE_LOW);
+       
+       write_mmreg32((uint32_t)ioapic_redirects[irq].ioapic_address , 0x10 + 2*ioapic_redirects[irq].ioapic_int + 1);
+       write_mmreg32((uint32_t)ioapic_redirects[irq].ioapic_address  + 0x10, IOAPIC_UNROUTE_HIGH);
+
+}
index c51fcf8..fce3005 100644 (file)
@@ -6,6 +6,8 @@
 #include <arch/x86.h>
 #include <arch/smp.h>
 #include <arch/apic.h>
+#include <arch/ioapic.h>
+
 
 #include <ros/memlayout.h>
 
@@ -45,8 +47,10 @@ void * mp_entries[NUM_ENTRY_TYPES]; // Array of entry type arrays. Indexable by
 int mp_entries_count[NUM_ENTRY_TYPES]; // How large each array is.
 
 pci_int_group pci_int_groups[PCI_MAX_BUS][PCI_MAX_DEV];
+isa_int_entry isa_int_entries[NUM_IRQS];
 ioapic_entry ioapic_entries[IOAPIC_MAX_ID];
 
+// All this max stuff is removable. Here for debugging (originally for dynamically sized arrays.)
 int max_pci_device = -1;
 int max_pci_bus = -1;
 int num_ioapics = -1;
@@ -57,6 +61,17 @@ void mptables_parse() {
        
        mpfps_t *mpfps;
        
+       // Memsets.
+       // Setup the indexable ioapic array.
+       // YOU MUST check the flag field to see if its 0. If 0, unusable.
+       // Ths is defined by MPTables, and I leaverage this with the memset below.
+       memset(ioapic_entries, 0, sizeof(ioapic_entries));
+       
+       // We define an IOAPIC ID over 255 to be invalid.
+       memset(pci_int_groups, 0xFF, sizeof(pci_int_groups));
+       memset(isa_int_entries, 0xFF, sizeof(isa_int_entries));
+       
+       
        mptables_info("Starting MPTables Parsing...\n");
        
        // Basic struct:
@@ -135,46 +150,44 @@ void mptables_parse() {
                mptables_info("Virtual Wire\n");
        }
        
-       mptables_info("\n");
-       
        configuration_parse((physaddr_t)KADDR((uint32_t)(mpfps->pap)));
        proc_parse(             mp_entries[PROC], mp_entries_count[PROC]);
        bus_parse(              mp_entries[BUS], mp_entries_count[BUS]);
        ioapic_parse(   mp_entries[IOAPIC], mp_entries_count[IOAPIC]);
        int_parse(              mp_entries[INT], mp_entries_count[INT]);
        lint_parse(             mp_entries[LINT], mp_entries_count[LINT]);
-       
-/*
-       // debugging the parsing.
-       cprintf("\n");
-       cprintf("max_pci_device: %u\n", max_pci_device);
-       cprintf("max_pci_bus: %u\n", max_pci_bus);
-       cprintf("num_ioapics: %u\n", num_ioapics);
-       cprintf("max_ioapic_id: %u\n", max_ioapic_id);
-       int n =0;
-       for (int i = 0; i <= max_pci_bus; i++) {
-               for (int j = 0; j <= max_pci_device; j++) {
-                       for (int k = 0; k < 4; k++) {
-                               if (pci_int_groups[i][j].intn[k].dstApicID != 0xFF) {
-                                       cprintf("Bus: %u\n", i);
-                                       cprintf("Device: %u\n", j);
-                                       cprintf("ApicID: %u\n", pci_int_groups[i][j].intn[k].dstApicID);
-                                       cprintf("INTLINE: %u\n", pci_int_groups[i][j].intn[k].dstApicINT);
-                                       cprintf("\n");
-                                       n++;
-                               }
-                       }
-               }
-       }
-       cprintf("n: %u\n", n);
-       for (int i = 0; i <= max_ioapic_id; i++) {
-               if ((ioapic_entries[i].apicFlags & 0x1) != 0) {
-                       cprintf("IOAPIC ID: %u\n", ioapic_entries[i].apicID);
-                       cprintf("IOAPIC Offset: %x\n", ioapic_entries[i].apicAddress);
-                       cprintf("\n");
-               }
-       }
-*/     
+
+
+       // // debugging the parsing.
+       // cprintf("\n");
+       // cprintf("max_pci_device: %u\n", max_pci_device);
+       // cprintf("max_pci_bus: %u\n", max_pci_bus);
+       // cprintf("num_ioapics: %u\n", num_ioapics);
+       // cprintf("max_ioapic_id: %u\n", max_ioapic_id);
+       // int n =0;
+       // for (int i = 0; i <= max_pci_bus; i++) {
+       //      for (int j = 0; j <= max_pci_device; j++) {
+       //              for (int k = 0; k < 4; k++) {
+       //                      if (pci_int_groups[i][j].intn[k].dstApicID != 0xFFFF) {
+       //                              cprintf("Bus: %u\n", i);
+       //                              cprintf("Device: %u\n", j);
+       //                              cprintf("ApicID: %u\n", pci_int_groups[i][j].intn[k].dstApicID);
+       //                              cprintf("INTLINE: %u\n", pci_int_groups[i][j].intn[k].dstApicINT);
+       //                              cprintf("\n");
+       //                              n++;
+       //                      }
+       //              }
+       //      }
+       // }
+       // cprintf("n: %u\n", n);
+       // for (int i = 0; i <= max_ioapic_id; i++) {
+       //      if ((ioapic_entries[i].apicFlags & 0x1) != 0) {
+       //              cprintf("IOAPIC ID: %u\n", ioapic_entries[i].apicID);
+       //              cprintf("IOAPIC Offset: %x\n", ioapic_entries[i].apicAddress);
+       //              cprintf("\n");
+       //      }
+       // }
+       // panic("AHH!");       
        
 }
 
@@ -299,6 +312,7 @@ void bus_parse(bus_entry* entries, uint32_t count) {
                mptables_dump("-->BusID: %x\n", entries[i].busID);
                mptables_dump("-->Bus: %c%c%c\n", entries[i].busType[0], entries[i].busType[1], entries[i].busType[2]);
                
+               // This is removable. Just here for debugging for now.
                if ((strncmp(entries[i].busType, "PCI", 3) == 0) && (entries[i].busID > max_pci_bus))
                        max_pci_bus = entries[i].busID;
                
@@ -327,10 +341,7 @@ void ioapic_parse(ioapic_entry* entries, uint32_t count) {
        }
        mptables_dump("\n");
        
-       // Setup the indexable ioapic array.
-       // YOU MUST check the flag field to see if its 0. If 0, unusable.
-       // Ths is defined by MPTables, and I leaverage this with the memset below.
-       memset(ioapic_entries, 0, sizeof(ioapic_entries));
+
        
        for (int i = 0; i < count; i++) {
                memcpy((void*)(ioapic_entries + entries[i].apicID), (void*)(entries + i), sizeof(ioapic_entry));
@@ -345,12 +356,13 @@ void int_parse(int_entry* entries, uint32_t count) {
                mptables_dump("-->type: %x\n", entries[i].type);
                mptables_dump("-->intType: %x\n", entries[i].intType);
                mptables_dump("-->srcBusID: %u\n", entries[i].srcBusID);
-               mptables_dump("-->srcDevice: %u\n", (entries[i].srcBusIRQ >> 2) & 0x1F);
+               mptables_dump("-->srcDevice: %u (PCI ONLY)\n", (entries[i].srcBusIRQ >> 2) & 0x1F);
                mptables_dump("-->srcBusIRQ: %x\n", entries[i].srcBusIRQ);
                mptables_dump("-->dstApicID: %u\n", entries[i].dstApicID);
                mptables_dump("-->dstApicINT: %u\n", entries[i].dstApicINT);
                
                // Find the max PCI device.
+               // removable. here for debugging.
                if (strncmp(((bus_entry*)mp_entries[BUS])[entries[i].srcBusID].busType, "PCI", 3) == 0) {
                        
                        // Mask out the device number
@@ -360,12 +372,8 @@ void int_parse(int_entry* entries, uint32_t count) {
                }                       
        }
        mptables_dump("\n");
-       
-       memset(pci_int_groups, 0xFF, sizeof(pci_int_groups));
-
-       // We define an IOAPIC ID over 255 to be invalid.
 
-       // Populate the PCI structure with the interrupt entries.
+       // Populate the PCI/ISA structure with the interrupt entries.
        for (int i = 0; i < count; i++) {
                if (strncmp(((bus_entry*)mp_entries[BUS])[entries[i].srcBusID].busType, "PCI", 3) == 0) {
                        int bus_idx, dev_idx, int_idx;
@@ -374,6 +382,32 @@ void int_parse(int_entry* entries, uint32_t count) {
                        int_idx = entries[i].srcBusIRQ & 0x3;
                        pci_int_groups[bus_idx][dev_idx].intn[int_idx].dstApicID = entries[i].dstApicID;
                        pci_int_groups[bus_idx][dev_idx].intn[int_idx].dstApicINT = entries[i].dstApicINT;
+               }
+               
+               if (strncmp(((bus_entry*)mp_entries[BUS])[entries[i].srcBusID].busType, "ISA", 3) == 0) {
+                       int irq = entries[i].srcBusIRQ;
+                       int int_type = entries[i].intType;
+                       
+                       if (int_type == 3) {
+                               // THIS IS WHERE THE PIC CONNECTS TO THE IOAPIC
+                               // WE DON'T CURRENTLY DO ANYTHING WITH THIS, BUT SHOULD WE NEED TO
+                               // HERED WHERE TO LOOK!
+                               // WE MUST NOT PLACE THIS INTO OUR TABLE AS IRQ HAS NO REAL MEANING AFAPK
+                               continue;
+                               
+                               // Note. On the dev boxes the pit and pic both claim to be on irq 0
+                               // However the pit and the pic are on different ioapic entries.
+                               // Seems odd. Not sure whats up with this. Paul assumes the IRQ has no meaning
+                               // in regards to the pic... which makes sense.
+                       }
+                                               
+                       if ((isa_int_entries[irq].dstApicID != 0xFFFF) && 
+                                ((isa_int_entries[irq].dstApicID != entries[i].dstApicID) 
+                                  || (isa_int_entries[irq].dstApicINT != entries[i].dstApicINT)))
+                               panic("SAME IRQ MAPS TO DIFFERENT IOAPIC/INTN'S. THIS DEFIES LOGIC.");
+                       
+                       isa_int_entries[irq].dstApicID = entries[i].dstApicID;
+                       isa_int_entries[irq].dstApicINT = entries[i].dstApicINT;
                }                       
        }
 }
index c75d0e2..6baa123 100644 (file)
@@ -24,7 +24,7 @@
  *
  * Insight into functionality goes here
  *
- * TODO: Write it
+ * TODO: See todo's below
  */
 
 // 256 or larger means invalid irq.
@@ -104,6 +104,9 @@ void pci_init() {
                                        irq_pci_map[irq].dev = j;
                                        irq_pci_map[irq].func = k;
                                        irq_pci_map[irq].intn = intn;
+                                       
+                                       // Perform some check to make usre if we are overwriting a current irq that it goes to the same place. else panic
+                                       // TODO
                                }
                                
 
index e1e495c..97653ec 100644 (file)
@@ -44,7 +44,7 @@
  * TODO: CONCURRENCY!
  */
 
-
+void test_pit_handler(trapframe_t *tf, void* data);
 
 struct Descriptor
 {
@@ -344,9 +344,8 @@ void setup_interrupts() {
        
        // Kernel based interrupt stuff
        register_interrupt_handler(interrupt_handlers, KERNEL_IRQ_OFFSET + irq, nic_interrupt_handler, 0);
-       //pic_unmask_irq(irq);
-       //unmask_lapic_lvt(LAPIC_LVT_LINT0);
-       ioapic_route_irq(irq, 7);       
+       ioapic_route_irq(irq, NIC_IRQ_CPU);     
+       
        return;
 }
 
index 0c5210a..1a24ef9 100644 (file)
@@ -231,7 +231,7 @@ void
 (IN_HANDLER irq_handler)(trapframe_t *tf)
 {
        //if (lapic_get_id())
-       //      cprintf("Incoming IRQ, ISR: %d on core %d\n", tf->tf_trapno, lapic_get_id());
+       //      cprintf("Incoming IRQ, ISR: %d on core %d\n", tf->tf_trapno, lapic_get_id());           
        // merge this with alltraps?  other than the EOI... or do the same in all traps
 
        extern handler_wrapper_t handler_wrappers[NUM_HANDLER_WRAPPERS];