forked from Isuruni/MYOS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterrupts.c
80 lines (61 loc) · 2.11 KB
/
interrupts.c
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
#include "interrupts.h"
#include "pic.h"
#include "io.h"
#include "framebuffer.h"
#include "serial_port.h"
#include "keyboard.h"
#include "paging.h"
#define INTERRUPTS_DESCRIPTOR_COUNT 256
#define INTERRUPTS_KEYBOARD 33
#define INTERRUPTS_PAGING 14
isr_t interrupt_handlers[256];
registers_t regs;
void register_interrupt_handler(u8int n, isr_t handler) {
interrupt_handlers[n] = handler;
}
struct IDTDescriptor idt_descriptors[INTERRUPTS_DESCRIPTOR_COUNT];
struct IDT idt;
void interrupts_init_descriptor(int index, unsigned int address)
{
idt_descriptors[index].offset_high = (address >> 16) & 0xFFFF; // offset bits 0..15
idt_descriptors[index].offset_low = (address & 0xFFFF); // offset bits 16..31
idt_descriptors[index].segment_selector = 0x08; // The second (code) segment selector in GDT: one segment is 64b.
idt_descriptors[index].reserved = 0x00; // Reserved.
idt_descriptors[index].type_and_attr = (0x01 << 7) | // P
(0x00 << 6) | (0x00 << 5) | // DPL
0xe; // 0b1110=0xE 32-bit interrupt gate
}
void interrupts_install_idt()
{
interrupts_init_descriptor(INTERRUPTS_KEYBOARD, (unsigned int) interrupt_handler_33);
interrupts_init_descriptor(INTERRUPTS_PAGING, (unsigned int) interrupt_handler_14);
idt.address = (int) &idt_descriptors;
idt.size = sizeof(struct IDTDescriptor) * INTERRUPTS_DESCRIPTOR_COUNT;
load_idt((int) &idt);
/*pic_remap(PIC_PIC1_OFFSET, PIC_PIC2_OFFSET);*/
pic_remap(PIC_1_OFFSET, PIC_2_OFFSET);
}
/* Interrupt handlers ********************************************************/
void interrupt_handler(__attribute__((unused)) struct cpu_state cpu, unsigned int interrupt, __attribute__((unused)) struct stack_state stack)
{
unsigned char scan_code;
unsigned char ascii;
switch (interrupt){
case INTERRUPTS_KEYBOARD:
scan_code = keyboard_read_scan_code();
if (scan_code <= KEYBOARD_MAX_ASCII) {
ascii = keyboard_scan_code_to_ascii(scan_code);
char str[1];
str[0] = ascii;
fb_write(str, 1);
serial_write(0x3F8,str,1);
}
pic_acknowledge(interrupt);
break;
case INTERRUPTS_PAGING:
page_fault(regs);
break;
default:
break;
}
}