-
Notifications
You must be signed in to change notification settings - Fork 0
/
interrupt.c
117 lines (98 loc) · 3.88 KB
/
interrupt.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
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
/*
* interrupt.c -
*/
#include <types.h>
#include <interrupt.h>
#include <segment.h>
#include <hardware.h>
#include <io.h>
#include <zeos_interrupt.h>
Gate idt[IDT_ENTRIES];
Register idtR;
void keyboard_handler();
void clock_handler();
char char_map[] =
{
'\0','\0','1','2','3','4','5','6',
'7','8','9','0','\'','¡','\0','\0',
'q','w','e','r','t','y','u','i',
'o','p','`','+','\0','\0','a','s',
'd','f','g','h','j','k','l','ñ',
'\0','º','\0','ç','z','x','c','v',
'b','n','m',',','.','-','\0','*',
'\0','\0','\0','\0','\0','\0','\0','\0',
'\0','\0','\0','\0','\0','\0','\0','7',
'8','9','-','4','5','6','+','1',
'2','3','0','\0','\0','\0','<','\0',
'\0','\0','\0','\0','\0','\0','\0','\0',
'\0','\0'
};
void setInterruptHandler(int vector, void (*handler)(), int maxAccessibleFromPL)
{
/***********************************************************************/
/* THE INTERRUPTION GATE FLAGS: R1: pg. 5-11 */
/* *************************** */
/* flags = x xx 0x110 000 ????? */
/* | | | */
/* | | \ D = Size of gate: 1 = 32 bits; 0 = 16 bits */
/* | \ DPL = Num. higher PL from which it is accessible */
/* \ P = Segment Present bit */
/***********************************************************************/
Word flags = (Word)(maxAccessibleFromPL << 13);
flags |= 0x8E00; /* P = 1, D = 1, Type = 1110 (Interrupt Gate) */
idt[vector].lowOffset = lowWord((DWord)handler);
idt[vector].segmentSelector = __KERNEL_CS;
idt[vector].flags = flags;
idt[vector].highOffset = highWord((DWord)handler);
}
void setTrapHandler(int vector, void (*handler)(), int maxAccessibleFromPL)
{
/***********************************************************************/
/* THE TRAP GATE FLAGS: R1: pg. 5-11 */
/* ******************** */
/* flags = x xx 0x111 000 ????? */
/* | | | */
/* | | \ D = Size of gate: 1 = 32 bits; 0 = 16 bits */
/* | \ DPL = Num. higher PL from which it is accessible */
/* \ P = Segment Present bit */
/***********************************************************************/
Word flags = (Word)(maxAccessibleFromPL << 13);
//flags |= 0x8F00; /* P = 1, D = 1, Type = 1111 (Trap Gate) */
/* Changed to 0x8e00 to convert it to an 'interrupt gate' and so
the system calls will be thread-safe. */
flags |= 0x8E00; /* P = 1, D = 1, Type = 1110 (Interrupt Gate) */
idt[vector].lowOffset = lowWord((DWord)handler);
idt[vector].segmentSelector = __KERNEL_CS;
idt[vector].flags = flags;
idt[vector].highOffset = highWord((DWord)handler);
}
void syscall_handler_sysenter();
void write_msr(unsigned long msr, unsigned long value);
void setIdt()
{
/* Program interrups/exception service routines */
idtR.base = (DWord)idt;
idtR.limit = IDT_ENTRIES * sizeof(Gate) - 1;
set_handlers();
/* ADD INITIALIZATION CODE FOR INTERRUPT VECTOR */
setInterruptHandler (32, clock_handler, 0);
setInterruptHandler (33, keyboard_handler, 0);
write_msr(0x174, __KERNEL_CS);
write_msr(0x175, INITIAL_ESP);
write_msr(0x176, (unsigned long)syscall_handler_sysenter);
set_idt_reg(&idtR);
}
void keyboard_routine(){
unsigned char c = inb(0x60);
int is_break = c & 0x80;
if (! is_break){
char c_to_print = char_map[c & 0x7F];
if (c_to_print == '\0') c_to_print = 'C';
printc_xy (60, 5, c_to_print);
}
}
int zeos_ticks = 0;
void clock_routine(){
zeos_show_clock();
zeos_ticks++;
}