uint64_t ioapic_rte_read(uint32_t index);
void ioapic_rte_write(uint32_t index, uint64_t v);
-
-union hpet_timn_conf_cap {
- uint64_t value;
- struct {
- // BYTE 1
- uint64_t reserved0 : 1; // bit0
- uint64_t trigger_mode : 1; // bit1
- uint64_t enable_int : 1; // bit2
- uint64_t type : 1; // bit3
- uint64_t periodic : 1; // bit4 read only
- uint64_t bit_size : 1; // bit5 read only 0 32位位宽 1 64位位宽
- uint64_t val_set : 1; // bit6 标志位只对处于周期定时模式下的定时器0起作⽤
- // 置位此标志位可使软件在定时器运⾏时直接修改定时值。
- // bit7
- uint64_t reserved1 : 1;
-
- // >>> bin(0x174C)
- // '0b1 0111 0100 1100'
- // >>> bin(0x2E7C)
- // '0b10 1110 0111 1100'
- // BYTE 2
- uint64_t counter_bit_size : 1;
- uint64_t int_route : 5;
- uint64_t fsb_en : 1;
- uint64_t fsb_delivery_status : 1; // 15 read only
-
- // BYTE 3~4
- uint64_t reserved2 : 16;
-
- // BYTE 5~8
- uint64_t int_route_cap : 32; // read only
- };
-} PACKED;
-typedef union hpet_timn_conf_cap hpet_timn_conf_cap_t;
const char* title = "KERNEL MONITOR";
printlxy(MPL_TITLE, (80 - strlen(title)) / 2, title);
- while (1) {
- asm("hlt;");
- }
+ void system_monitor();
+ system_monitor();
}
bool ap_ready() {
uint8_t* p = (uint8_t*)0xC00B8002;
*p = *p == ' ' ? 'E' : ' ';
+ ap_lapic_ticks++;
+
+ system.lapic->write(LAPIC_EOI, 0);
+}
+
+void _system_monitor() {
//
extern volatile uint64_t jiffies;
extern volatile uint64_t hpet_ticks; // jiffies 和 hpet_ticks 是同一个东西
//
// void print_all_ides();
// print_all_ides();
-
- ap_lapic_ticks++;
-
- system.lapic->write(LAPIC_EOI, 0);
+}
+void system_monitor() {
+ while (1) {
+ asm("hlt");
+ uint64_t ap_monitor_begin = ap_lapic_ticks;
+ _system_monitor();
+ uint64_t ap_monitor_end = ap_lapic_ticks;
+ if (ap_monitor_end != ap_monitor_begin) {
+ // panic("AP monitor cost too long\n");
+ }
+ }
}
#include <task.h>
extern irq_chip_t ioapic_chip;
#if 1
+ ioapic_rte_t rte;
- // 8253/8254连在i8259的0号引脚,但连在IO APIC的2号引脚上
- // 把8253/8254的中断通过IOAPIC转发到CPU0的0号中断
- // ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (dst_cpuid << 56));
+ // 8253/8254连在8259的0号引脚,但8259连在IO APIC的2号引脚上
// 把8253/8254的中断通过IOAPIC转发到CPU1的0号中断
- ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (1ULL << 56));
- ioapic_rte_write(IOAPIC_RTE(2), 0x20 + 0 | (1ULL << 56) | 0x10000);
+ rte.value = 0;
+ rte.vector = 0x20 + 0;
+ rte.delivery_mode = IOAPIC_DELIVERY_MODE_FIXED;
+ rte.destination_mode = IOAPIC_PHYSICAL_DESTINATION;
+ rte.trigger_mode = IOAPIC_TRIGGER_MODE_EDGE;
+ rte.mask = IOAPIC_INT_MASKED; // 暂时先屏蔽
+ rte.destination = 1;
+ ioapic_rte_write(IOAPIC_RTE(2), rte.value);
+
// 把键盘中断通过IOAPIC转发到CPU0的1号中断
- ioapic_rte_write(IOAPIC_RTE(1), 0x20 + 1 | (dst_cpuid << 56));
- // irq_set_chip(0x00, &ioapic_chip); // ap不需要这个
+ rte.value = 0;
+ rte.vector = 0x20 + 1;
+ rte.delivery_mode = IOAPIC_DELIVERY_MODE_FIXED;
+ rte.destination_mode = IOAPIC_PHYSICAL_DESTINATION;
+ rte.trigger_mode = IOAPIC_TRIGGER_MODE_EDGE;
+ rte.mask = IOAPIC_INT_UNMASKED;
+ rte.destination = 0;
+ ioapic_rte_write(IOAPIC_RTE(1), rte.value);
irq_set_chip(0x01, &ioapic_chip);
#endif
}