blob: 211dcb23e74071934eb41bd874c3b60332afad24 [file] [log] [blame]
swissChilid8137922021-02-17 15:34:07 -08001#include "descriptor_tables.h"
swissChili9b3584b2021-02-18 13:57:27 -08002#include "io.h"
swissChilidefeb0d2021-02-18 15:28:36 -08003#include "log.h"
swissChili9b3584b2021-02-18 13:57:27 -08004#include "pic.h"
swissChili825d46b2021-02-21 10:14:16 -08005#include "vga.h"
swissChiliaed6ff32021-05-29 17:51:04 -07006#include "faults.h"
swissChilid8137922021-02-17 15:34:07 -08007
8extern void gdt_flush(uint gdt);
9extern void idt_flush(uint idt);
10
swissChili825d46b2021-02-21 10:14:16 -080011static void gdt_set_gate(uint i, uint base, uint limit, uchar access,
12 uchar gran);
swissChilid8137922021-02-17 15:34:07 -080013static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags);
14
15struct gdt_entry gdt_entries[5];
16struct gdt_pointer gdt_pointer;
17
18struct idt_entry idt_entries[256];
19struct idt_pointer idt_pointer;
20
swissChili9b3584b2021-02-18 13:57:27 -080021static void (*isrs[32])() = {
swissChili825d46b2021-02-21 10:14:16 -080022 isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10,
23 isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19, isr20, isr21,
24 isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31};
swissChili9b3584b2021-02-18 13:57:27 -080025
swissChili825d46b2021-02-21 10:14:16 -080026static void (*irqs[16])() = {irq0, irq1, irq2, irq3, irq4, irq5,
27 irq6, irq7, irq8, irq9, irq10, irq11,
28 irq12, irq13, irq14, irq15};
29
30extern void (*interrupt_handlers[256])(struct registers);
swissChilid8137922021-02-17 15:34:07 -080031
32void init_gdt()
33{
swissChili0b35bf22021-02-18 12:49:40 -080034 vga_write("Initializing GDT...\n");
swissChilid8137922021-02-17 15:34:07 -080035 gdt_pointer.limit = sizeof(struct gdt_entry) * 5 - 1;
36 gdt_pointer.base = (uint)&gdt_entries;
37
swissChili825d46b2021-02-21 10:14:16 -080038 gdt_set_gate(0, 0, 0, 0, 0); // Null segment
39 gdt_set_gate(1, 0, ~0, 0x9a, 0xcf); // Code segment
40 gdt_set_gate(2, 0, ~0, 0x92, 0xcf); // Data segment
41 gdt_set_gate(3, 0, ~0, 0xfa, 0xcf); // User mode code segment
42 gdt_set_gate(4, 0, ~0, 0xf2, 0xcf); // User mode data segment
swissChilid8137922021-02-17 15:34:07 -080043
swissChili0b35bf22021-02-18 12:49:40 -080044 for (volatile uint i = 0; i < 0x1000; i++)
swissChili825d46b2021-02-21 10:14:16 -080045 {
46 } // waste some time, for some reason this helps
47
48 gdt_flush((uint)&gdt_pointer);
swissChilid8137922021-02-17 15:34:07 -080049
50 vga_write("GDT Initialized\n");
51}
52
swissChili825d46b2021-02-21 10:14:16 -080053static void gdt_set_gate(uint i, uint base, uint limit, uchar access,
54 uchar gran)
swissChilid8137922021-02-17 15:34:07 -080055{
56 struct gdt_entry *e = &gdt_entries[i];
57
58 e->base_low = base & 0xffff;
59 e->base_middle = (base >> 16) & 0xff;
60 e->base_high = (base >> 24) & 0xff;
61
62 e->limit_low = limit & 0xffff;
63 e->granularity = ((limit >> 16) & 0x0f) | (gran & 0xf0);
64
65 e->access = access;
66}
67
68void init_idt()
69{
70 idt_pointer.limit = sizeof(struct idt_entry) * 256 - 1;
71 idt_pointer.base = (uint)&idt_entries;
72
73 memset(&idt_entries, 0, sizeof(idt_entries));
74
swissChilidefeb0d2021-02-18 15:28:36 -080075 // Remap PIC
76 pic_remap();
swissChilid8137922021-02-17 15:34:07 -080077
swissChiliaed6ff32021-05-29 17:51:04 -070078 init_faults();
79
swissChilidefeb0d2021-02-18 15:28:36 -080080 vga_set_color(CYAN, BLACK);
81 for (int i = 0; i < 16; i++)
82 {
swissChilidefeb0d2021-02-18 15:28:36 -080083 idt_set_gate(IRQ_TO_INT(i), (uint)irqs[i], 0x08, 0x8e);
84 }
85 vga_set_color(WHITE, BLACK);
swissChilid8137922021-02-17 15:34:07 -080086
87 for (int i = 0; i < 32; i++)
88 {
89 idt_set_gate(i, (uint)isrs[i], 0x08, 0x8e);
90 }
91
swissChiliee6d10d2021-05-29 18:05:16 -070092 idt_set_gate(0x80, (uint)isr128, 0x08, 0x8e);
93 idt_set_gate(0x81, (uint)isr129, 0x08, 0x8e);
94
swissChilid8137922021-02-17 15:34:07 -080095 idt_flush((uint)&idt_pointer);
96
swissChilid8137922021-02-17 15:34:07 -080097 vga_write("IDT Initialized!\n");
98}
99
100static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags)
101{
102 struct idt_entry *e = &idt_entries[num];
103
104 e->base_low = base & 0xffff;
105 e->base_high = (base >> 16) & 0xffff;
106
107 e->selector = selector;
108 e->zero = 0;
109 e->flags = flags /* | 0x60 */;
110}
111
112void init_descriptor_tables()
113{
114 init_gdt();
115 init_idt();
swissChilid8137922021-02-17 15:34:07 -0800116}