forked from cfenollosa/os-tutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathisr.c
More file actions
153 lines (139 loc) · 3.86 KB
/
isr.c
File metadata and controls
153 lines (139 loc) · 3.86 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "isr.h"
#include "idt.h"
#include "../drivers/screen.h"
#include "../drivers/keyboard.h"
#include "../libc/string.h"
#include "timer.h"
#include "ports.h"
isr_t interrupt_handlers[256];
/* Can't do this with a loop because we need the address
* of the function names */
void isr_install() {
set_idt_gate(0, (u32)isr0);
set_idt_gate(1, (u32)isr1);
set_idt_gate(2, (u32)isr2);
set_idt_gate(3, (u32)isr3);
set_idt_gate(4, (u32)isr4);
set_idt_gate(5, (u32)isr5);
set_idt_gate(6, (u32)isr6);
set_idt_gate(7, (u32)isr7);
set_idt_gate(8, (u32)isr8);
set_idt_gate(9, (u32)isr9);
set_idt_gate(10, (u32)isr10);
set_idt_gate(11, (u32)isr11);
set_idt_gate(12, (u32)isr12);
set_idt_gate(13, (u32)isr13);
set_idt_gate(14, (u32)isr14);
set_idt_gate(15, (u32)isr15);
set_idt_gate(16, (u32)isr16);
set_idt_gate(17, (u32)isr17);
set_idt_gate(18, (u32)isr18);
set_idt_gate(19, (u32)isr19);
set_idt_gate(20, (u32)isr20);
set_idt_gate(21, (u32)isr21);
set_idt_gate(22, (u32)isr22);
set_idt_gate(23, (u32)isr23);
set_idt_gate(24, (u32)isr24);
set_idt_gate(25, (u32)isr25);
set_idt_gate(26, (u32)isr26);
set_idt_gate(27, (u32)isr27);
set_idt_gate(28, (u32)isr28);
set_idt_gate(29, (u32)isr29);
set_idt_gate(30, (u32)isr30);
set_idt_gate(31, (u32)isr31);
// Remap the PIC
port_byte_out(0x20, 0x11);
port_byte_out(0xA0, 0x11);
port_byte_out(0x21, 0x20);
port_byte_out(0xA1, 0x28);
port_byte_out(0x21, 0x04);
port_byte_out(0xA1, 0x02);
port_byte_out(0x21, 0x01);
port_byte_out(0xA1, 0x01);
port_byte_out(0x21, 0x0);
port_byte_out(0xA1, 0x0);
// Install the IRQs
set_idt_gate(32, (u32)irq0);
set_idt_gate(33, (u32)irq1);
set_idt_gate(34, (u32)irq2);
set_idt_gate(35, (u32)irq3);
set_idt_gate(36, (u32)irq4);
set_idt_gate(37, (u32)irq5);
set_idt_gate(38, (u32)irq6);
set_idt_gate(39, (u32)irq7);
set_idt_gate(40, (u32)irq8);
set_idt_gate(41, (u32)irq9);
set_idt_gate(42, (u32)irq10);
set_idt_gate(43, (u32)irq11);
set_idt_gate(44, (u32)irq12);
set_idt_gate(45, (u32)irq13);
set_idt_gate(46, (u32)irq14);
set_idt_gate(47, (u32)irq15);
set_idt(); // Load with ASM
}
/* To print the message which defines every exception */
char *exception_messages[] = {
"Division By Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Into Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void isr_handler(registers_t r) {
kprint("received interrupt: ");
char s[3];
int_to_ascii(r.int_no, s);
kprint(s);
kprint("\n");
kprint(exception_messages[r.int_no]);
kprint("\n");
}
void register_interrupt_handler(u8 n, isr_t handler) {
interrupt_handlers[n] = handler;
}
void irq_handler(registers_t r) {
/* After every interrupt we need to send an EOI to the PICs
* or they will not send another interrupt again */
if (r.int_no >= 40) port_byte_out(0xA0, 0x20); /* slave */
port_byte_out(0x20, 0x20); /* master */
/* Handle the interrupt in a more modular way */
if (interrupt_handlers[r.int_no] != 0) {
isr_t handler = interrupt_handlers[r.int_no];
handler(r);
}
}
void irq_install() {
/* Enable interruptions */
asm volatile("sti");
/* IRQ0: timer */
init_timer(50);
/* IRQ1: keyboard */
init_keyboard();
}