1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #include <mos/types.h> |
4 | #include <mos/x86/devices/port.h> |
5 | #include <mos/x86/x86_platform.h> |
6 | |
7 | // Reinitialize the PIC controllers. |
8 | // Giving them specified vector offsets rather than 8h and 70h, as configured by default |
9 | // ICW: Initialization command words |
10 | #define ICW1_ICW4 0x01 /* ICW4 (not) needed */ |
11 | #define ICW1_INIT 0x10 /* Initialization - required! */ |
12 | #define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ |
13 | |
14 | #define PIC1 0x20 // IO base address for master PIC |
15 | #define PIC2 0xA0 // IO base address for slave PIC |
16 | #define PIC1_COMMAND (PIC1) |
17 | #define PIC1_DATA (PIC1 + 1) |
18 | #define PIC2_COMMAND (PIC2) |
19 | #define PIC2_DATA (PIC2 + 1) |
20 | |
21 | #define PIC1_OFFSET 0x20 |
22 | #define PIC2_OFFSET 0x28 |
23 | |
24 | // We now have APIC, so PIC is not used anymore, but the above initialization code is still used |
25 | void pic_remap_irq(void) |
26 | { |
27 | port_outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode) |
28 | port_outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); |
29 | |
30 | port_outb(PIC1_DATA, PIC1_OFFSET); // ICW2: Master PIC vector offset |
31 | port_outb(PIC2_DATA, PIC2_OFFSET); // ICW2: Slave PIC vector offset |
32 | |
33 | port_outb(PIC1_DATA, value: 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100) |
34 | port_outb(PIC2_DATA, value: 2); // ICW3: tell Slave PIC its cascade identity (0000 0010) |
35 | |
36 | port_outb(PIC1_DATA, ICW4_8086); |
37 | port_outb(PIC2_DATA, ICW4_8086); |
38 | |
39 | port_outb(PIC2_DATA, value: 0xFF); // mask all interrupts on slave PIC |
40 | port_outb(PIC1_DATA, value: 0xFF); // mask all interrupts on master PIC |
41 | } |
42 | |