UnnamedOS
idt.c
Go to the documentation of this file.
1 
17 #include <common.h>
18 #include <interrupts/idt.h>
19 #include <mem/gdt.h>
20 
25 #define ISR_INIT(nr) extern void isr_intr_##nr(); \
26  idt_init_entry_isr((nr), &isr_intr_##nr, 0)
27 
29 typedef struct {
30  uint16_t limit;
31  uint32_t base;
32 } __attribute__((packed)) idtr_t;
33 
35 typedef enum {
36  TASK_32 = 0x5, INTR_16, TRAP_16, INTR_32 = 0xE, TRAP_32
38 
40 typedef struct {
41  uint16_t func0_15;
42  uint16_t selector;
43  uint8_t reserved;
44  idt_entry_type_t type : 4;
45  uint8_t st : 1;
46  uint8_t dpl : 2;
47  uint8_t pr : 1;
48  uint16_t func16_31;
49 } __attribute__((packed)) idt_entry_t;
50 
57 static idt_entry_t idt[IDT_ENTRIES];
58 
69 static void idt_init_entry(size_t entry, uintptr_t func, uint32_t selector,
70  idt_entry_type_t type, uint8_t st, uint8_t dpl, uint8_t pr) {
71  idt[entry].func0_15 = func & 0xFFFF; // 16 lower bits
72  idt[entry].func16_31 = (func >> 16) & 0xFFFF; // 16 higher bits
73  idt[entry].selector = selector;
74  idt[entry].reserved = 0;
75  idt[entry].type = type;
76  idt[entry].st = st;
77  idt[entry].dpl = dpl;
78  idt[entry].pr = pr;
79 }
80 
87 static void idt_init_entry_isr(size_t entry, void (*func)(), uint8_t dpl) {
88  idt_init_entry(entry, (uintptr_t) func,
89  gdt_get_selector(GDT_RING0_CODE_SEG), INTR_32, 0, dpl, 1);
90 }
91 
93 static void idt_load() {
94  idtr_t idtr = {.base = (uint32_t) idt, .limit = sizeof(idt) - 1};
95  asm volatile("lidt %0" : : "m" (idtr));
96 }
97 
99 void idt_init() {
100  print("IDT init ... ");
102  ISR_INIT(0x00); ISR_INIT(0x01); ISR_INIT(0x02); ISR_INIT(0x03);
103  ISR_INIT(0x04); ISR_INIT(0x05); ISR_INIT(0x06); ISR_INIT(0x07);
104  ISR_INIT(0x08); ISR_INIT(0x09); ISR_INIT(0x0A); ISR_INIT(0x0B);
105  ISR_INIT(0x0C); ISR_INIT(0x0D); ISR_INIT(0x0E); ISR_INIT(0x0F);
106  ISR_INIT(0x10); ISR_INIT(0x11); ISR_INIT(0x12); ISR_INIT(0x13);
107  ISR_INIT(0x14); ISR_INIT(0x15); ISR_INIT(0x16); ISR_INIT(0x17);
108  ISR_INIT(0x18); ISR_INIT(0x19); ISR_INIT(0x1A); ISR_INIT(0x1B);
109  ISR_INIT(0x1C); ISR_INIT(0x1D); ISR_INIT(0x1E); ISR_INIT(0x1F);
110  ISR_INIT(0x20); ISR_INIT(0x21); ISR_INIT(0x22); ISR_INIT(0x23);
111  ISR_INIT(0x24); ISR_INIT(0x25); ISR_INIT(0x26); ISR_INIT(0x27);
112  ISR_INIT(0x28); ISR_INIT(0x29); ISR_INIT(0x2A); ISR_INIT(0x2B);
113  ISR_INIT(0x2C); ISR_INIT(0x2D); ISR_INIT(0x2E); ISR_INIT(0x2F);
115  extern void isr_intr_0x30();
116  idt_init_entry_isr(0x30, &isr_intr_0x30, 3);
117  idt_load();
118  println("%2aok%a.");
119 }
120 
idt_entry_type_t type
gate type
Definition: idt.c:44
static void idt_init_entry_isr(size_t entry, void(*func)(), uint8_t dpl)
Shorthand for initializing an ISR.
Definition: idt.c:87
idt_entry_type_t
Different types of interrupt vectors.
Definition: idt.c:35
uint16_t func16_31
pointer to ISR (byte 3-4)
Definition: idt.c:48
uint32_t base
where the IDT is located
Definition: idt.c:31
uint16_t func0_15
pointer to ISR (byte 1-2)
Definition: idt.c:41
uint16_t limit
number of entries in the IDT
Definition: idt.c:30
uint8_t pr
present flag
Definition: idt.c:47
the IDTR register pointing to the IDT
Definition: idt.c:29
uint16_t gdt_get_selector(size_t entry)
Returns a selector ready to be loaded in a segment register.
Definition: gdt.c:103
#define IDT_ENTRIES
Number of entries in the IDT.
Definition: idt.h:11
uint16_t selector
RING0 code segment selector in GDT.
Definition: idt.c:42
uint8_t dpl
privilege (ring level)
Definition: idt.c:46
void idt_init()
Initializes the IDT.
Definition: idt.c:99
#define ISR_INIT(nr)
shorthand for initializing an ISR
Definition: idt.c:25
static idt_entry_t idt[IDT_ENTRIES]
The IDT itself.
Definition: idt.c:57
uint8_t st
storage segment flag
Definition: idt.c:45
An entry in the IDT.
Definition: idt.c:40
static void idt_init_entry(size_t entry, uintptr_t func, uint32_t selector, idt_entry_type_t type, uint8_t st, uint8_t dpl, uint8_t pr)
Initializes an IDT entry.
Definition: idt.c:69
static void idt_load()
Loads the IDT into the IDTR register.
Definition: idt.c:93
#define GDT_RING0_CODE_SEG
kernel code segment index
Definition: gdt.h:13
uint8_t reserved
always 0
Definition: idt.c:43