blob: 916a1aec8e1d8932573f2bbbba5694cd1f42e958 [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"
swissChilid8137922021-02-17 15:34:07 -08006
7extern void gdt_flush(uint gdt);
8extern void idt_flush(uint idt);
9
swissChili825d46b2021-02-21 10:14:16 -080010static void gdt_set_gate(uint i, uint base, uint limit, uchar access,
11 uchar gran);
swissChilid8137922021-02-17 15:34:07 -080012static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags);
13
14struct gdt_entry gdt_entries[5];
15struct gdt_pointer gdt_pointer;
16
17struct idt_entry idt_entries[256];
18struct idt_pointer idt_pointer;
19
swissChili9b3584b2021-02-18 13:57:27 -080020static void (*isrs[32])() = {
swissChili825d46b2021-02-21 10:14:16 -080021 isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10,
22 isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19, isr20, isr21,
23 isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31};
swissChili9b3584b2021-02-18 13:57:27 -080024
swissChili825d46b2021-02-21 10:14:16 -080025static void (*irqs[16])() = {irq0, irq1, irq2, irq3, irq4, irq5,
26 irq6, irq7, irq8, irq9, irq10, irq11,
27 irq12, irq13, irq14, irq15};
28
29extern void (*interrupt_handlers[256])(struct registers);
swissChilid8137922021-02-17 15:34:07 -080030
31void init_gdt()
32{
swissChili0b35bf22021-02-18 12:49:40 -080033 vga_write("Initializing GDT...\n");
swissChilid8137922021-02-17 15:34:07 -080034 gdt_pointer.limit = sizeof(struct gdt_entry) * 5 - 1;
35 gdt_pointer.base = (uint)&gdt_entries;
36
swissChili825d46b2021-02-21 10:14:16 -080037 gdt_set_gate(0, 0, 0, 0, 0); // Null segment
38 gdt_set_gate(1, 0, ~0, 0x9a, 0xcf); // Code segment
39 gdt_set_gate(2, 0, ~0, 0x92, 0xcf); // Data segment
40 gdt_set_gate(3, 0, ~0, 0xfa, 0xcf); // User mode code segment
41 gdt_set_gate(4, 0, ~0, 0xf2, 0xcf); // User mode data segment
swissChilid8137922021-02-17 15:34:07 -080042
swissChili0b35bf22021-02-18 12:49:40 -080043 for (volatile uint i = 0; i < 0x1000; i++)
swissChili825d46b2021-02-21 10:14:16 -080044 {
45 } // waste some time, for some reason this helps
46
47 gdt_flush((uint)&gdt_pointer);
swissChilid8137922021-02-17 15:34:07 -080048
49 vga_write("GDT Initialized\n");
50}
51
swissChili825d46b2021-02-21 10:14:16 -080052static void gdt_set_gate(uint i, uint base, uint limit, uchar access,
53 uchar gran)
swissChilid8137922021-02-17 15:34:07 -080054{
55 struct gdt_entry *e = &gdt_entries[i];
56
57 e->base_low = base & 0xffff;
58 e->base_middle = (base >> 16) & 0xff;
59 e->base_high = (base >> 24) & 0xff;
60
61 e->limit_low = limit & 0xffff;
62 e->granularity = ((limit >> 16) & 0x0f) | (gran & 0xf0);
63
64 e->access = access;
65}
66
67void init_idt()
68{
69 idt_pointer.limit = sizeof(struct idt_entry) * 256 - 1;
70 idt_pointer.base = (uint)&idt_entries;
71
72 memset(&idt_entries, 0, sizeof(idt_entries));
73
swissChilidefeb0d2021-02-18 15:28:36 -080074 // Remap PIC
75 pic_remap();
swissChilid8137922021-02-17 15:34:07 -080076
swissChilidefeb0d2021-02-18 15:28:36 -080077 vga_set_color(CYAN, BLACK);
78 for (int i = 0; i < 16; i++)
79 {
swissChilidefeb0d2021-02-18 15:28:36 -080080 idt_set_gate(IRQ_TO_INT(i), (uint)irqs[i], 0x08, 0x8e);
81 }
82 vga_set_color(WHITE, BLACK);
swissChilid8137922021-02-17 15:34:07 -080083
84 for (int i = 0; i < 32; i++)
85 {
86 idt_set_gate(i, (uint)isrs[i], 0x08, 0x8e);
87 }
88
89 idt_flush((uint)&idt_pointer);
90
swissChilid8137922021-02-17 15:34:07 -080091 vga_write("IDT Initialized!\n");
92}
93
94static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags)
95{
96 struct idt_entry *e = &idt_entries[num];
97
98 e->base_low = base & 0xffff;
99 e->base_high = (base >> 16) & 0xffff;
100
101 e->selector = selector;
102 e->zero = 0;
103 e->flags = flags /* | 0x60 */;
104}
105
106void init_descriptor_tables()
107{
108 init_gdt();
109 init_idt();
swissChili825d46b2021-02-21 10:14:16 -0800110 memset(interrupt_handlers, 0, sizeof(interrupt_handlers));
swissChilid8137922021-02-17 15:34:07 -0800111}