mach_cpu_states.c revision a3f75865e789d90ccd8aaa11f12d71a83bf5812e
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * CDDL HEADER START
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * The contents of this file are subject to the terms of the
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Common Development and Distribution License (the "License").
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * You may not use this file except in compliance with the License.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * See the License for the specific language governing permissions
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * and limitations under the License.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * When distributing Covered Code, include this CDDL HEADER in each
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * If applicable, add the following below this CDDL HEADER, with the
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * fields enclosed by brackets "[]" replaced with your own identifying
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * information: Portions Copyright [yyyy] [name of copyright owner]
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * CDDL HEADER END
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Use is subject to license terms.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers#pragma ident "%Z%%M% %I% %E% SMI"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * hvdump_buf_va is a pointer to the currently-configured hvdump_buf.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * A value of NULL indicates that this area is not configured.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * hvdump_buf_sz is tunable but will be clamped to HVDUMP_SIZE_MAX.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersstatic void reboot_machine(char *);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersstatic void update_hvdump_buffer(void);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * For xt_sync synchronization.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * We keep our own copies, used for cache flushing, because we can be called
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * before cpu_fiximpl().
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Assembly support for generic modules in sun4v/ml/mach_xc.s
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersextern void init_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersextern void kdi_flush_idcache(int, int, int, int);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Machine dependent code to reboot.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * "mdep" is interpreted as a character pointer; if non-null, it is a pointer
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * to a string to be used as the argument string when rebooting.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * "invoke_cb" is a boolean. It is set to true when mdboot() can safely
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * invoke CB_CL_MDBOOT callbacks before shutting the system down, i.e. when
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * we are in a normal shutdown sequence (interrupts are not blocked, the
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * system is not panic'ing or being suspended).
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*ARGSUSED*/
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowersmdboot(int cmd, int fcn, char *bootstr, boolean_t invoke_cb)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers extern void pm_cfb_check_and_powerup(void);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * XXX - rconsvp is set to NULL to ensure that output messages
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * are sent to the underlying "hardware" device using the
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * monitor's printf routine since we are in the process of
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * either rebooting or halting the machine.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * At a high interrupt level we can't:
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * 1) bring up the console
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * 2) wait for pending interrupts prior to redistribution
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * to the current CPU
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * so we do them now.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* make sure there are no more changes to the device tree */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Clear any unresolved UEs from memory.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * stop other cpus which also raise our priority. since there is only
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * one active cpu after this, and our priority will be too high
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * for us to be preempted, we're essentially single threaded
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * from here on out.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * try and reset leaf devices. reset_leaves() should only
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * be called when there are no other threads that could be
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * accessing devices
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* MAYBE REACHED */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/* mdpreboot - may be called prior to mdboot while root fs still mounted */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*ARGSUSED*/
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Halt the machine and then reboot with the device
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * and arguments specified in bootstr.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers stop_other_cpus(); /* send stop signal to other CPUs */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * For platforms that use CPU signatures, we
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * need to set the signature block to OS and
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * the state to exiting for all the processors.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_REBOOT, -1);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /*NOTREACHED*/
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * We use the x-trap mechanism and idle_stop_xcall() to stop the other CPUs.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Once in panic_idle() they raise spl, record their location, and spin.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Force the other CPUs to trap into panic_idle(), and then remove them
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * from the cpu_ready_set so they will no longer receive cross-calls.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*ARGSUSED*/
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers xt_some(cps, (xcfunc_t *)idle_stop_xcall, (uint64_t)&panic_idle, NULL);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers for (i = 0; i < NCPU; i++) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Platform callback following each entry to panicsys(). If we've panicked at
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * level 14, we examine t_panic_trap to see if a fatal trap occurred. If so,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * we disable further %tick_cmpr interrupts. If not, an explicit call to panic
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * was made and so we re-enqueue an interrupt request structure to allow
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * further level 14 interrupts to be processed once we lower PIL. This allows
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * us to handle panics from the deadman() CY_HIGH_LEVEL cyclic.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* there are no possible error codes for this hcall */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) hv_ttrace_freeze((uint64_t)TRAP_TFREEZE_ALL,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Clear SOFTINT<14>, SOFTINT<0> (TICK_INT)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * and SOFTINT<16> (STICK_INT) to indicate
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * that the current level 14 has been serviced.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Miscellaneous hardware-specific code to execute after panicstr is set
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * by the panic code: we also print and record PTL1 panic information here.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*ARGSUSED*/
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Turn off TRAPTRACE and save the current %tick value in panic_tick.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /* there are no possible error codes for this hcall */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (void) hv_ttrace_freeze((uint64_t)TRAP_TFREEZE_ALL,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * For Platforms that use CPU signatures, we
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * need to set the signature block to OS, the state to
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * exiting, and the substate to panic for all the processors.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_PANIC, -1);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Disable further ECC errors from the bus nexus.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Redirect all interrupts to the current CPU.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * This call exists solely to support dumps to network
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * devices after sync from OBP.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * If we came here via the sync callback, then on some
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * platforms, interrupts may have arrived while we were
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * stopped in OBP. OBP will arrange for those interrupts to
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * be redelivered if you say "go", but not if you invoke a
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * client callback like 'sync'. For some dump devices
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * (network swap devices), we need interrupts to be
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * delivered in order to dump, so we have to call the bus
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * nexus driver to reset the interrupt state machines.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Platforms that use CPU signatures need to set the signature block to OS and
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * the state to exiting for all CPUs. PANIC_CONT indicates that we're about to
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * write the crash dump, which tells the SSP/SMS to begin a timeout routine to
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * reboot the machine if the dump never completes.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers/*ARGSUSED*/
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_DUMP, -1);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * for ptl1_panic
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers /*CONSTCOND*/
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (sizeof (struct cpu) + PTL1_SSIZE > CPU_ALLOC_SIZE) {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers panic("ptl1_init_cpu: not enough space left for ptl1_panic "
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "stack, sizeof (struct cpu) = %lu",
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers (unsigned long)sizeof (struct cpu));
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers pstate->ptl1_stktop = (uintptr_t)cpu + CPU_ALLOC_SIZE;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers static const char *ptl1_reasons[] = {
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "kernel protection fault", /* PTL1_BAD_KPROT_FAULT */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "attempt to steal locked ctx", /* PTL1_BAD_CTX_STEAL */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "unexpected error from hypervisor call", /* PTL1_BAD_HCALL */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "return value EINVAL from hcall: "\
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "UNMAP_PERM_ADDR", /* PTL1_BAD_HCALL_UNMAP_PERM_EINVAL */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "return value ENOMAP from hcall: "\
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "UNMAP_PERM_ADDR", /* PTL1_BAD_HCALL_UNMAP_PERM_ENOMAP */
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uint_t reason = pstate->ptl1_regs.ptl1_gregs[0].ptl1_g1;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers uint_t tl = pstate->ptl1_regs.ptl1_trap_regs[0].ptl1_tl;
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Use trap_info for a place holder to call panic_savetrap() and
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * panic_showtrap() to save and print out ptl1_panic information.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (reason < sizeof (ptl1_reasons) / sizeof (ptl1_reasons[0]))
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers panic("bad %s at TL %u", ptl1_reasons[reason], tl);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers panic("ptl1_panic reason 0x%x at TL %u", reason, tl);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers prom_printf("Debugging requested; hardware watchdog suspended.\n");
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Restore the watchdog timer when returning from a debugger
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * after a panic or L1-A and resume watchdog pat.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers return (0);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers hvdump_buf_va = contig_mem_alloc_align(hvdump_buf_sz, PAGESIZE);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ret = hv_dump_buf_update(hvdump_buf_pa, hvdump_buf_sz,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "dump buffer. Error = 0x%lx, size = 0x%lx,"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "Available buffer size = 0x%lx,"
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "Minimum buffer size required = 0x%lx",
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers ret = hv_dump_buf_update(hvdump_buf_pa, hvdump_buf_sz,
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers case sizeof (int):
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * Called by setcpudelay
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers listp = (mde_cookie_t *)prom_alloc((caddr_t)0, listsz, 0);
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers num_nodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, "platform"),
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (md_get_prop_val(mdp, *listp, "stick-frequency", &stick_prop) != 0)
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "cpuid: 0x%x has been marked in "
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "unexpected hypervisor error 0x%x "
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "while sending a mondo to cpuid: "
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * If there is a big jump between the current tick
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * count and lasttick, we have probably hit a break
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers * point. Adjust endtick accordingly to avoid panic.
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers "(target 0x%x) [retries: 0x%x hvstat: 0x%x]",
f9fbec18f5b458b560ecf45d3db8e8bd56bf6942mcpowers if (n < 8192)
int ncpuids = 0;
int shipped = 0;
int retries = 0;
int stat;
for (i = 0, j = 0; i < ncpuids; i++) {
shipped++;
ncpuids = j;
int errorcpus;
if (!panic_quiesce)
if (!panic_quiesce)
errorcpus++;
} else if (errorcpus > 0) {
if (!panic_quiesce) {
if (errorcpus == 0) {
if (panic_quiesce)
for (i = 0; i < ncpuids; i++) {
if (panic_quiesce)
for (i = 0; i < ncpuids; i++)
retries++;
} while (ncpuids > 0);
#ifdef SEND_MONDO_STATS
syncfpu(void)
cpu_flush_ecache(void)
sticksync_slave(void)
sticksync_master(void)
cpu_init_cache_scrub(void)
if (watched)
return (ret);
int rc, i;
return (rc);
int stat;
if (stat == 0)
return (KDI_XC_RES_OK);
return (KDI_XC_RES_NACK);
int icache_linesize)
/* used directly by kdi_read/write_phys */
kdi_flush_caches(void)
sun4v_system_claim(void)
sun4v_system_release(void)
return (ENOTSUP);
return (UNUM_NAMLEN);
return (ENOTSUP);
return (ENOTSUP);
return (ENOTSUP);
} cpu_sync;
goto out;
if (panic_quiesce)
goto out;
out:
recalc_xc_timeouts(void)
} half;
} u_number;
/* See x_call.c for descriptions of these extern variables. */
int nrnode;
goto done;
goto done;
* clock.h defines an assembly-language macro
* please read the discussion of the macro in clock.h.
if (scale == 0)
done:
if (nrnode > 0)