blob: 36e6f8f3fc1c62dd10eaa1a63c211da75c17e9f0 [file] [log] [blame]
swissChilid8137922021-02-17 15:34:07 -08001#include "descriptor_tables.h"
2#include "vga.h"
3#include "mem.h"
4
5extern void gdt_flush(uint gdt);
6extern void idt_flush(uint idt);
7
8static void gdt_set_gate(uint i, uint base, uint limit, uchar access, uchar gran);
9static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags);
10
11struct gdt_entry gdt_entries[5];
12struct gdt_pointer gdt_pointer;
13
14struct idt_entry idt_entries[256];
15struct idt_pointer idt_pointer;
16
17static void (* isrs[32])() =
18{
19 isr0,
20 isr1,
21 isr2,
22 isr3,
23 isr4,
24 isr5,
25 isr6,
26 isr7,
27 isr8,
28 isr9,
29 isr10,
30 isr11,
31 isr12,
32 isr13,
33 isr14,
34 isr15,
35 isr16,
36 isr17,
37 isr18,
38 isr19,
39 isr20,
40 isr21,
41 isr22,
42 isr23,
43 isr24,
44 isr25,
45 isr26,
46 isr27,
47 isr28,
48 isr29,
49 isr30,
50 isr31
51};
52
53void init_gdt()
54{
swissChili0b35bf22021-02-18 12:49:40 -080055 vga_write("Initializing GDT...\n");
swissChilid8137922021-02-17 15:34:07 -080056 gdt_pointer.limit = sizeof(struct gdt_entry) * 5 - 1;
57 gdt_pointer.base = (uint)&gdt_entries;
58
59 gdt_set_gate(0, 0, 0, 0, 0); // Null segment
60 gdt_set_gate(1, 0, ~0, 0x9a, 0xcf); // Code segment
61 gdt_set_gate(2, 0, ~0, 0x92, 0xcf); // Data segment
62 gdt_set_gate(3, 0, ~0, 0xfa, 0xcf); // User mode code segment
63 gdt_set_gate(4, 0, ~0, 0xf2, 0xcf); // User mode data segment
64
swissChili0b35bf22021-02-18 12:49:40 -080065 for (volatile uint i = 0; i < 0x1000; i++)
66 {} // waste some time, for some reason this helps
67
swissChilid8137922021-02-17 15:34:07 -080068 gdt_flush((uint) &gdt_pointer);
69
70 vga_write("GDT Initialized\n");
71}
72
73static void gdt_set_gate(uint i, uint base, uint limit, uchar access, uchar gran)
74{
75 struct gdt_entry *e = &gdt_entries[i];
76
77 e->base_low = base & 0xffff;
78 e->base_middle = (base >> 16) & 0xff;
79 e->base_high = (base >> 24) & 0xff;
80
81 e->limit_low = limit & 0xffff;
82 e->granularity = ((limit >> 16) & 0x0f) | (gran & 0xf0);
83
84 e->access = access;
85}
86
87void init_idt()
88{
89 idt_pointer.limit = sizeof(struct idt_entry) * 256 - 1;
90 idt_pointer.base = (uint)&idt_entries;
91
92 memset(&idt_entries, 0, sizeof(idt_entries));
93
94 vga_write("sizeof(idt_entries) = ");
95 vga_putx(sizeof(idt_entries));
96 vga_put('\n');
97
98 vga_write("isr0 = ");
99 vga_putx((uint)isrs[0]);
100 vga_put('\n');
101
102 for (int i = 0; i < 32; i++)
103 {
104 idt_set_gate(i, (uint)isrs[i], 0x08, 0x8e);
105 }
106
107 idt_flush((uint)&idt_pointer);
108
109 vga_write("IDT Initialized!\n");
110}
111
112static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags)
113{
114 struct idt_entry *e = &idt_entries[num];
115
116 e->base_low = base & 0xffff;
117 e->base_high = (base >> 16) & 0xffff;
118
119 e->selector = selector;
120 e->zero = 0;
121 e->flags = flags /* | 0x60 */;
122}
123
124void init_descriptor_tables()
125{
126 init_gdt();
127 init_idt();
128}