static void host_signal_handler(int host_signum, siginfo_t *info, void *puc) { int sig; target_siginfo_t tinfo; /* the CPU emulator uses some host signals to detect exceptions, we we forward to it some signals */ if (host_signum == SIGSEGV || host_signum == SIGBUS) { if (cpu_signal_handler(host_signum, (void*)info, puc)) return; } /* get target signal number */ sig = host_to_target_signal(host_signum); if (sig < 1 || sig > NSIG) return; #if defined(DEBUG_SIGNAL) fprintf(stderr, "qemu: got signal %d\n", sig); #endif if (queue_signal(sig, &tinfo) == 1) { /* interrupt the virtual CPU as soon as possible */ cpu_exit(global_env); } }
void kprintf(const char *fmt, ...) { va_list listp; boolean_t state; if (!disable_serial_output) { boolean_t early = FALSE; if (rdmsr64(MSR_IA32_GS_BASE) == 0) { early = TRUE; } /* If PE_kputc has not yet been initialized, don't * take any locks, just dump to serial */ if (!PE_kputc || early) { va_start(listp, fmt); _doprnt(fmt, &listp, pal_serial_putc, 16); va_end(listp); return; } /* * Spin to get kprintf lock but poll for incoming signals * while interrupts are masked. */ state = ml_set_interrupts_enabled(FALSE); pal_preemption_assert(); while (!simple_lock_try(&kprintf_lock)) { (void) cpu_signal_handler(NULL); } if (cpu_number() != cpu_last_locked) { MP_DEBUG_KPRINTF("[cpu%d...]\n", cpu_number()); cpu_last_locked = cpu_number(); } va_start(listp, fmt); _doprnt(fmt, &listp, PE_kputc, 16); va_end(listp); simple_unlock(&kprintf_lock); ml_set_interrupts_enabled(state); } }
struct savearea * interrupt( int type, struct savearea *ssp, unsigned int dsisr, unsigned int dar) { int current_cpu; struct per_proc_info *proc_info; uint64_t now; thread_t thread; disable_preemption(); perfCallback fn = perfIntHook; if(fn) { /* Is there a hook? */ if(fn(type, ssp, dsisr, dar) == KERN_SUCCESS) return ssp; /* If it succeeds, we are done... */ } #if CONFIG_DTRACE if(tempDTraceIntHook) { /* Is there a hook? */ if(tempDTraceIntHook(type, ssp, dsisr, dar) == KERN_SUCCESS) return ssp; /* If it succeeds, we are done... */ } #endif #if 0 { extern void fctx_text(void); fctx_test(); } #endif current_cpu = cpu_number(); proc_info = getPerProc(); switch (type) { case T_DECREMENTER: KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 0) | DBG_FUNC_NONE, isync_mfdec(), (unsigned int)ssp->save_srr0, 0, 0, 0); now = mach_absolute_time(); /* Find out what time it is */ if(now >= proc_info->pms.pmsPop) { /* Is it time for power management state change? */ pmsStep(1); /* Yes, advance step */ now = mach_absolute_time(); /* Get the time again since we ran a bit */ } thread = current_thread(); /* Find ourselves */ if(thread->machine.qactTimer != 0) { /* Is the timer set? */ if (thread->machine.qactTimer <= now) { /* It is set, has it popped? */ thread->machine.qactTimer = 0; /* Clear single shot timer */ if((unsigned int)thread->machine.vmmControl & 0xFFFFFFFE) { /* Are there any virtual machines? */ vmm_timer_pop(thread); /* Yes, check out them out... */ } } } etimer_intr(USER_MODE(ssp->save_srr1), ssp->save_srr0); /* Handle event timer */ break; case T_INTERRUPT: /* Call the platform interrupt routine */ counter(c_incoming_interrupts++); KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_INTR, 0) | DBG_FUNC_START, current_cpu, (unsigned int)ssp->save_srr0, 0, 0, 0); #if CONFIG_DTRACE && (DEVELOPMENT || DEBUG ) DTRACE_INT5(interrupt__start, void *, proc_info->interrupt_nub, int, proc_info->interrupt_source, void *, proc_info->interrupt_target, IOInterruptHandler, proc_info->interrupt_handler, void *, proc_info->interrupt_refCon); #endif proc_info->interrupt_handler( proc_info->interrupt_target, proc_info->interrupt_refCon, proc_info->interrupt_nub, proc_info->interrupt_source); #if CONFIG_DTRACE && (DEVELOPMENT || DEBUG ) DTRACE_INT5(interrupt__complete, void *, proc_info->interrupt_nub, int, proc_info->interrupt_source, void *, proc_info->interrupt_target, IOInterruptHandler, proc_info->interrupt_handler, void *, proc_info->interrupt_refCon); #endif KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_INTR, 0) | DBG_FUNC_END, 0, 0, 0, 0, 0); break; case T_SIGP: /* Did the other processor signal us? */ cpu_signal_handler(); break; case T_SHUTDOWN: cpu_doshutdown(); panic("returning from cpu_doshutdown()\n"); break; default: if (!Call_Debugger(type, ssp)) unresolved_kernel_trap(type, ssp, dsisr, dar, NULL); break; } enable_preemption(); return ssp; }