aboutsummaryrefslogtreecommitdiff
path: root/mubios
diff options
context:
space:
mode:
Diffstat (limited to 'mubios')
-rw-r--r--mubios/arch/irq.S13
-rw-r--r--mubios/core/bda.c2
-rw-r--r--mubios/drivers/ioapic.c37
3 files changed, 50 insertions, 2 deletions
diff --git a/mubios/arch/irq.S b/mubios/arch/irq.S
index 4e3b4e2..0c192ff 100644
--- a/mubios/arch/irq.S
+++ b/mubios/arch/irq.S
@@ -116,3 +116,16 @@ irq1_send_eoi:
pop bx
pop ax
iret
+
+ .global irq7_entry
+ .type irq7_entry, @function
+
+irq7_entry:
+ push ax
+
+ # Acknowledge IRQ7 on the master PIC.
+ mov al, 0x20
+ out 0x20, al
+
+ pop ax
+ iret
diff --git a/mubios/core/bda.c b/mubios/core/bda.c
index 105812e..4de2243 100644
--- a/mubios/core/bda.c
+++ b/mubios/core/bda.c
@@ -58,6 +58,7 @@ struct ivt_entry
extern u8 __rom_start[];
extern void irq0_entry (void);
extern void irq1_entry (void);
+extern void irq7_entry (void);
extern void int1a_entry (void);
extern void int10_entry (void);
@@ -85,6 +86,7 @@ ivt_init (void)
{
install_ivt_entry (0x08u, irq0_entry);
install_ivt_entry (0x09u, irq1_entry);
+ install_ivt_entry (0x0Fu, irq7_entry);
install_ivt_entry (0x1Au, int1a_entry);
install_ivt_entry (0x10u, int10_entry);
install_ivt_entry (0x13u, int13_entry);
diff --git a/mubios/drivers/ioapic.c b/mubios/drivers/ioapic.c
index 97c9d15..7a0b6cb 100644
--- a/mubios/drivers/ioapic.c
+++ b/mubios/drivers/ioapic.c
@@ -24,6 +24,9 @@
#define IOAPIC_INDEX 0xFEC00000u
#define IOAPIC_DATA 0xFEC00010u
+#define IOAPIC_VERSION 0x01u
+#define IOAPIC_REDIRECTION_BASE 0x10u
+#define IOAPIC_REDIRECTION_MASK 0x00010000u
#define IOAPIC_IRQ0_LOW 0x10u
#define IOAPIC_IRQ0_HIGH 0x11u
@@ -61,6 +64,31 @@ ioapic_write (u8 index, u32 value)
*ioapic_data = value;
}
+static u32
+ioapic_read (u8 index)
+{
+ *ioapic_index = index;
+ return *ioapic_data;
+}
+
+static void
+ioapic_mask_all (void)
+{
+ u32 version;
+ u32 maximum_pin;
+ u32 pin;
+
+ version = ioapic_read (IOAPIC_VERSION);
+ maximum_pin = (version >> 16) & 0xFFu;
+
+ for (pin = 0; pin <= maximum_pin; ++pin)
+ {
+ ioapic_write ((u8)(IOAPIC_REDIRECTION_BASE + 2u * pin),
+ IOAPIC_REDIRECTION_MASK);
+ ioapic_write ((u8)(IOAPIC_REDIRECTION_BASE + 2u * pin + 1u), 0);
+ }
+}
+
void
ioapic_init (void)
{
@@ -83,14 +111,19 @@ ioapic_init (void)
*(volatile u32 *)(APIC_BASE + APIC_LVT0_OFFSET) = 0x00000700u;
/*
+ * Mask every IOAPIC input before enabling the explicitly configured lines.
+ */
+ ioapic_mask_all ();
+
+ /*
* Route IOAPIC pin 0 to the legacy PIC ExtINT path.
*/
- ioapic_write (IOAPIC_IRQ0_LOW, IOAPIC_IRQ0_EXTINT);
ioapic_write (IOAPIC_IRQ0_HIGH, 0x00000000u);
+ ioapic_write (IOAPIC_IRQ0_LOW, IOAPIC_IRQ0_EXTINT);
/*
* Route the keyboard IRQ through the legacy PIC ExtINT path.
*/
- ioapic_write (IOAPIC_IRQ1_LOW, IOAPIC_IRQ1_EXTINT);
ioapic_write (IOAPIC_IRQ1_HIGH, 0x00000000u);
+ ioapic_write (IOAPIC_IRQ1_LOW, IOAPIC_IRQ1_EXTINT);
}