]> pd.if.org Git - zos/blob - pic.c
add a readme with a public domain note
[zos] / pic.c
1 #include <stdint.h>
2
3 #include "kernel.h"
4
5 #include "ioport.h"
6
7 #include "pic.h"
8 #include "interrupt.h"
9
10 /* ioports */
11 #define MCMD 0x20
12 #define SCMD 0xA0
13 #define MDATA 0x21
14 #define SDATA 0xA1
15
16 #define IRR 0x0A
17 #define ISR 0x0B
18
19 #define EOI 0x20
20 #define ICW1_ICW4  0x01
21 #define CMD_INIT  0x10
22 #define MODE_8086  0x01
23
24 static uint16_t readregister(uint8_t ocw3) {
25         outport8(MCMD, ocw3);
26         outport8(SCMD, ocw3);
27         return inport8(MCMD) | inport8(SCMD) << 8;
28 }
29
30 static uint16_t readirr() {
31         return readregister(IRR);
32 }
33
34 static uint16_t readisr() {
35         return readregister(ISR);
36 }
37
38 static void reprogram() {
39         outport8(MCMD, CMD_INIT | ICW1_ICW4);
40         outport8(SCMD, CMD_INIT | ICW1_ICW4);
41         outport8(MDATA, IRQ0);
42         outport8(SDATA, IRQ8);
43         outport8(MDATA, 0x04); /* Slave PIC at IRQ2 */
44         outport8(SDATA, 0x02); /* Cascade Identity */
45         outport8(MDATA, MODE_8086);
46         outport8(SDATA, MODE_8086);
47         /* masks */
48         outport8(MDATA, 0);
49         outport8(SDATA, 0);
50 }
51
52 static void deprogram() {
53         outport8(MCMD, CMD_INIT | ICW1_ICW4);
54         outport8(SCMD, CMD_INIT | ICW1_ICW4);
55         outport8(MDATA, 0x08);
56         outport8(SDATA, 0x70);
57         outport8(MDATA, 0x04); /* Slave PIC at IRQ2 */
58         outport8(SDATA, 0x02); /* Cascade Identity */
59         outport8(MDATA, MODE_8086);
60         outport8(SDATA, MODE_8086);
61         outport8(MDATA, 0);
62         outport8(SDATA, 0);
63 }
64
65 static void sendmastereoi() {
66         outport8(MCMD, EOI);
67 }
68
69 static void sendslaveeoi() {
70         outport8(SCMD, EOI);
71 }
72
73 static void sendeoi(unsigned int irq) {
74         if (irq >= 8) {
75                 sendslaveeoi();
76         }
77         sendmastereoi();
78 }
79
80 struct pic pic;
81
82 void pic_init() {
83         pic.eoi = sendeoi;
84         pic.mastereoi = sendmastereoi;
85         pic.readirr = readirr;
86         pic.readisr = readisr;
87         pic.reprogram = reprogram;
88         pic.deprogram = deprogram;
89 }