void default_handler(u32 irq, u32 error_code, u32 eip, u32 cs, u32 eflag) { tw_printf("recv irq(%d): error_code(0x%x), eip(0x%x), cs(0x%x), eflag(0x%x)\n", irq, error_code, eip, cs, eflag); if (handlers[irq].callback != 0) { handlers[irq].callback(handlers[irq].arg); } if (irq >= 0x20) { apic_eoi(irq); } }
void apic_init() { apic_address_init(); apic_register(32, dummy_timer_handler); apic_write32(APIC_REG_SIVR, apic_read32(APIC_REG_SIVR) | 0x100); apic_write32(APIC_REG_TPR, 0); apic_write32(APIC_REG_LVT_TR, apic_read32(APIC_REG_LVT_TR) | APIC_IM_DISABLED); apic_write32(APIC_REG_LVT_TSR, apic_read32(APIC_REG_LVT_TSR) | APIC_IM_DISABLED); apic_write32(APIC_REG_LVT_PMR, apic_read32(APIC_REG_LVT_PMR) | APIC_IM_DISABLED); apic_write32(APIC_REG_LVT_LINT0R, apic_read32(APIC_REG_LVT_LINT0R) | APIC_IM_DISABLED); apic_write32(APIC_REG_LVT_LINT1R, APIC_TM_EDGE | APIC_PP_ACTIVEHIGH | APIC_DMODE_NMI); apic_write32(APIC_REG_LVT_ER, apic_read32(APIC_REG_LVT_ER) | APIC_IM_DISABLED); apic_eoi(); }
/* * All of our Exception handling Interrupt Service Routines will * point to this function. This will tell us what exception has * occured! Right now, we simply abort the current task. * All ISRs disable interrupts while they are being * serviced as a 'locking' mechanism to prevent an IRQ from * happening and messing up kernel data structures */ static void fault_handler(struct state *s) { if (s->int_no < 32) kputs(exception_messages[s->int_no]); else kprintf("Unknown exception %d", s->int_no); kprintf(" Exception (%d) on core %d at %#x:%#lx, fs = %#lx, gs = %#lx, error code = 0x%#lx, task id = %u, rflags = %#x\n", s->int_no, CORE_ID, s->cs, s->rip, s->fs, s->gs, s->error, per_core(current_task)->id, s->rflags); kprintf("rax %#lx, rbx %#lx, rcx %#lx, rdx %#lx, rbp, %#lx, rsp %#lx rdi %#lx, rsi %#lx, r8 %#lx, r9 %#lx, r10 %#lx, r11 %#lx, r12 %#lx, r13 %#lx, r14 %#lx, r15 %#lx\n", s->rax, s->rbx, s->rcx, s->rdx, s->rbp, s->rsp, s->rdi, s->rsi, s->r8, s->r9, s->r10, s->r11, s->r12, s->r13, s->r14, s->r15); apic_eoi(s->int_no); irq_enable(); //do_abort(); sys_exit(-EFAULT); }
// Dummy interrupt handler static void dummy_timer_handler(uint64_t vector, uint64_t error_code) { // Do nothing apic_eoi(); }
PUBLIC int init_local_timer(unsigned freq) { #ifdef USE_APIC /* if we know the address, lapic is enabled and we should use it */ if (lapic_addr) { unsigned cpu = cpuid; tsc_per_ms[cpu] = div64u(cpu_get_freq(cpu), 1000); lapic_set_timer_one_shot(1000000/system_hz); } else { BOOT_VERBOSE(printf("Initiating legacy i8253 timer\n")); #else { #endif init_8253A_timer(freq); estimate_cpu_freq(); /* always only 1 cpu in the system */ tsc_per_ms[0] = div64u(cpu_get_freq(0), 1000); } return 0; } PUBLIC void stop_local_timer(void) { #ifdef USE_APIC if (lapic_addr) { lapic_stop_timer(); apic_eoi(); } else #endif { stop_8253A_timer(); } } PUBLIC void restart_local_timer(void) { #ifdef USE_APIC if (lapic_addr) { lapic_restart_timer(); } #endif } PUBLIC int register_local_timer_handler(const irq_handler_t handler) { #ifdef USE_APIC if (lapic_addr) { /* Using APIC, it is configured in apic_idt_init() */ BOOT_VERBOSE(printf("Using LAPIC timer as tick source\n")); } else #endif { /* Using PIC, Initialize the CLOCK's interrupt hook. */ pic_timer_hook.proc_nr_e = NONE; pic_timer_hook.irq = CLOCK_IRQ; put_irq_handler(&pic_timer_hook, CLOCK_IRQ, handler); } return 0; } PUBLIC void cycles_accounting_init(void) { #ifdef CONFIG_SMP unsigned cpu = cpuid; #endif read_tsc_64(get_cpu_var_ptr(cpu, tsc_ctr_switch)); make_zero64(get_cpu_var(cpu, cpu_last_tsc)); make_zero64(get_cpu_var(cpu, cpu_last_idle)); }
void apic_timer_handler() { inc_sys_clock(); apic_eoi(); }