mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-31 14:38:21 +00:00
apic: ioapic set irq
This commit is contained in:
@@ -65,6 +65,14 @@ typedef struct {
|
|||||||
uint8_t lint;
|
uint8_t lint;
|
||||||
} __attribute__((packed)) lapicnmientry_t;
|
} __attribute__((packed)) lapicnmientry_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
listheader_t header;
|
||||||
|
uint8_t bus;
|
||||||
|
uint8_t irq;
|
||||||
|
uint32_t gsi;
|
||||||
|
uint16_t flags;
|
||||||
|
} __attribute__((packed)) ioapicoverride_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *addr;
|
void *addr;
|
||||||
int base;
|
int base;
|
||||||
@@ -83,6 +91,14 @@ static size_t iocount;
|
|||||||
static size_t lapiccount;
|
static size_t lapiccount;
|
||||||
static size_t lapicnmicount;
|
static size_t lapicnmicount;
|
||||||
|
|
||||||
|
static ioapicdesc_t *ioapicfromgsi(int gsi) {
|
||||||
|
for (int i = 0; i < iocount; ++i) {
|
||||||
|
if (ioapics[i].base <= gsi && ioapics[i].top > gsi)
|
||||||
|
return &ioapics[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline listheader_t *getnext(listheader_t *header) {
|
static inline listheader_t *getnext(listheader_t *header) {
|
||||||
uintptr_t ptr = (uintptr_t)header;
|
uintptr_t ptr = (uintptr_t)header;
|
||||||
return (listheader_t *)(ptr + header->length);
|
return (listheader_t *)(ptr + header->length);
|
||||||
@@ -149,6 +165,27 @@ static void writeiored(void *ioapic, uint8_t entry, uint8_t vector, uint8_t deli
|
|||||||
writeioapic(ioapic, 0x11 + entry * 2, (uint32_t)dest << 24);
|
writeioapic(ioapic, 0x11 + entry * 2, (uint32_t)dest << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arch_ioapic_setirq(uint8_t irq, uint8_t vector, uint8_t proc, bool masked) {
|
||||||
|
// default settings for ISA irqs
|
||||||
|
uint8_t polarity = 1; // active high
|
||||||
|
uint8_t trigger = 0; // edge triggered
|
||||||
|
for (uintmax_t i = 0; i < overridecount; ++i) {
|
||||||
|
ioapicoverride_t *override = getentry(ACPI_MADT_TYPE_OVERRIDE, i);
|
||||||
|
if (override->irq != irq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
polarity = override->flags & 2 ? 1 : 0; // active low
|
||||||
|
trigger = override->flags & 8 ? 1 : 0; // level triggered
|
||||||
|
irq = override->irq;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ioapicdesc_t* ioapic = ioapicfromgsi(irq);
|
||||||
|
__assert(ioapic);
|
||||||
|
irq = irq - ioapic->base;
|
||||||
|
writeiored(ioapic->addr, irq, vector, 0, 0, polarity, trigger, masked ? 1 : 0, proc);
|
||||||
|
}
|
||||||
|
|
||||||
static void spurious(isr_t *self, context_t *ctx) {
|
static void spurious(isr_t *self, context_t *ctx) {
|
||||||
__assert(!"Spurious interrupt");
|
__assert(!"Spurious interrupt");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,7 @@
|
|||||||
void arch_apic_timerinit();
|
void arch_apic_timerinit();
|
||||||
void arch_apic_init();
|
void arch_apic_init();
|
||||||
void arch_apic_initap();
|
void arch_apic_initap();
|
||||||
|
void arch_apic_eoi();
|
||||||
|
void arch_ioapic_setirq(uint8_t gsi, uint8_t vector, uint8_t proc, bool masked);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user