#define SMP #define APIC_IO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #undef KLD_MODULE #include #define KLD_MODULE #include #include #include #include static const int apic_bus_freq = 100; /* in MHz */ void Xrsvd(u_int cs, u_int ef, u_int esp, u_int ss); void apic_timer_handler(u_int cs, u_int ef, u_int esp, u_int ss); #define lapic_eoi (*(unsigned *)(lapic_start + 0xb0)) #define lapic_lvt_timer (*(unsigned *)(lapic_start + 0x320)) #define lapic_dcr_timer (*(unsigned *)(lapic_start + 0x3e0)) #define lapic_icr_timer (*(unsigned *)(lapic_start + 0x380)) static void _timeout_init(int freq) { vm_offset_t start; /* check if lapic registers need to be mapped */ if (lapic_start == 0) { start = kmem_alloc(kernel_map, 2*PAGE_SIZE); start = (start + PAGE_SIZE) & ~(PAGE_SIZE-1); pmap_remove(vm_map_pmap(kernel_map), start, start+PAGE_SIZE-1); pmap_map(start, 0xfee00000, 0xfee00000+PAGE_SIZE-1, VM_PROT_READ | VM_PROT_WRITE); lapic_start = start; } setidt(60, apic_timer_handler, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); lapic_dcr_timer = 0xb; /* divisor is 1 */ lapic_lvt_timer = (0x20000 | 60); /* periodic */ lapic_icr_timer = apic_bus_freq * (1000000/freq); } static void _timeout_deinit(void) { lapic_lvt_timer = 0x10000; lapic_icr_timer = 0; setidt(60, Xrsvd, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); } #undef SMP #undef APIC_IO