Avoid reading the ioapic registers for vector and trigger mode,
by introducing an O(1) memory lookup for these properties.
---
 i386/i386/apic.h     |  6 ++++++
 i386/i386/pic.c      |  5 +++++
 i386/i386/pic.h      |  6 ++++++
 i386/i386at/ioapic.c | 27 +++++++++++++--------------
 4 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/i386/i386/apic.h b/i386/i386/apic.h
index 92fb900a..df95b812 100644
--- a/i386/i386/apic.h
+++ b/i386/i386/apic.h
@@ -235,6 +235,11 @@ typedef struct ApicInfo {
         struct    IrqOverrideData irq_override_list[MAX_IRQ_OVERRIDE];
 } ApicInfo;
 
+struct irqinfo {
+    uint8_t trigger;
+    uint8_t vector;
+};
+
 int apic_data_init(void);
 void apic_add_cpu(uint16_t apic_id);
 void apic_lapic_init(ApicLocalUnit* lapic_ptr);
@@ -275,6 +280,7 @@ extern volatile ApicLocalUnit* lapic;
 extern int cpu_id_lut[];
 extern uint32_t *hpet_addr;
 extern uint8_t apic_id_mask;
+extern struct irqinfo irqinfo[];
 
 #endif
 
diff --git a/i386/i386/pic.c b/i386/i386/pic.c
index 0218fea4..b51bf3ad 100644
--- a/i386/i386/pic.c
+++ b/i386/i386/pic.c
@@ -80,6 +80,8 @@ int   spl_init = 0;
 
 int    iunit[NINTR] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
 
+struct irqinfo irqinfo[NINTR];
+
 unsigned short master_icw, master_ocw, slaves_icw, slaves_ocw;
 
 u_short PICM_ICW1, PICM_OCW1, PICS_ICW1, PICS_OCW1 ;
@@ -119,6 +121,9 @@ picinit(void)
                curr_ipl[i] = SPLHI;
        curr_pic_mask = 0;
 
+       for (i = 0; i < NINTR; i++)
+               irqinfo[i].trigger = EDGE_TRIGGER;
+
        /*
        ** 1. Generate addresses to each PIC port.
        */
diff --git a/i386/i386/pic.h b/i386/i386/pic.h
index aec0ef6b..aa5f7e60 100644
--- a/i386/i386/pic.h
+++ b/i386/i386/pic.h
@@ -181,11 +181,17 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #define PIC_MASK_ZERO          0x00
 
 #if !defined(__ASSEMBLER__) && !defined(APIC)
+struct irqinfo {
+    unsigned char trigger;
+    unsigned char vector;
+};
+
 extern void picinit (void);
 extern int curr_pic_mask;
 extern void intnull(int unit);
 extern void mask_irq (unsigned int irq_nr);
 extern void unmask_irq (unsigned int irq_nr);
+extern struct irqinfo irqinfo[];
 #endif /* __ASSEMBLER__ */
 
 #endif /* _I386_PIC_H_ */
diff --git a/i386/i386at/ioapic.c b/i386/i386at/ioapic.c
index a6c0fd6a..e38e4d6b 100644
--- a/i386/i386at/ioapic.c
+++ b/i386/i386at/ioapic.c
@@ -128,6 +128,8 @@ interrupt_handler_fn ivect[NINTR] = {
     /* 63 */   intnull,
 };
 
+struct irqinfo irqinfo[NINTR];
+
 void
 picdisable(void)
 {
@@ -290,17 +292,6 @@ ioapic_toggle(int pin, int mask)
     ioapic_toggle_entry(apic, pin, mask);
 }
 
-#if 0
-static int
-lapic_tmr_bit(uint8_t vec)
-{
-    int i;
-
-    i = (vec & ~0x1f) >> 5;
-    return lapic->tmr[i].r & (1 << (vec & 0x1f));
-}
-#endif
-
 void
 ioapic_irq_eoi(int pin)
 {
@@ -314,7 +305,7 @@ ioapic_irq_eoi(int pin)
     spl_t s = simple_lock_irq(&ioapic_lock);
 
     if (!has_irq_specific_eoi) {
-      // XXX Linux conditions on TMR bit: if 
(!lapic_tmr_bit(entry.both.vector)) {
+      // XXX Linux conditions on trigger mode: if (irqinfo[pin].trigger) {
         /* Workaround for old IOAPICs with no specific EOI */
 
         /* Mask the pin and change to edge triggered */
@@ -329,8 +320,7 @@ ioapic_irq_eoi(int pin)
       //}
     } else {
         volatile ApicIoUnit *ioapic = apic_get_ioapic(apic)->ioapic;
-        ioapic_read_entry(apic, pin, &entry.both);
-        ioapic->eoi.r = entry.both.vector;
+        ioapic->eoi.r = irqinfo[pin].vector;
     }
 
     simple_unlock_irq(s, &ioapic_lock);
@@ -420,6 +410,9 @@ ioapic_configure(void)
         entry.both.vector = IOAPIC_INT_BASE + gsi;
         ioapic_write_entry(apic, pin, entry.both);
 
+        irqinfo[pin].vector = entry.both.vector;
+        irqinfo[pin].trigger = entry.both.trigger;
+
         /* Set initial state to masked */
         mask_irq(pin);
 
@@ -454,6 +447,9 @@ ioapic_configure(void)
         entry.both.vector = IOAPIC_INT_BASE + gsi;
         ioapic_write_entry(apic, pin, entry.both);
 
+        irqinfo[pin].vector = entry.both.vector;
+        irqinfo[pin].trigger = entry.both.trigger;
+
         /* Set initial state to masked */
         mask_irq(pin);
     }
@@ -478,6 +474,9 @@ ioapic_configure(void)
             entry.both.vector = IOAPIC_INT_BASE + gsi;
             ioapic_write_entry(apic, pin, entry.both);
 
+            irqinfo[pin + ngsis].vector = entry.both.vector;
+            irqinfo[pin + ngsis].trigger = entry.both.trigger;
+
             /* Set initial state to masked */
             mask_irq(pin + ngsis);
         }
-- 
2.45.2



Reply via email to