| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include <mos/types.hpp> |
| 4 | #include <mos/x86/devices/port.hpp> |
| 5 | #include <mos/x86/x86_platform.hpp> |
| 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 | |