Files
Sylva/kernel/interrupt/pic.cpp
T
2026-06-06 10:31:20 +08:00

73 lines
1.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <pic.h>
#include <common.h>
#include <string_utils.h>
#include <serial.h>
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(); // 级联标识
// ICW48086 模式
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);
}