// Initialize and load the IDT. void setup_idt (void) { idt_ptr.size = (sizeof (idt_entry) * 256) - 1; idt_ptr.address = (uint32_t) &idt; set_idt_entry (0, (uint32_t) &exc0); set_idt_entry (1, (uint32_t) &exc1); set_idt_entry (2, (uint32_t) &exc2); set_idt_entry (3, (uint32_t) &exc3); set_idt_entry (4, (uint32_t) &exc4); set_idt_entry (5, (uint32_t) &exc5); set_idt_entry (6, (uint32_t) &exc6); set_idt_entry (7, (uint32_t) &exc7); set_idt_entry (8, (uint32_t) &exc8); set_idt_entry (9, (uint32_t) &exc9); set_idt_entry (10, (uint32_t) &exc10); set_idt_entry (11, (uint32_t) &exc11); set_idt_entry (12, (uint32_t) &exc12); set_idt_entry (13, (uint32_t) &exc13); set_idt_entry (14, (uint32_t) &exc14); set_idt_entry (15, (uint32_t) &exc15); set_idt_entry (16, (uint32_t) &exc16); set_idt_entry (17, (uint32_t) &exc17); set_idt_entry (18, (uint32_t) &exc18); set_idt_entry (19, (uint32_t) &exc19); set_idt_entry (20, (uint32_t) &exc20); set_idt_entry (21, (uint32_t) &exc21); set_idt_entry (22, (uint32_t) &exc22); set_idt_entry (23, (uint32_t) &exc23); set_idt_entry (24, (uint32_t) &exc24); set_idt_entry (25, (uint32_t) &exc25); set_idt_entry (26, (uint32_t) &exc26); set_idt_entry (27, (uint32_t) &exc27); set_idt_entry (28, (uint32_t) &exc28); set_idt_entry (29, (uint32_t) &exc29); set_idt_entry (30, (uint32_t) &exc30); set_idt_entry (31, (uint32_t) &exc31); remap_pics (); set_idt_entry (32, (uint32_t) &irq0); set_idt_entry (33, (uint32_t) &irq1); set_idt_entry (34, (uint32_t) &irq2); set_idt_entry (35, (uint32_t) &irq3); set_idt_entry (36, (uint32_t) &irq4); set_idt_entry (37, (uint32_t) &irq5); set_idt_entry (38, (uint32_t) &irq6); set_idt_entry (39, (uint32_t) &irq7); set_idt_entry (40, (uint32_t) &irq8); set_idt_entry (41, (uint32_t) &irq9); set_idt_entry (42, (uint32_t) &irq10); set_idt_entry (43, (uint32_t) &irq11); set_idt_entry (44, (uint32_t) &irq12); set_idt_entry (45, (uint32_t) &irq13); set_idt_entry (46, (uint32_t) &irq14); set_idt_entry (47, (uint32_t) &irq15); load_idt (); }
// This function must be called before doing anything with IRQs. // It remaps the PIC and sets up the ISRs for IRQs 1-15(IRQ 0 // is handled by the task scheduler). void setup_irqs() { k_printf("\nSetting up IRQs...\n"); k_printf("Remapping the PIC... "); remap_pics(0x40, 0x48); k_printf("completed\n"); k_printf("Masking all IRQs... "); mask_irq(0); mask_irq(1); mask_irq(2); mask_irq(3); mask_irq(4); mask_irq(5); mask_irq(6); mask_irq(7); mask_irq(8); mask_irq(9); mask_irq(10); mask_irq(11); mask_irq(12); mask_irq(13); mask_irq(14); mask_irq(15); k_printf("completed\n"); k_printf("Installing ISRs for IRQs 1-15... "); modify_gate_address((u_long)&irq_watcher_1, 0x41, 0); modify_gate_address((u_long)&irq_watcher_2, 0x42, 0); modify_gate_address((u_long)&irq_watcher_3, 0x43, 0); modify_gate_address((u_long)&irq_watcher_4, 0x44, 0); modify_gate_address((u_long)&irq_watcher_5, 0x45, 0); modify_gate_address((u_long)&irq_watcher_6, 0x46, 0); modify_gate_address((u_long)&irq_watcher_7, 0x47, 0); modify_gate_address((u_long)&irq_watcher_8, 0x48, 0); modify_gate_address((u_long)&irq_watcher_9, 0x49, 0); modify_gate_address((u_long)&irq_watcher_10, 0x4A, 0); modify_gate_address((u_long)&irq_watcher_11, 0x4B, 0); modify_gate_address((u_long)&irq_watcher_12, 0x4C, 0); modify_gate_address((u_long)&irq_watcher_13, 0x4D, 0); modify_gate_address((u_long)&irq_watcher_14, 0x4E, 0); modify_gate_address((u_long)&irq_watcher_15, 0x4F, 0); k_printf("completed\n"); k_printf("The IRQs have been setup.\n"); };
void install_idt() { idtp.limit=(sizeof(struct idt_entry)* 47)-1; /* 255 ISRs */ idtp.base=(unsigned int)&idt; remap_pics(0x20,0x28); /* remap interrups to; master pic interrups -> 0x20 (32) slave pic interrupts -> 0x28 (40) */ /* assing handlers to interrups & exceptions */ set_idt_entry(0 ,(unsigned long)&isr0,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(1 ,(unsigned long)&isr1,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(2 ,(unsigned long)&isr2,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(3 ,(unsigned long)&isr3,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(4 ,(unsigned long)&isr4,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(5 ,(unsigned long)&isr5,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(6 ,(unsigned long)&isr6,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(7 ,(unsigned long)&isr7,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(8 ,(unsigned long)&isr8,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(9 ,(unsigned long)&isr9,0x08 , 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(10,(unsigned long)&isr10,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(11,(unsigned long)&isr11,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(12,(unsigned long)&isr12,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(13,(unsigned long)&isr13,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(14,(unsigned long)&isr14,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(15,(unsigned long)&isr15,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(16,(unsigned long)&isr16,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(17,(unsigned long)&isr17,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(18,(unsigned long)&isr18,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(19,(unsigned long)&isr19,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(20,(unsigned long)&isr20,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(21,(unsigned long)&isr21,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(22,(unsigned long)&isr22,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(23,(unsigned long)&isr23,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(24,(unsigned long)&isr24,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(25,(unsigned long)&isr25,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(26,(unsigned long)&isr26,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(27,(unsigned long)&isr27,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(28,(unsigned long)&isr28,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(29,(unsigned long)&isr29,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(30,(unsigned long)&isr30,0x08, 0xF | PRESENT | KERNEL_LEVEL); set_idt_entry(31,(unsigned long)&isr31,0x08, 0xF | PRESENT | KERNEL_LEVEL); /* hardware IRQ handlers */ set_idt_entry(32,(unsigned long)&IRQ0,0x08, 0xF | PRESENT | KERNEL_LEVEL); // timer IRQ set_idt_entry(33,(unsigned long)&IRQ1,0x08, 0xF | PRESENT | KERNEL_LEVEL); // keyboard IRQ set_idt_entry(34,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(35,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(36,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(37,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(38,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(39,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(40,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(41,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(42,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(43,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(44,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(45,(unsigned long)&IRQ_NOT_IMPLEMENTED,0x08, 0xF | NOT_PRESENT | KERNEL_LEVEL); set_idt_entry(46,(unsigned long)&IRQ14,0x08, 0xF | PRESENT | KERNEL_LEVEL); // ata-0 handler set_idt_entry(47,(unsigned long)&IRQ15,0x08, 0xF | PRESENT | KERNEL_LEVEL); // ata-1 handler load_idt(); }