Welcome to The Fiwix Project
A UNIX-like kernel for the i386 architecture
1 /* 2 * fiwix/kernel/idt.c 3 * 4 * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved. 5 * Distributed under the terms of the Fiwix License. 6 */ 7 8 #include <fiwix/asm.h> 9 #include <fiwix/types.h> 10 #include <fiwix/segments.h> 11 #include <fiwix/string.h> 12 13 struct gate_desc idt[NR_IDT_ENTRIES]; 14 15 struct desc_r idtr = { 16 sizeof(idt) - 1, 17 (unsigned int)idt 18 }; 19 20 static void *except_handlers[] = { 21 &except0, &except1, &except2, &except3, &except4, &except5, &except6, &except7, 22 &except8, &except9, &except10, &except11, &except12, &except13, &except14, &except15, 23 &except16, &except17, &except18, &except19, &except20, &except21, &except22, &except23, 24 &except24, &except25, &except26, &except27, &except28, &except29, &except30, &except31 25 }; 26 27 static void *irq_handlers[] = { 28 &irq0, &irq1, &irq2, &irq3, &irq4, &irq5, &irq6, &irq7, 29 &irq8, &irq9, &irq10, &irq11, &irq12, &irq13, &irq14, &irq15 30 }; 31 32 static void set_idt_entry(int num, __off_t handler, unsigned int flags) 33 { 34 idt[num].gd_looffset = handler & 0x0000FFFF; 35 idt[num].gd_selector = KERNEL_CS; 36 idt[num].gd_flags = flags << 8; 37 idt[num].gd_hioffset = handler >> 16; 38 } 39 40 void idt_init(void) 41 { 42 int n; 43 44 memset_b(idt, NULL, sizeof(idt)); 45 for(n = 0; n < NR_IDT_ENTRIES; n++) { 46 if(n < 0x20) { 47 set_idt_entry(n, (__off_t)except_handlers[n], SD_32TRAPGATE | SD_PRESENT); 48 continue; 49 } 50 if(n < 0x30) { 51 set_idt_entry(n, (__off_t)irq_handlers[n - 0x20], SD_32INTRGATE | SD_PRESENT); 52 continue; 53 } 54 set_idt_entry(n, (__off_t)&unknown_irq, SD_32INTRGATE | SD_PRESENT); 55 } 56 57 set_idt_entry(0x80, (__off_t)&syscall, SD_32TRAPGATE | SD_DPL3 | SD_PRESENT); 58 59 load_idt((unsigned int)&idtr); 60 }