blob: 3b121b1668d58a71bce8aab4ec425deeec2d7cdb [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{
55 gdt_pointer.limit = sizeof(struct gdt_entry) * 5 - 1;
56 gdt_pointer.base = (uint)&gdt_entries;
57
58 gdt_set_gate(0, 0, 0, 0, 0); // Null segment
59 gdt_set_gate(1, 0, ~0, 0x9a, 0xcf); // Code segment
60 gdt_set_gate(2, 0, ~0, 0x92, 0xcf); // Data segment
61 gdt_set_gate(3, 0, ~0, 0xfa, 0xcf); // User mode code segment
62 gdt_set_gate(4, 0, ~0, 0xf2, 0xcf); // User mode data segment
63
64 gdt_flush((uint) &gdt_pointer);
65
66 vga_write("GDT Initialized\n");
67}
68
69static void gdt_set_gate(uint i, uint base, uint limit, uchar access, uchar gran)
70{
71 struct gdt_entry *e = &gdt_entries[i];
72
73 e->base_low = base & 0xffff;
74 e->base_middle = (base >> 16) & 0xff;
75 e->base_high = (base >> 24) & 0xff;
76
77 e->limit_low = limit & 0xffff;
78 e->granularity = ((limit >> 16) & 0x0f) | (gran & 0xf0);
79
80 e->access = access;
81}
82
83void init_idt()
84{
85 idt_pointer.limit = sizeof(struct idt_entry) * 256 - 1;
86 idt_pointer.base = (uint)&idt_entries;
87
88 memset(&idt_entries, 0, sizeof(idt_entries));
89
90 vga_write("sizeof(idt_entries) = ");
91 vga_putx(sizeof(idt_entries));
92 vga_put('\n');
93
94 vga_write("isr0 = ");
95 vga_putx((uint)isrs[0]);
96 vga_put('\n');
97
98 for (int i = 0; i < 32; i++)
99 {
100 idt_set_gate(i, (uint)isrs[i], 0x08, 0x8e);
101 }
102
103 idt_flush((uint)&idt_pointer);
104
105 vga_write("IDT Initialized!\n");
106}
107
108static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags)
109{
110 struct idt_entry *e = &idt_entries[num];
111
112 e->base_low = base & 0xffff;
113 e->base_high = (base >> 16) & 0xffff;
114
115 e->selector = selector;
116 e->zero = 0;
117 e->flags = flags /* | 0x60 */;
118}
119
120void init_descriptor_tables()
121{
122 init_gdt();
123 init_idt();
124}