diff options
Diffstat (limited to 'src/c/idt.c')
| -rw-r--r-- | src/c/idt.c | 100 |
1 files changed, 54 insertions, 46 deletions
diff --git a/src/c/idt.c b/src/c/idt.c index 274db6d..d12015e 100644 --- a/src/c/idt.c +++ b/src/c/idt.c @@ -1,6 +1,8 @@ #include"../include/types.h" +#include"../include/irq.h" +#include"../include/asm.h" -#define INTERRUPT_GATE_32 0x8e +#define INTERRUPT_GATE_32 0x8E #define KERNEL_CODE 0x08 #define KERNEL_DATA 0x10 @@ -25,10 +27,9 @@ struct idt_pointer uint32_t offset; } __attribute__((packed)); -// asm function + extern void load_idt(struct idt_pointer *idtp); -extern void keyboard_handler(); -extern void ioport_out(uint8_t port, char data); +extern void keyboard_irq(); struct idt_entry idt[256]; struct idt_pointer idtp; @@ -41,57 +42,64 @@ void init_idt_entry(size_t num, uint32_t offset, uint16_t selector, uint8_t type idt[num].type_attr=type_attr; idt[num].offset2=(offset & 0xffff0000)>>16; } - -void init_idt_table() +void add_idt_entry(size_t num,uint32_t offset) { - // Program the PICs - Programmable Interrupt Controllers - // Background: - // In modern architectures, the PIC is not a separate chip. - // It is emulated in the CPU for backwards compatability. - // The APIC (Advanced Programmable Interrupt Controller) - // is the new version of the PIC that is integrated into the CPU. - // Default vector offset for PIC is 8 - // This maps IRQ0 to interrupt 8, IRQ1 to interrupt 9, etc. - // This is a problem. The CPU reserves the first 32 interrupts for - // CPU exceptions such as divide by 0, etc. - // In programming the PICs, we move this offset to 0x2 (32) so that - // we can handle all interrupts coming to the PICs without overlapping - // with any CPU exceptions. + init_idt_entry(num,offset,KERNEL_CODE,INTERRUPT_GATE_32); +} - // Send ICWs - Initialization Command Words - // PIC1: IO Port 0x20 (command), 0xA0 (data) - // PIC2: IO Port 0x21 (command), 0xA1 (data) - // ICW1: Initialization command - // Send a fixed value of 0x11 to each PIC to tell it to expect ICW2-4 - // Restart PIC1 +void init_pic() +{ ioport_out(PIC1_COMMAND_PORT, 0x11); ioport_out(PIC2_COMMAND_PORT, 0x11); - // ICW2: Vector Offset (this is what we are fixing) - // Start PIC1 at 32 (0x20 in hex) (IRQ0=0x20, ..., IRQ7=0x27) - // Start PIC2 right after, at 40 (0x28 in hex) ioport_out(PIC1_DATA_PORT, 0x20); ioport_out(PIC2_DATA_PORT, 0x28); - // ICW3: Cascading (how master/slave PICs are wired/daisy chained) - // Tell PIC1 there is a slave PIC at IRQ2 (why 4? don't ask me - https://wiki.osdev.org/8259_PIC) - // Tell PIC2 "its cascade identity" - again, I'm shaky on this concept. More resources in notes - ioport_out(PIC1_DATA_PORT, 0x0); - ioport_out(PIC2_DATA_PORT, 0x0); - // ICW4: "Gives additional information about the environemnt" - // See notes for some potential values - // We are using 8086/8088 (MCS-80/85) mode - // Not sure if that's relevant, but there it is. - // Other modes appear to be special slave/master configurations (see wiki) - ioport_out(PIC1_DATA_PORT, 0x1); - ioport_out(PIC2_DATA_PORT, 0x1); - // Voila! PICs are initialized - - // Mask all interrupts (why? not entirely sure) - // 0xff is 16 bits that are all 1. - // This masks each of the 16 interrupts for that PIC. + ioport_out(PIC1_DATA_PORT, 0x04); + ioport_out(PIC2_DATA_PORT, 0x02); + ioport_out(PIC1_DATA_PORT, 0x01); + ioport_out(PIC2_DATA_PORT, 0x01); ioport_out(PIC1_DATA_PORT, 0xff); ioport_out(PIC2_DATA_PORT, 0xff); - init_idt_entry(0x21,(uint32_t)keyboard_handler,KERNEL_CODE,INTERRUPT_GATE_32); + ioport_out(PIC1_DATA_PORT, 0xFC); +} + +void init_idt_table() +{ + init_pic(); + add_idt_entry(0,(uint32_t)irq0); + add_idt_entry(1,(uint32_t)irq1); + add_idt_entry(2,(uint32_t)irq2); + add_idt_entry(3,(uint32_t)irq3); + add_idt_entry(4,(uint32_t)irq4); + add_idt_entry(5,(uint32_t)irq5); + add_idt_entry(6,(uint32_t)irq6); + add_idt_entry(7,(uint32_t)irq7); + add_idt_entry(8,(uint32_t)irq8); + add_idt_entry(9,(uint32_t)irq9); + add_idt_entry(10,(uint32_t)irq10); + add_idt_entry(11,(uint32_t)irq11); + add_idt_entry(12,(uint32_t)irq12); + add_idt_entry(13,(uint32_t)irq13); + add_idt_entry(14,(uint32_t)irq14); + add_idt_entry(15,(uint32_t)irq15); + add_idt_entry(16,(uint32_t)irq16); + add_idt_entry(17,(uint32_t)irq17); + add_idt_entry(18,(uint32_t)irq18); + add_idt_entry(19,(uint32_t)irq19); + add_idt_entry(20,(uint32_t)irq20); + add_idt_entry(21,(uint32_t)irq21); + add_idt_entry(22,(uint32_t)irq22); + add_idt_entry(23,(uint32_t)irq23); + add_idt_entry(24,(uint32_t)irq24); + add_idt_entry(25,(uint32_t)irq25); + add_idt_entry(26,(uint32_t)irq26); + add_idt_entry(27,(uint32_t)irq27); + add_idt_entry(28,(uint32_t)irq28); + add_idt_entry(29,(uint32_t)irq29); + add_idt_entry(30,(uint32_t)irq30); + add_idt_entry(31,(uint32_t)irq31); + add_idt_entry(32,(uint32_t)timer_irq); + add_idt_entry(33,(uint32_t)keyboard_irq); idtp.size=sizeof(struct idt_entry)*256-1; idtp.offset=(uint32_t)&idt; |
