#include #include #include #include static inline void outb(UINT16 port, UINT8 val) { ASM("outb %0, %1" : : "a"(val), "Nd"(port)); } static inline UINT8 inb(UINT16 port) { UINT8 ret; ASM("inb %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } // 慢速 PIC 的小延迟 static void pic_wait(void) { ASM("jmp 1f\n\t1: jmp 1f\n\t1:"); } void pic_init(void) { serial_write("PIC: remapping 8259 PIC\n"); // 保存掩码 UINT8 mask1 = inb(PIC1_DATA); UINT8 mask2 = inb(PIC2_DATA); // ICW1:开始初始化,需要 ICW4 outb(PIC1_CMD, 0x11); pic_wait(); outb(PIC2_CMD, 0x11); pic_wait(); // ICW2:向量偏移 outb(PIC1_DATA, PIC_IRQ_BASE); // IRQ 0-7 → 向量 0x20-0x27 pic_wait(); outb(PIC2_DATA, PIC_IRQ_BASE + 8); // IRQ 8-15 → 向量 0x28-0x2F pic_wait(); // ICW3:级联 outb(PIC1_DATA, 0x04); pic_wait(); // 从片在 IRQ 2 outb(PIC2_DATA, 0x02); pic_wait(); // 级联标识 // ICW4:8086 模式 outb(PIC1_DATA, 0x01); pic_wait(); outb(PIC2_DATA, 0x01); pic_wait(); // 恢复掩码 outb(PIC1_DATA, mask1); outb(PIC2_DATA, mask2); serial_write("PIC: remapped IRQ 0-7 → 0x20-0x27\n"); } void pic_send_eoi(UINT8 irq) { if (irq >= 8) { outb(PIC2_CMD, PIC_EOI); } outb(PIC1_CMD, PIC_EOI); } void pic_mask_irq(UINT8 irq) { UINT16 port = (irq < 8) ? PIC1_DATA : PIC2_DATA; UINT8 shift = irq % 8; UINT8 mask = inb(port) | (1 << shift); outb(port, mask); } void pic_unmask_irq(UINT8 irq) { UINT16 port = (irq < 8) ? PIC1_DATA : PIC2_DATA; UINT8 shift = irq % 8; UINT8 mask = inb(port) & ~(1 << shift); outb(port, mask); }