summaryrefslogtreecommitdiff
path: root/src/idt/idt.c
blob: a83c612a49a69c4318ad29855d3871c24019cf03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <stdint.h>
#include <toxic/config.h>
#include <toxic/string.h>
#include <toxic/vga.h>
#include <toxic/idt.h>
#include <toxic/io.h>

struct int_descriptor int_table[TOTAL_INTERRUPTS];
struct int_reg_descriptor idtr_descriptor;

extern void idt_load(struct int_reg_descriptor *desc);
extern void int21h();
extern void default_handler();

void
int21h_handler(void)
{
	vprintl("Keyboard pressed\n");
	outb(0x20, 0x20);
}

void
default_int_handler(void)
{
	/* Ack the Interrupt */
	outb(0x20, 0x20);
}

static void
idt_zero()
{
	vprintl("Illegal operation: Divide by zero\n");
}

static void
idt_set(int int_num, void *addr)
{
	struct int_descriptor *desc = &int_table[int_num];

	desc->offset_low = (uint32_t) addr & 0x0000FFFF;
	desc->selector = KERNEL_CODE_SELECTOR;
	desc->reserved = 0x00;
	desc->type_attr = TOXIC_INT_ATTR;
	desc->offset_high = (uint32_t) addr >> 16;
}

void
interrupts_init(void)
{
	int i;

	memset(int_table, 0, sizeof(int_table));

	idtr_descriptor.limit = sizeof(int_table) - 1;
	idtr_descriptor.base = (uint32_t) int_table;

	for (i = 0; i < TOTAL_INTERRUPTS; i++)
	       idt_set(i, default_handler);

	idt_set(0, idt_zero);
	idt_set(0x21, int21h);

	idt_load(&idtr_descriptor);
}