blob: 56ea13f0025d8d96cbfa6a808f33ab7793282cc9 [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
swissChilie4229a22023-01-01 15:59:53 -050050/*
swissChili1e8b7562021-12-22 21:22:57 -080051static void init_tss(uint num, uint ss, uint esp)
52{
53 gdt_set_gate(num, (uint)&tss_entry, (uint)&tss_entry+1, 0xe9, 0x00);
54
55 memset(&tss_entry, 0, sizeof(tss_entry));
56
57 tss_entry.ss0 = ss;
58 tss_entry.esp0 = esp;
59 tss_entry.cs = 0x0b;
60 // | 0b11 to make these readable from user-mode. i.e. user mode
61 // can switch to kernel mode using this tss
62 tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13;
63}
swissChilie4229a22023-01-01 15:59:53 -050064*/
swissChili1e8b7562021-12-22 21:22:57 -080065
66void init_gdt()
67{
68 vga_write("Initializing GDT...\n");
69 gdt_pointer.limit = sizeof(struct gdt_entry) * 5 - 1;
70 gdt_pointer.base = (uint)&gdt_entries;
71
72 gdt_set_gate(0, 0, 0, 0, 0); // Null segment, 0x00
73 gdt_set_gate(1, 0, ~0, 0x9a, 0xcf); // Code segment, 0x08
74 gdt_set_gate(2, 0, ~0, 0x92, 0xcf); // Data segment, 0x10
75 gdt_set_gate(3, 0, ~0, 0xfa, 0xcf); // User mode code segment, 0x18
76 gdt_set_gate(4, 0, ~0, 0xf2, 0xcf); // User mode data segment, 0x20
77 //init_tss(5, 0x10, 0x0); // 0x10 = kernel data segment, 0x28
78
79 for (volatile uint i = 0; i < 0x1000; i++)
80 {
81 } // waste some time, for some reason this helps
82
83 gdt_flush((uint)&gdt_pointer);
84 // For now let's not do this
85 // tss_flush();
86
87 vga_write("GDT Initialized\n");
88}
89
swissChilid8137922021-02-17 15:34:07 -080090void init_idt()
91{
92 idt_pointer.limit = sizeof(struct idt_entry) * 256 - 1;
93 idt_pointer.base = (uint)&idt_entries;
94
95 memset(&idt_entries, 0, sizeof(idt_entries));
96
swissChilidefeb0d2021-02-18 15:28:36 -080097 // Remap PIC
98 pic_remap();
swissChilid8137922021-02-17 15:34:07 -080099
swissChiliaed6ff32021-05-29 17:51:04 -0700100 init_faults();
101
swissChilidefeb0d2021-02-18 15:28:36 -0800102 vga_set_color(CYAN, BLACK);
103 for (int i = 0; i < 16; i++)
104 {
swissChilidefeb0d2021-02-18 15:28:36 -0800105 idt_set_gate(IRQ_TO_INT(i), (uint)irqs[i], 0x08, 0x8e);
106 }
107 vga_set_color(WHITE, BLACK);
swissChilid8137922021-02-17 15:34:07 -0800108
109 for (int i = 0; i < 32; i++)
110 {
111 idt_set_gate(i, (uint)isrs[i], 0x08, 0x8e);
112 }
113
swissChiliee6d10d2021-05-29 18:05:16 -0700114 idt_set_gate(0x80, (uint)isr128, 0x08, 0x8e);
115 idt_set_gate(0x81, (uint)isr129, 0x08, 0x8e);
116
swissChilid8137922021-02-17 15:34:07 -0800117 idt_flush((uint)&idt_pointer);
118
swissChilid8137922021-02-17 15:34:07 -0800119 vga_write("IDT Initialized!\n");
120}
121
122static void idt_set_gate(uchar num, uint base, ushort selector, uchar flags)
123{
124 struct idt_entry *e = &idt_entries[num];
125
126 e->base_low = base & 0xffff;
127 e->base_high = (base >> 16) & 0xffff;
128
129 e->selector = selector;
130 e->zero = 0;
131 e->flags = flags /* | 0x60 */;
132}
133
134void init_descriptor_tables()
135{
136 init_gdt();
137 init_idt();
swissChilid8137922021-02-17 15:34:07 -0800138}
swissChili1e8b7562021-12-22 21:22:57 -0800139
140void set_kernel_interrupt_stack(void *stack)
141{
142 tss_entry.esp0 = (uint)stack;
143}