summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2025-07-19 06:41:44 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2025-07-19 09:11:29 +0200
commit8b9765332e5c30690619a314fd780cb8ca3f0169 (patch)
treeb84cb166cb45c6a6e50cd2dfb06579a6c64d72d6
parent7bf3238396e3b34b4f6a75d09e73a209b844a47f (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.h6
-rw-r--r--i386/i386/pic.c5
-rw-r--r--i386/i386/pic.h6
-rw-r--r--i386/i386at/ioapic.c27
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);
}