strat9_kernel/arch/x86_64/
pic.rs1use super::io::{inb, outb};
8
9const MASTER_COMMAND: u16 = 0x20;
11const MASTER_DATA: u16 = 0x21;
13const SLAVE_COMMAND: u16 = 0xA0;
15const SLAVE_DATA: u16 = 0xA1;
17
18const ICW1_INIT: u8 = 0x10;
20const ICW1_ICW4: u8 = 0x01;
21const ICW3_SLAVE_PIC: u8 = 0x04;
23const ICW3_CASCADE: u8 = 0x02;
25const ICW4_8086: u8 = 0x01;
27
28const COMMAND_EOI: u8 = 0x20;
30
31pub const PIC1_OFFSET: u8 = 0x20;
33pub const PIC2_OFFSET: u8 = 0x28;
35
36pub fn init(offset1: u8, offset2: u8) {
40 unsafe {
41 let mask1 = inb(MASTER_DATA);
43 let mask2 = inb(SLAVE_DATA);
44
45 outb(MASTER_COMMAND, ICW1_INIT | ICW1_ICW4);
47 super::io::io_wait();
48 outb(SLAVE_COMMAND, ICW1_INIT | ICW1_ICW4);
49 super::io::io_wait();
50
51 outb(MASTER_DATA, offset1);
53 super::io::io_wait();
54 outb(SLAVE_DATA, offset2);
55 super::io::io_wait();
56
57 outb(MASTER_DATA, ICW3_SLAVE_PIC);
59 super::io::io_wait();
60 outb(SLAVE_DATA, ICW3_CASCADE);
61 super::io::io_wait();
62
63 outb(MASTER_DATA, ICW4_8086);
65 super::io::io_wait();
66 outb(SLAVE_DATA, ICW4_8086);
67 super::io::io_wait();
68
69 outb(MASTER_DATA, mask1);
71 outb(SLAVE_DATA, mask2);
72 }
73}
74
75pub fn disable() {
77 unsafe {
78 outb(MASTER_DATA, 0xFF);
79 outb(SLAVE_DATA, 0xFF);
80 }
81}
82
83pub fn disable_permanently() {
88 unsafe {
89 outb(MASTER_DATA, 0xFF);
90 outb(SLAVE_DATA, 0xFF);
91 }
92 log::info!("Legacy 8259 PIC disabled permanently");
93}
94
95pub fn enable_irq(mut irq: u8) {
97 let port = if irq < 8 {
98 MASTER_DATA
99 } else {
100 irq -= 8;
101 SLAVE_DATA
102 };
103 unsafe {
104 let value = inb(port) & !(1 << irq);
105 outb(port, value);
106 }
107}
108
109pub fn disable_irq(mut irq: u8) {
111 let port = if irq < 8 {
112 MASTER_DATA
113 } else {
114 irq -= 8;
115 SLAVE_DATA
116 };
117 unsafe {
118 let value = inb(port) | (1 << irq);
119 outb(port, value);
120 }
121}
122
123pub fn end_of_interrupt(irq: u8) {
125 unsafe {
126 if irq >= 8 {
127 outb(SLAVE_COMMAND, COMMAND_EOI);
128 }
129 outb(MASTER_COMMAND, COMMAND_EOI);
130 }
131}