int acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result, int intr_enabled) { if (sleep_result == -1) return (sleep_result); if (!intr_enabled) { /* Wakeup MD procedures in interrupt disabled context */ if (sleep_result == 1) { pmap_init_pat(); initializecpu(); PCPU_SET(switchtime, 0); PCPU_SET(switchticks, ticks); #ifdef DEV_APIC lapic_xapic_mode(); #endif #ifdef SMP if (!CPU_EMPTY(&suspcpus)) acpi_wakeup_cpus(sc); #endif } #ifdef SMP if (!CPU_EMPTY(&suspcpus)) restart_cpus(suspcpus); #endif mca_resume(); #ifdef __amd64__ if (vmm_resume_p != NULL) vmm_resume_p(); #endif intr_resume(/*suspend_cancelled*/false); AcpiSetFirmwareWakingVector(0, 0); } else { /* Wakeup MD procedures in interrupt enabled context */ if (sleep_result == 1 && mem_range_softc.mr_op != NULL && mem_range_softc.mr_op->reinit != NULL) mem_range_softc.mr_op->reinit(&mem_range_softc); } return (sleep_result); }
void dump_reactivate_cpus(void) { #ifdef SMP globaldata_t gd; int cpu, seq; #endif dump_stop_usertds = 1; need_user_resched(); #ifdef SMP for (cpu = 0; cpu < ncpus; cpu++) { gd = globaldata_find(cpu); seq = lwkt_send_ipiq(gd, need_user_resched_remote, NULL); lwkt_wait_ipiq(gd, seq); } restart_cpus(stopped_cpus); #endif }
int acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result, int intr_enabled) { if (sleep_result == -1) return (sleep_result); if (intr_enabled == 0) { /* Wakeup MD procedures in interrupt disabled context */ if (sleep_result == 1) { pmap_init_pat(); load_cr3(susppcbs[0]->pcb_cr3); initializecpu(); PCPU_SET(switchtime, 0); PCPU_SET(switchticks, ticks); #ifdef SMP if (!CPU_EMPTY(&suspcpus)) acpi_wakeup_cpus(sc, &suspcpus); #endif } #ifdef SMP if (!CPU_EMPTY(&suspcpus)) restart_cpus(suspcpus); #endif mca_resume(); intr_resume(); } else { /* Wakeup MD procedures in interrupt enabled context */ AcpiSetFirmwareWakingVector(0); if (sleep_result == 1 && mem_range_softc.mr_op != NULL && mem_range_softc.mr_op->reinit != NULL) mem_range_softc.mr_op->reinit(&mem_range_softc); } return (sleep_result); }
/* * kdb_trap - field a TRACE or BPT trap */ int kdb_trap(int type, int code, struct x86_64_saved_state *regs) { volatile int ddb_mode = !(boothowto & RB_GDB); /* * XXX try to do nothing if the console is in graphics mode. * Handle trace traps (and hardware breakpoints...) by ignoring * them except for forgetting about them. Return 0 for other * traps to say that we haven't done anything. The trap handler * will usually panic. We should handle breakpoint traps for * our breakpoints by disarming our breakpoints and fixing up * %eip. */ if (cons_unavail && ddb_mode) { if (type == T_TRCTRAP) { regs->tf_rflags &= ~PSL_T; return (1); } return (0); } switch (type) { case T_BPTFLT: /* breakpoint */ case T_TRCTRAP: /* debug exception */ break; default: /* * XXX this is almost useless now. In most cases, * trap_fatal() has already printed a much more verbose * message. However, it is dangerous to print things in * trap_fatal() - kprintf() might be reentered and trap. * The debugger should be given control first. */ if (ddb_mode) db_printf("kernel: type %d trap, code=%x\n", type, code); if (db_nofault) { jmp_buf *no_fault = db_nofault; db_nofault = NULL; longjmp(*no_fault, 1); } } /* * This handles unexpected traps in ddb commands, including calls to * non-ddb functions. db_nofault only applies to memory accesses by * internal ddb commands. */ if (db_global_jmpbuf_valid) longjmp(db_global_jmpbuf, 1); /* * XXX We really should switch to a local stack here. */ ddb_regs = *regs; crit_enter(); db_printf("\nCPU%d stopping CPUs: 0x%016jx\n", mycpu->gd_cpuid, (uintmax_t)CPUMASK_LOWMASK(mycpu->gd_other_cpus)); /* We stop all CPUs except ourselves (obviously) */ stop_cpus(mycpu->gd_other_cpus); db_printf(" stopped\n"); setjmp(db_global_jmpbuf); db_global_jmpbuf_valid = TRUE; db_active++; vcons_set_mode(1); if (ddb_mode) { cndbctl(TRUE); db_trap(type, code); cndbctl(FALSE); } else gdb_handle_exception(&ddb_regs, type, code); db_active--; vcons_set_mode(0); db_global_jmpbuf_valid = FALSE; db_printf("\nCPU%d restarting CPUs: 0x%016jx\n", mycpu->gd_cpuid, (uintmax_t)CPUMASK_LOWMASK(stopped_cpus)); /* Restart all the CPUs we previously stopped */ if (CPUMASK_CMPMASKNEQ(stopped_cpus, mycpu->gd_other_cpus)) { db_printf("whoa, other_cpus: 0x%016jx, " "stopped_cpus: 0x%016jx\n", (uintmax_t)CPUMASK_LOWMASK(mycpu->gd_other_cpus), (uintmax_t)CPUMASK_LOWMASK(stopped_cpus)); panic("stop_cpus() failed"); } restart_cpus(stopped_cpus); db_printf(" restarted\n"); crit_exit(); regs->tf_rip = ddb_regs.tf_rip; regs->tf_rflags = ddb_regs.tf_rflags; regs->tf_rax = ddb_regs.tf_rax; regs->tf_rcx = ddb_regs.tf_rcx; regs->tf_rdx = ddb_regs.tf_rdx; regs->tf_rbx = ddb_regs.tf_rbx; regs->tf_rsp = ddb_regs.tf_rsp; regs->tf_ss = ddb_regs.tf_ss & 0xffff; regs->tf_rbp = ddb_regs.tf_rbp; regs->tf_rsi = ddb_regs.tf_rsi; regs->tf_rdi = ddb_regs.tf_rdi; regs->tf_r8 = ddb_regs.tf_r8; regs->tf_r9 = ddb_regs.tf_r9; regs->tf_r10 = ddb_regs.tf_r10; regs->tf_r11 = ddb_regs.tf_r11; regs->tf_r12 = ddb_regs.tf_r12; regs->tf_r13 = ddb_regs.tf_r13; regs->tf_r14 = ddb_regs.tf_r14; regs->tf_r15 = ddb_regs.tf_r15; /* regs->tf_es = ddb_regs.tf_es & 0xffff; */ /* regs->tf_fs = ddb_regs.tf_fs & 0xffff; */ /* regs->tf_gs = ddb_regs.tf_gs & 0xffff; */ regs->tf_cs = ddb_regs.tf_cs & 0xffff; /* regs->tf_ds = ddb_regs.tf_ds & 0xffff; */ return (1); }
/* * kdb_trap - field a TRACE or BPT trap */ int kdb_trap(int type, int code, struct i386_saved_state *regs) { volatile int ddb_mode = !(boothowto & RB_GDB); /* * XXX try to do nothing if the console is in graphics mode. * Handle trace traps (and hardware breakpoints...) by ignoring * them except for forgetting about them. Return 0 for other * traps to say that we haven't done anything. The trap handler * will usually panic. We should handle breakpoint traps for * our breakpoints by disarming our breakpoints and fixing up * %eip. */ if (cons_unavail && ddb_mode) { if (type == T_TRCTRAP) { regs->tf_eflags &= ~PSL_T; return (1); } return (0); } switch (type) { case T_BPTFLT: /* breakpoint */ case T_TRCTRAP: /* debug exception */ break; default: /* * XXX this is almost useless now. In most cases, * trap_fatal() has already printed a much more verbose * message. However, it is dangerous to print things in * trap_fatal() - kprintf() might be reentered and trap. * The debugger should be given control first. */ if (ddb_mode) db_printf("kernel: type %d trap, code=%x\n", type, code); if (db_nofault) { jmp_buf *no_fault = db_nofault; db_nofault = NULL; longjmp(*no_fault, 1); } } /* * This handles unexpected traps in ddb commands, including calls to * non-ddb functions. db_nofault only applies to memory accesses by * internal ddb commands. */ if (db_global_jmpbuf_valid) longjmp(db_global_jmpbuf, 1); /* * XXX We really should switch to a local stack here. */ ddb_regs = *regs; /* * If in kernel mode, esp and ss are not saved, so dummy them up. */ if (ISPL(regs->tf_cs) == 0) { ddb_regs.tf_esp = (int)®s->tf_esp; ddb_regs.tf_ss = rss(); } crit_enter(); #ifdef SMP db_printf("\nCPU%d stopping CPUs: 0x%08x\n", mycpu->gd_cpuid, mycpu->gd_other_cpus); /* We stop all CPUs except ourselves (obviously) */ stop_cpus(mycpu->gd_other_cpus); db_printf(" stopped\n"); #endif /* SMP */ setjmp(db_global_jmpbuf); db_global_jmpbuf_valid = TRUE; db_active++; if (ddb_mode) { cndbctl(TRUE); db_trap(type, code); cndbctl(FALSE); } else gdb_handle_exception(&ddb_regs, type, code); db_active--; db_global_jmpbuf_valid = FALSE; #ifdef SMP db_printf("\nCPU%d restarting CPUs: 0x%08x\n", mycpu->gd_cpuid, stopped_cpus); /* Restart all the CPUs we previously stopped */ if (stopped_cpus != mycpu->gd_other_cpus) { db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n", mycpu->gd_other_cpus, stopped_cpus); panic("stop_cpus() failed"); } restart_cpus(stopped_cpus); db_printf(" restarted\n"); #endif /* SMP */ crit_exit(); regs->tf_eip = ddb_regs.tf_eip; regs->tf_eflags = ddb_regs.tf_eflags; regs->tf_eax = ddb_regs.tf_eax; regs->tf_ecx = ddb_regs.tf_ecx; regs->tf_edx = ddb_regs.tf_edx; regs->tf_ebx = ddb_regs.tf_ebx; /* * If in user mode, the saved ESP and SS were valid, restore them. */ if (ISPL(regs->tf_cs)) { regs->tf_esp = ddb_regs.tf_esp; regs->tf_ss = ddb_regs.tf_ss & 0xffff; } regs->tf_ebp = ddb_regs.tf_ebp; regs->tf_esi = ddb_regs.tf_esi; regs->tf_edi = ddb_regs.tf_edi; regs->tf_es = ddb_regs.tf_es & 0xffff; regs->tf_fs = ddb_regs.tf_fs & 0xffff; regs->tf_gs = ddb_regs.tf_gs & 0xffff; regs->tf_cs = ddb_regs.tf_cs & 0xffff; regs->tf_ds = ddb_regs.tf_ds & 0xffff; return (1); }
/* Full PV mode suspension. */ static void xctrl_suspend() { int i, j, k, fpp, suspend_cancelled; unsigned long max_pfn, start_info_mfn; EVENTHANDLER_INVOKE(power_suspend); #ifdef SMP struct thread *td; cpuset_t map; u_int cpuid; /* * Bind us to CPU 0 and stop any other VCPUs. */ td = curthread; thread_lock(td); sched_bind(td, 0); thread_unlock(td); cpuid = PCPU_GET(cpuid); KASSERT(cpuid == 0, ("xen_suspend: not running on cpu 0")); map = all_cpus; CPU_CLR(cpuid, &map); CPU_NAND(&map, &stopped_cpus); if (!CPU_EMPTY(&map)) stop_cpus(map); #endif /* * Be sure to hold Giant across DEVICE_SUSPEND/RESUME since non-MPSAFE * drivers need this. */ mtx_lock(&Giant); if (DEVICE_SUSPEND(root_bus) != 0) { mtx_unlock(&Giant); printf("%s: device_suspend failed\n", __func__); #ifdef SMP if (!CPU_EMPTY(&map)) restart_cpus(map); #endif return; } mtx_unlock(&Giant); local_irq_disable(); xencons_suspend(); gnttab_suspend(); intr_suspend(); max_pfn = HYPERVISOR_shared_info->arch.max_pfn; void *shared_info = HYPERVISOR_shared_info; HYPERVISOR_shared_info = NULL; pmap_kremove((vm_offset_t) shared_info); PT_UPDATES_FLUSH(); xen_start_info->store_mfn = MFNTOPFN(xen_start_info->store_mfn); xen_start_info->console.domU.mfn = MFNTOPFN(xen_start_info->console.domU.mfn); /* * We'll stop somewhere inside this hypercall. When it returns, * we'll start resuming after the restore. */ start_info_mfn = VTOMFN(xen_start_info); pmap_suspend(); suspend_cancelled = HYPERVISOR_suspend(start_info_mfn); pmap_resume(); pmap_kenter_ma((vm_offset_t) shared_info, xen_start_info->shared_info); HYPERVISOR_shared_info = shared_info; HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = VTOMFN(xen_pfn_to_mfn_frame_list_list); fpp = PAGE_SIZE/sizeof(unsigned long); for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) { if ((j % fpp) == 0) { k++; xen_pfn_to_mfn_frame_list_list[k] = VTOMFN(xen_pfn_to_mfn_frame_list[k]); j = 0; } xen_pfn_to_mfn_frame_list[k][j] = VTOMFN(&xen_phys_machine[i]); } HYPERVISOR_shared_info->arch.max_pfn = max_pfn; gnttab_resume(); intr_resume(suspend_cancelled != 0); local_irq_enable(); xencons_resume(); #ifdef CONFIG_SMP for_each_cpu(i) vcpu_prepare(i); #endif /* * Only resume xenbus /after/ we've prepared our VCPUs; otherwise * the VCPU hotplug callback can race with our vcpu_prepare */ mtx_lock(&Giant); DEVICE_RESUME(root_bus); mtx_unlock(&Giant); #ifdef SMP thread_lock(curthread); sched_unbind(curthread); thread_unlock(curthread); if (!CPU_EMPTY(&map)) restart_cpus(map); #endif EVENTHANDLER_INVOKE(power_resume); }
/* * ddb_trap - field a kernel trap */ int kdb_trap(int vector, struct trapframe *regs) { int ddb_mode = !(boothowto & RB_GDB); register_t s; /* * Don't bother checking for usermode, since a benign entry * by the kernel (call to Debugger() or a breakpoint) has * already checked for usermode. If neither of those * conditions exist, something Bad has happened. */ if (vector != IA64_VEC_BREAK && vector != IA64_VEC_SINGLE_STEP_TRAP) { #if 0 if (ddb_mode) { db_printf("ddbprinttrap from 0x%lx\n", /* XXX */ regs->tf_regs[FRAME_PC]); ddbprinttrap(a0, a1, a2, entry); /* * Tell caller "We did NOT handle the trap." * Caller should panic, or whatever. */ return (0); } #endif if (db_nofault) { jmp_buf *no_fault = db_nofault; db_nofault = 0; longjmp(*no_fault, 1); } } /* * XXX Should switch to DDB's own stack, here. */ s = intr_disable(); #ifdef SMP #ifdef CPUSTOP_ON_DDBBREAK #if defined(VERBOSE_CPUSTOP_ON_DDBBREAK) db_printf("CPU%d stopping CPUs: 0x%08x...", PCPU_GET(cpuid), PCPU_GET(other_cpus)); #endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */ /* We stop all CPUs except ourselves (obviously) */ stop_cpus(PCPU_GET(other_cpus)); #if defined(VERBOSE_CPUSTOP_ON_DDBBREAK) db_printf(" stopped.\n"); #endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */ #endif /* CPUSTOP_ON_DDBBREAK */ #endif /* SMP */ ddb_regs = *regs; /* * XXX pretend that registers outside the current frame don't exist. */ db_eregs = db_regs + DB_MISC_REGS + 8 + 32 + (ddb_regs.tf_cr_ifs & 0x7f); __asm __volatile("flushrs"); /* so we can look at them */ db_active++; if (ddb_mode) { cndbctl(TRUE); /* DDB active, unblank video */ db_trap(vector, 0); /* Where the work happens */ cndbctl(FALSE); /* DDB inactive */ } else gdb_handle_exception(&ddb_regs, vector); db_active--; #ifdef SMP #ifdef CPUSTOP_ON_DDBBREAK #if defined(VERBOSE_CPUSTOP_ON_DDBBREAK) db_printf("CPU%d restarting CPUs: 0x%08x...", PCPU_GET(cpuid), stopped_cpus); #endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */ /* Restart all the CPUs we previously stopped */ if (stopped_cpus != PCPU_GET(other_cpus) && smp_started != 0) { db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n", PCPU_GET(other_cpus), stopped_cpus); panic("stop_cpus() failed"); } restart_cpus(stopped_cpus); #if defined(VERBOSE_CPUSTOP_ON_DDBBREAK) db_printf(" restarted.\n"); #endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */ #endif /* CPUSTOP_ON_DDBBREAK */ #endif /* SMP */ *regs = ddb_regs; intr_restore(s); /* * Tell caller "We HAVE handled the trap." */ return (1); }