blob: 339162e91f98b802d3912fefab2ded098eafad2c [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);
swissChili1e8b7562021-12-22 21:22:57 -080010extern void tss_flush();
swissChilid8137922021-02-17 15:34:07 -080011
swissChili825d46b2021-02-21 10:14:16 -080012static void gdt_set_gate(uint i, uint base, uint limit, uchar access,
13 uchar gran);
swissChilid8137922021-02-17 15:34:07 -080014static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags);
15
16struct gdt_entry gdt_entries[5];
17struct gdt_pointer gdt_pointer;
18
19struct idt_entry idt_entries[256];
20struct idt_pointer idt_pointer;
21
swissChili9b3584b2021-02-18 13:57:27 -080022static void (*isrs[32])() = {
swissChili825d46b2021-02-21 10:14:16 -080023 isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10,
24 isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19, isr20, isr21,
25 isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31};
swissChili9b3584b2021-02-18 13:57:27 -080026
swissChili825d46b2021-02-21 10:14:16 -080027static void (*irqs[16])() = {irq0, irq1, irq2, irq3, irq4, irq5,
28 irq6, irq7, irq8, irq9, irq10, irq11,
29 irq12, irq13, irq14, irq15};
30
31extern void (*interrupt_handlers[256])(struct registers);
swissChilid8137922021-02-17 15:34:07 -080032
swissChili1e8b7562021-12-22 21:22:57 -080033struct tss_entry tss_entry;
swissChilid8137922021-02-17 15:34:07 -080034
swissChili825d46b2021-02-21 10:14:16 -080035static void gdt_set_gate(uint i, uint base, uint limit, uchar access,
36 uchar gran)
swissChilid8137922021-02-17 15:34:07 -080037{
38 struct gdt_entry *e = &gdt_entries[i];
39
40 e->base_low = base & 0xffff;
41 e->base_middle = (base >> 16) & 0xff;
42 e->base_high = (base >> 24) & 0xff;
43
44 e->limit_low = limit & 0xffff;
45 e->granularity = ((limit >> 16) & 0x0f) | (gran & 0xf0);
46
47 e->access = access;
48}
49
swissChili1e8b7562021-12-22 21:22:57 -080050static void init_tss(uint num, uint ss, uint esp)
51{
52 gdt_set_gate(num, (uint)&tss_entry, (uint)&tss_entry+1, 0xe9, 0x00);
53
54 memset(&tss_entry, 0, sizeof(tss_entry));
55
56 tss_entry.ss0 = ss;
57 tss_entry.esp0 = esp;
58 tss_entry.cs = 0x0b;
59 // | 0b11 to make these readable from user-mode. i.e. user mode
60 // can switch to kernel mode using this tss
61 tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13;
62}
63
64void init_gdt()
65{
66 vga_write("Initializing GDT...\n");
67 gdt_pointer.limit = sizeof(struct gdt_entry) * 5 - 1;
68 gdt_pointer.base = (uint)&gdt_entries;
69
70 gdt_set_gate(0, 0, 0, 0, 0); // Null segment, 0x00
71 gdt_set_gate(1, 0, ~0, 0x9a, 0xcf); // Code segment, 0x08
72 gdt_set_gate(2, 0, ~0, 0x92, 0xcf); // Data segment, 0x10
73 gdt_set_gate(3, 0, ~0, 0xfa, 0xcf); // User mode code segment, 0x18
74 gdt_set_gate(4, 0, ~0, 0xf2, 0xcf); // User mode data segment, 0x20
75 //init_tss(5, 0x10, 0x0); // 0x10 = kernel data segment, 0x28
76
77 for (volatile uint i = 0; i < 0x1000; i++)
78 {
79 } // waste some time, for some reason this helps
80
81 gdt_flush((uint)&gdt_pointer);
82 // For now let's not do this
83 // tss_flush();
84
85 vga_write("GDT Initialized\n");
86}
87
swissChilid8137922021-02-17 15:34:07 -080088void init_idt()
89{
90 idt_pointer.limit = sizeof(struct idt_entry) * 256 - 1;
91 idt_pointer.base = (uint)&idt_entries;
92
93 memset(&idt_entries, 0, sizeof(idt_entries));
94
swissChilidefeb0d2021-02-18 15:28:36 -080095 // Remap PIC
96 pic_remap();
swissChilid8137922021-02-17 15:34:07 -080097
swissChiliaed6ff32021-05-29 17:51:04 -070098 init_faults();
99
swissChilidefeb0d2021-02-18 15:28:36 -0800100 vga_set_color(CYAN, BLACK);
101 for (int i = 0; i < 16; i++)
102 {
swissChilidefeb0d2021-02-18 15:28:36 -0800103 idt_set_gate(IRQ_TO_INT(i), (uint)irqs[i], 0x08, 0x8e);
104 }
105 vga_set_color(WHITE, BLACK);
swissChilid8137922021-02-17 15:34:07 -0800106
107 for (int i = 0; i < 32; i++)
108 {
109 idt_set_gate(i, (uint)isrs[i], 0x08, 0x8e);
110 }
111
swissChiliee6d10d2021-05-29 18:05:16 -0700112 idt_set_gate(0x80, (uint)isr128, 0x08, 0x8e);
113 idt_set_gate(0x81, (uint)isr129, 0x08, 0x8e);
114
swissChilid8137922021-02-17 15:34:07 -0800115 idt_flush((uint)&idt_pointer);
116
swissChilid8137922021-02-17 15:34:07 -0800117 vga_write("IDT Initialized!\n");
118}
119
120static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags)
121{
122 struct idt_entry *e = &idt_entries[num];
123
124 e->base_low = base & 0xffff;
125 e->base_high = (base >> 16) & 0xffff;
126
127 e->selector = selector;
128 e->zero = 0;
129 e->flags = flags /* | 0x60 */;
130}
131
132void init_descriptor_tables()
133{
134 init_gdt();
135 init_idt();
swissChilid8137922021-02-17 15:34:07 -0800136}
swissChili1e8b7562021-12-22 21:22:57 -0800137
138void set_kernel_interrupt_stack(void *stack)
139{
140 tss_entry.esp0 = (uint)stack;
141}