Microkernel thing OS experiment (Zig ⚡)
1/// Remap the 8259 PIC to an interrupt base of 0x32 2const arch = @import("../root.zig"); 3const out = arch.port.out; 4const in = arch.port.in; 5 6const PIC_ONE_CMD_PORT = 0x20; 7const PIC_ONE_DATA_PORT = 0x21; 8const PIC_ONE_IDT_BASE = 32; 9 10const PIC_TWO_CMD_PORT = 0xA0; 11const PIC_TWO_DATA_PORT = 0xA1; 12const PIC_TWO_IDT_BASE = 40; 13 14const CMD_INIT = 0x11; 15const CMD_EOI = 0x20; 16 17// Remap the sixteen 8259 interrupts out of the way to 18// base interrupt number 32, and mask all interrupts 19// except the 8254 PIT 20pub fn init() void { 21 // Init the 8259's 22 out(u8, PIC_ONE_CMD_PORT, CMD_INIT); 23 wait(); 24 out(u8, PIC_TWO_CMD_PORT, CMD_INIT); 25 wait(); 26 27 // Write the interrupt base numbers for both 28 out(u8, PIC_ONE_DATA_PORT, PIC_ONE_IDT_BASE); 29 wait(); 30 out(u8, PIC_TWO_DATA_PORT, PIC_TWO_IDT_BASE); 31 wait(); 32 33 // Tell first 8259 that there's a second 8259 at IRQ 2, and tell 34 // the second 8259 that it is at that position. 35 out(u8, PIC_ONE_DATA_PORT, 1 << 2); 36 wait(); 37 out(u8, PIC_TWO_DATA_PORT, 2); 38 wait(); 39 40 // Tell the PICs to use 8086 mode 41 out(u8, PIC_ONE_DATA_PORT, 1); 42 wait(); 43 out(u8, PIC_ONE_DATA_PORT, 1); 44 wait(); 45 46 // Unmask only the 8254 47 out(u8, PIC_ONE_DATA_PORT, 0b1111_1111); 48 wait(); 49 out(u8, PIC_TWO_DATA_PORT, 0b1111_1111); 50 wait(); 51} 52 53inline fn wait() void { 54 out(u8, 0x80, 0); 55} 56 57// Notify the first 8259 that we're done with the timer interrupt 58pub fn end_of_timer_interrupt() void { 59 out(u8, PIC_ONE_CMD_PORT, CMD_EOI); 60}