diff options
author | Damien Zammit <damien@zamaudio.com> | 2025-07-19 06:41:44 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2025-07-19 09:11:29 +0200 |
commit | 8b9765332e5c30690619a314fd780cb8ca3f0169 (patch) | |
tree | b84cb166cb45c6a6e50cd2dfb06579a6c64d72d6 | |
parent | 7bf3238396e3b34b4f6a75d09e73a209b844a47f (diff) |
ioapic: Introduce irqinfo helper struct
Avoid reading the ioapic registers for vector and trigger mode,
by introducing an O(1) memory lookup for these properties.
Message-ID: <20250719064116.285288-2-damien@zamaudio.com>
-rw-r--r-- | i386/i386/apic.h | 6 | ||||
-rw-r--r-- | i386/i386/pic.c | 5 | ||||
-rw-r--r-- | i386/i386/pic.h | 6 | ||||
-rw-r--r-- | 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); } |