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
|
#include "bindings.h"
#include "pic.h"
#define PIC1_COMMAND_PORT 0x20
#define PIC1_DATA_PORT 0x21
#define PIC2_COMMAND_PORT 0xA0
#define PIC2_DATA_PORT 0xA1
void pic_remap(void) {
char a1 = inb(PIC1_DATA_PORT);
char a2 = inb(PIC2_DATA_PORT);
// control word 1
// 0x11: initialize, enable ICW4
outb(PIC1_COMMAND_PORT, 0x11);
io_wait();
outb(PIC2_COMMAND_PORT, 0x11);
io_wait();
// control word 2
// interrupt offset
outb(PIC1_DATA_PORT, PIC_REMAP_OFFSET);
io_wait();
outb(PIC2_DATA_PORT, PIC_REMAP_OFFSET + 8);
io_wait();
// control word 3
// primary pic: set which pin secondary is connected to
// (pin 2)
outb(PIC1_DATA_PORT, 0x04);
io_wait();
outb(PIC2_DATA_PORT, 2);
io_wait();
// control word 3
// 0x01: enable 8086 mode
outb(PIC1_DATA_PORT, 0x01);
io_wait();
outb(PIC2_DATA_PORT, 0x01);
io_wait();
// clear data registers
outb(PIC1_DATA_PORT, a1);
outb(PIC2_DATA_PORT, a2);
}
void pic_mask(int irq) {
uint8_t port;
if(irq < 8) {
port = PIC1_DATA_PORT;
} else {
irq -= 8;
port = PIC2_DATA_PORT;
}
uint8_t mask = inb(port);
outb(port, mask | (1 << irq));
}
void pic_unmask(int irq) {
uint8_t port;
if(irq < 8) {
port = PIC1_DATA_PORT;
} else {
irq -= 8;
port = PIC2_DATA_PORT;
}
uint8_t mask = inb(port);
outb(port, mask & ~(1 << irq));
}
void pic_disable(void) {
outb(PIC1_DATA_PORT, 0xff);
io_wait();
outb(PIC2_DATA_PORT, 0xff);
io_wait();
}
void pic_eoi(int irq) {
if(irq >= 8) {
outb(PIC2_COMMAND_PORT, 0x20);
}
outb(PIC1_COMMAND_PORT, 0x20);
}
|