int inthand_add(const char *name, u_int irq, void (*handler)(void *), void *arg, int flags, void **cookiep) { struct intr_handler *ih; struct ithd *ithd, *orphan; int error = 0; int created_ithd = 0; /* * Work around a race where more than one CPU may be registering * handlers on the same IRQ at the same time. */ ih = &intr_handlers[irq]; mtx_lock_spin(&intr_table_lock); ithd = ih->ih_ithd; mtx_unlock_spin(&intr_table_lock); if (ithd == NULL) { error = ithread_create(&ithd, irq, 0, irq_disable, irq_enable, "irq%d:", irq); if (error) return (error); mtx_lock_spin(&intr_table_lock); if (ih->ih_ithd == NULL) { ih->ih_ithd = ithd; created_ithd++; mtx_unlock_spin(&intr_table_lock); } else { orphan = ithd; ithd = ih->ih_ithd; mtx_unlock_spin(&intr_table_lock); ithread_destroy(orphan); } } error = ithread_add_handler(ithd, name, handler, arg, ithread_priority(flags), flags, cookiep); if ((flags & INTR_FAST) == 0 || error) { intr_setup(irq, sched_ithd, ih); error = 0; } if (error) return (error); if (flags & INTR_FAST) intr_setup(irq, handler, arg); intr_stray_count[irq] = 0; return (0); }
/* * Fire up any non-boot processors. */ void cpu_mp_start(void) { u_int cpu_impl, isjbus; mtx_init(&ipi_mtx, "ipi", NULL, MTX_SPIN); isjbus = 0; cpu_impl = PCPU_GET(impl); if (cpu_impl == CPU_IMPL_ULTRASPARCIIIi || cpu_impl == CPU_IMPL_ULTRASPARCIIIip) { isjbus = 1; cpu_ipi_selected = jalapeno_ipi_selected; cpu_ipi_single = jalapeno_ipi_single; } else if (cpu_impl == CPU_IMPL_SPARC64V || cpu_impl >= CPU_IMPL_ULTRASPARCIII) { cpu_ipi_selected = cheetah_ipi_selected; cpu_ipi_single = cheetah_ipi_single; } else { cpu_ipi_selected = spitfire_ipi_selected; cpu_ipi_single = spitfire_ipi_single; } intr_setup(PIL_AST, cpu_ipi_ast, -1, NULL, NULL); intr_setup(PIL_RENDEZVOUS, (ih_func_t *)smp_rendezvous_action, -1, NULL, NULL); intr_setup(PIL_STOP, cpu_ipi_stop, -1, NULL, NULL); intr_setup(PIL_PREEMPT, cpu_ipi_preempt, -1, NULL, NULL); intr_setup(PIL_HARDCLOCK, cpu_ipi_hardclock, -1, NULL, NULL); cpuid_to_mid[curcpu] = PCPU_GET(mid); foreach_ap(OF_child(OF_peer(0)), ap_start); KASSERT(!isjbus || mp_ncpus <= IDR_JALAPENO_MAX_BN_PAIRS, ("%s: can only IPI a maximum of %d JBus-CPUs", __func__, IDR_JALAPENO_MAX_BN_PAIRS)); }
int inthand_remove(u_int irq, void *cookie) { struct intr_handler *ih; int error; error = ithread_remove_handler(cookie); if (error == 0) { ih = &intr_handlers[irq]; mtx_lock_spin(&intr_table_lock); if (ih->ih_ithd == NULL) { intr_setup(irq, intr_stray_handler, ih); } else { intr_setup(irq, sched_ithd, ih); } mtx_unlock_spin(&intr_table_lock); } return (error); }
void intr_init() { intr_disable(); IDT_addr = (char *)(&IDT[0]); s_intr_install(0x20, &timer_intr, INTR_PRESENT|INTR_INTR_GATE); s_intr_install(0x21, &kbd_intr, INTR_PRESENT|INTR_INTR_GATE); //s_intr_install(0x0E, &page_fault, INTR_PRESENT|INTR_INTR_GATE); intr_install(0x0E, &page_fault, INTR_PRESENT|INTR_INTR_GATE, PAGE_IST, SYS_CODE_SELECTOR); //s_intr_install(0x80, &syscall_handler, INTR_PRESENT|INTR_INTR_GATE); intr_install(0x80, &syscall_handler, INTR_PRESENT|INTR_INTR_GATE|INTR_DPL3, CALL_IST, SYS_CODE_SELECTOR); intr_setup(); int i; for (i = 0; i < 15; i++) mask_irq(i); // Запретим все прерывания - мы будем использовать APIC timer unmask_irq(1); // Явно разрешим прерывание клавиатуры intr_enable(); }