aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--entry.S8
-rw-r--r--include/bios.h1
-rw-r--r--main.c24
3 files changed, 33 insertions, 0 deletions
diff --git a/entry.S b/entry.S
index 89fa51e..9a9454a 100644
--- a/entry.S
+++ b/entry.S
@@ -41,6 +41,14 @@
popl %fs
.endm
+ENTRY(bios_irq)
+ pushw %ax
+ mov $0x20, %al
+ out %al, $0x20
+ popw %ax
+ IRET
+ENTRY_END(bios_irq)
+
/*
* fake interrupt handler, nothing can be faster ever
*/
diff --git a/include/bios.h b/include/bios.h
index fcfc5ba..7232bef 100644
--- a/include/bios.h
+++ b/include/bios.h
@@ -32,6 +32,7 @@ extern bioscall void int15_handler(struct biosregs *regs);
extern bioscall void e820_query_map(struct biosregs *regs);
extern void bios_intfake(void);
+extern void bios_irq(void);
extern void bios_int10(void);
extern void bios_int15(void);
diff --git a/main.c b/main.c
index ed871df..5ef38cf 100644
--- a/main.c
+++ b/main.c
@@ -45,11 +45,34 @@ static void set_realmode_int(int vec, void *p)
realmode_idt[vec * 2 + 1] = flat_to_seg16((uintptr_t) p);
}
+static void setup_pic(void)
+{
+ /* Send ICW1 (select OCW1 + will send ICW4) */
+ outb(0x20, 0x11);
+ outb(0xa0, 0x11);
+ /* Send ICW2 (base irqs: 0x08-0x0f for irq0-7, 0x70-0x77 for irq8-15) */
+ outb(0x21, 8);
+ outb(0xa1, 0x70);
+ /* Send ICW3 (cascaded pic ids) */
+ outb(0x21, 0x04);
+ outb(0xa1, 0x02);
+ /* Send ICW4 (enable 8086 mode) */
+ outb(0x21, 0x01);
+ outb(0xa1, 0x01);
+ /* Mask all irqs (except cascaded PIC2 irq) */
+ outb(0x21, ~(1 << 2));
+ outb(0xa1, ~0);
+}
+
static void setup_idt(void)
{
int i;
for (i = 0; i < 0x1f; i++)
set_realmode_int(i, bios_intfake);
+ for (i = 8; i < 16; i++)
+ set_realmode_int(i, bios_irq);
+ for (i = 0x70; i < 0x78; i++)
+ set_realmode_int(i, bios_irq);
set_realmode_int(0x10, bios_int10);
set_realmode_int(0x15, bios_int15);
}
@@ -57,6 +80,7 @@ static void setup_idt(void)
int main(void)
{
make_bios_writable();
+ setup_pic();
setup_idt();
// extract_acpi();
// extract_e820();