#define IRQ_CASCADE 0x02
#define IRQ_DISK 0x0E
+void irq_set_chip(unsigned int irq, irq_chip_t* chip);
+
#endif //_IRQ_H
#include <pci.h>
#include <ioremap.h>
#include <io.h>
-#include <i8259.h>
+#include <irq.h>
static inline uint32_t apic_offset_to_msr(uint32_t offset) {
return 0x800 + (offset >> 4);
// 打开键盘中断
ioapic_rte_write(IOAPIC_RTE(1), 0x21);
+ extern irq_chip_t ioapic_chip;
+ irq_set_chip(0x01, &ioapic_chip);
}
void disable_i8259();
// IOAPIC重定向到LAPIC
// 8259A被禁用或掩码
-// irq_chip_t apic_chip = {
-// .name = "APIC",
-// .enable = enable_apic_irq,
-// .disable = disable_apic_irq,
-// .ack = ack_apic_irq,
-// };
+int enable_ioapic_irq(unsigned int irq) {
+ uint64_t rte = ioapic_rte_read(irq);
+ rte &= ~IOAPIC_RTE_MASK;
+ ioapic_rte_write(irq, rte);
+ return 0;
+}
+
+int disable_ioapic_irq(unsigned int irq) {
+ uint64_t rte = ioapic_rte_read(irq);
+ rte |= IOAPIC_RTE_MASK;
+ ioapic_rte_write(irq, rte);
+ return 0;
+}
+
+void ack_ioapic_irq(unsigned int irq) {
+ system.lapic->write(LAPIC_EOI, 0);
+}
+
+irq_chip_t ioapic_chip = {
+ .name = "IO-APIC",
+ .enable = enable_ioapic_irq,
+ .disable = disable_ioapic_irq,
+ .ack = ack_ioapic_irq,
+};
panic("invalid irq %d\n", irq);
}
+#if 0
assert(1 == irq);
uint8_t b = inb(0x60);
printk("irq %d b %02x\n", irq, b);
// vaddr_t apic_virt_base_addr = fixid_to_vaddr(FIX_LAPIC_BASE);
// apic_virt_base_addr += 0xB0;
// *((volatile uint32_t*)apic_virt_base_addr) = 0x0;
-
-#if 1
+#endif
+#if 0
// 检查IMCR
outb(0x22, 0x70);
uint8_t imcr = inb(0x23);
assert(reenter <= 1);
// TODO 判断打断的是否是内核态代码
-
- // 屏蔽当前中断
- // p->chip->disable(irq);
-
#if 0
if (0x00 == irq) {
if ((clk_irq_cnt++ & 0xFU) != 0) {
action = action->next;
}
- // 解除屏蔽当前中断
- // p->chip->enable(irq);
-
// 代表当前中断程序打断了前一个中断程序的“开中断处理的底半部分逻辑”
// 即前一个中断处理尚未完全完成
assert(irq_disabled());
- // 发送EOI
p->chip->ack(irq);
if (reenter != 0) {
void exit_critical_zone() {
irq_restore(__critical_zone_eflags);
}
+
+void irq_set_chip(unsigned int irq, irq_chip_t* chip) {
+ assert(irq < NR_IRQS);
+ assert(chip != NULL);
+ irq_desc[irq].chip = chip;
+}
init_mm();
init_buffer();
-#if 1
- void init_acpi();
- init_acpi();
-#endif
-#if 1
- void init_apic();
- init_apic();
-#endif
void init_mount();
init_mount();
setup_i8254(100);
setup_irqs();
+#if 1
+ void init_acpi();
+ init_acpi();
+#endif
+#if 1
+ void init_apic();
+ init_apic();
+#endif
+
#if !DISABLE_IDE
void ide_init();
ide_init();
irq_desc[i] = no_irq_desc;
if (i < 16) {
- irq_desc[i].chip = &i8259_chip;
+ irq_set_chip(i, &i8259_chip);
}
}
-m 3100\
-smp 2 \
-cpu qemu32,+x2apic \
+ -machine q35 \
-serial tcp::6666,server,nowait \
-drive file=hd.img,format=raw,index=0,media=disk \
-drive file=kernel.iso,index=1,media=cdrom \