10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 52036Swentaoy * Common Development and Distribution License (the "License"). 62036Swentaoy * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*10843SDave.Plauger@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <sys/types.h> 270Sstevel@tonic-gate #include <sys/t_lock.h> 280Sstevel@tonic-gate #include <sys/uadmin.h> 290Sstevel@tonic-gate #include <sys/panic.h> 300Sstevel@tonic-gate #include <sys/reboot.h> 310Sstevel@tonic-gate #include <sys/autoconf.h> 320Sstevel@tonic-gate #include <sys/machsystm.h> 330Sstevel@tonic-gate #include <sys/promif.h> 340Sstevel@tonic-gate #include <sys/membar.h> 350Sstevel@tonic-gate #include <vm/hat_sfmmu.h> 360Sstevel@tonic-gate #include <sys/cpu_module.h> 370Sstevel@tonic-gate #include <sys/cpu_sgnblk_defs.h> 380Sstevel@tonic-gate #include <sys/intreg.h> 390Sstevel@tonic-gate #include <sys/consdev.h> 400Sstevel@tonic-gate #include <sys/kdi_impl.h> 41136Sachartre #include <sys/callb.h> 42*10843SDave.Plauger@Sun.COM #include <sys/dumphdr.h> 430Sstevel@tonic-gate 440Sstevel@tonic-gate #ifdef TRAPTRACE 450Sstevel@tonic-gate #include <sys/traptrace.h> 460Sstevel@tonic-gate u_longlong_t panic_tick; 470Sstevel@tonic-gate #endif /* TRAPTRACE */ 480Sstevel@tonic-gate 490Sstevel@tonic-gate extern u_longlong_t gettick(); 500Sstevel@tonic-gate static void reboot_machine(char *); 512036Swentaoy int disable_watchdog_on_exit = 0; 520Sstevel@tonic-gate 530Sstevel@tonic-gate /* 540Sstevel@tonic-gate * Machine dependent code to reboot. 550Sstevel@tonic-gate * "mdep" is interpreted as a character pointer; if non-null, it is a pointer 560Sstevel@tonic-gate * to a string to be used as the argument string when rebooting. 57136Sachartre * 58136Sachartre * "invoke_cb" is a boolean. It is set to true when mdboot() can safely 59136Sachartre * invoke CB_CL_MDBOOT callbacks before shutting the system down, i.e. when 60136Sachartre * we are in a normal shutdown sequence (interrupts are not blocked, the 61136Sachartre * system is not panic'ing or being suspended). 620Sstevel@tonic-gate */ 630Sstevel@tonic-gate /*ARGSUSED*/ 640Sstevel@tonic-gate void 65136Sachartre mdboot(int cmd, int fcn, char *bootstr, boolean_t invoke_cb) 660Sstevel@tonic-gate { 670Sstevel@tonic-gate extern void pm_cfb_check_and_powerup(void); 680Sstevel@tonic-gate 690Sstevel@tonic-gate /* 700Sstevel@tonic-gate * Disable the hw watchdog timer. 710Sstevel@tonic-gate */ 720Sstevel@tonic-gate if (disable_watchdog_on_exit && watchdog_activated) { 730Sstevel@tonic-gate mutex_enter(&tod_lock); 740Sstevel@tonic-gate (void) tod_ops.tod_clear_watchdog_timer(); 750Sstevel@tonic-gate mutex_exit(&tod_lock); 760Sstevel@tonic-gate } 770Sstevel@tonic-gate 780Sstevel@tonic-gate /* 795630Sjbeck * XXX - rconsvp is set to NULL to ensure that output messages 805630Sjbeck * are sent to the underlying "hardware" device using the 815630Sjbeck * monitor's printf routine since we are in the process of 825630Sjbeck * either rebooting or halting the machine. 835630Sjbeck */ 845630Sjbeck rconsvp = NULL; 855630Sjbeck 865630Sjbeck /* 870Sstevel@tonic-gate * At a high interrupt level we can't: 880Sstevel@tonic-gate * 1) bring up the console 890Sstevel@tonic-gate * or 900Sstevel@tonic-gate * 2) wait for pending interrupts prior to redistribution 910Sstevel@tonic-gate * to the current CPU 920Sstevel@tonic-gate * 930Sstevel@tonic-gate * so we do them now. 940Sstevel@tonic-gate */ 950Sstevel@tonic-gate pm_cfb_check_and_powerup(); 960Sstevel@tonic-gate 970Sstevel@tonic-gate /* make sure there are no more changes to the device tree */ 980Sstevel@tonic-gate devtree_freeze(); 990Sstevel@tonic-gate 100136Sachartre if (invoke_cb) 101136Sachartre (void) callb_execute_class(CB_CL_MDBOOT, NULL); 102136Sachartre 1030Sstevel@tonic-gate /* 104917Selowe * Clear any unresolved UEs from memory. 105917Selowe */ 1063253Smec page_retire_mdboot(); 107917Selowe 108917Selowe /* 1090Sstevel@tonic-gate * stop other cpus which also raise our priority. since there is only 1100Sstevel@tonic-gate * one active cpu after this, and our priority will be too high 1110Sstevel@tonic-gate * for us to be preempted, we're essentially single threaded 1120Sstevel@tonic-gate * from here on out. 1130Sstevel@tonic-gate */ 1140Sstevel@tonic-gate stop_other_cpus(); 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate /* 1170Sstevel@tonic-gate * try and reset leaf devices. reset_leaves() should only 1180Sstevel@tonic-gate * be called when there are no other threads that could be 1190Sstevel@tonic-gate * accessing devices 1200Sstevel@tonic-gate */ 1210Sstevel@tonic-gate reset_leaves(); 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate if (fcn == AD_HALT) { 1240Sstevel@tonic-gate halt((char *)NULL); 1250Sstevel@tonic-gate } else if (fcn == AD_POWEROFF) { 1260Sstevel@tonic-gate power_down(NULL); 1270Sstevel@tonic-gate } else { 1280Sstevel@tonic-gate if (bootstr == NULL) { 1290Sstevel@tonic-gate switch (fcn) { 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate case AD_BOOT: 1320Sstevel@tonic-gate bootstr = ""; 1330Sstevel@tonic-gate break; 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate case AD_IBOOT: 1360Sstevel@tonic-gate bootstr = "-a"; 1370Sstevel@tonic-gate break; 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate case AD_SBOOT: 1400Sstevel@tonic-gate bootstr = "-s"; 1410Sstevel@tonic-gate break; 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate case AD_SIBOOT: 1440Sstevel@tonic-gate bootstr = "-sa"; 1450Sstevel@tonic-gate break; 1460Sstevel@tonic-gate default: 1470Sstevel@tonic-gate cmn_err(CE_WARN, 1480Sstevel@tonic-gate "mdboot: invalid function %d", fcn); 1490Sstevel@tonic-gate bootstr = ""; 1500Sstevel@tonic-gate break; 1510Sstevel@tonic-gate } 1520Sstevel@tonic-gate } 1530Sstevel@tonic-gate reboot_machine(bootstr); 1540Sstevel@tonic-gate } 1550Sstevel@tonic-gate /* MAYBE REACHED */ 1560Sstevel@tonic-gate } 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate /* mdpreboot - may be called prior to mdboot while root fs still mounted */ 1590Sstevel@tonic-gate /*ARGSUSED*/ 1600Sstevel@tonic-gate void 1610Sstevel@tonic-gate mdpreboot(int cmd, int fcn, char *bootstr) 1620Sstevel@tonic-gate { 1630Sstevel@tonic-gate } 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate /* 1660Sstevel@tonic-gate * Halt the machine and then reboot with the device 1670Sstevel@tonic-gate * and arguments specified in bootstr. 1680Sstevel@tonic-gate */ 1690Sstevel@tonic-gate static void 1700Sstevel@tonic-gate reboot_machine(char *bootstr) 1710Sstevel@tonic-gate { 1720Sstevel@tonic-gate flush_windows(); 1730Sstevel@tonic-gate stop_other_cpus(); /* send stop signal to other CPUs */ 1740Sstevel@tonic-gate prom_printf("rebooting...\n"); 1750Sstevel@tonic-gate /* 1760Sstevel@tonic-gate * For platforms that use CPU signatures, we 1770Sstevel@tonic-gate * need to set the signature block to OS and 1780Sstevel@tonic-gate * the state to exiting for all the processors. 1790Sstevel@tonic-gate */ 1800Sstevel@tonic-gate CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_REBOOT, -1); 1810Sstevel@tonic-gate prom_reboot(bootstr); 1820Sstevel@tonic-gate /*NOTREACHED*/ 1830Sstevel@tonic-gate } 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate /* 1860Sstevel@tonic-gate * We use the x-trap mechanism and idle_stop_xcall() to stop the other CPUs. 1870Sstevel@tonic-gate * Once in panic_idle() they raise spl, record their location, and spin. 1880Sstevel@tonic-gate */ 1890Sstevel@tonic-gate static void 1900Sstevel@tonic-gate panic_idle(void) 1910Sstevel@tonic-gate { 1920Sstevel@tonic-gate cpu_async_panic_callb(); /* check for async errors */ 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate (void) spl7(); 1950Sstevel@tonic-gate 1960Sstevel@tonic-gate debug_flush_windows(); 1970Sstevel@tonic-gate (void) setjmp(&curthread->t_pcb); 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate CPU->cpu_m.in_prom = 1; 2000Sstevel@tonic-gate membar_stld(); 2010Sstevel@tonic-gate 202*10843SDave.Plauger@Sun.COM dumpsys_helper(); 203*10843SDave.Plauger@Sun.COM 2045084Sjohnlev for (;;) 2055084Sjohnlev continue; 2060Sstevel@tonic-gate } 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate /* 2090Sstevel@tonic-gate * Force the other CPUs to trap into panic_idle(), and then remove them 2100Sstevel@tonic-gate * from the cpu_ready_set so they will no longer receive cross-calls. 2110Sstevel@tonic-gate */ 2120Sstevel@tonic-gate /*ARGSUSED*/ 2130Sstevel@tonic-gate void 2140Sstevel@tonic-gate panic_stopcpus(cpu_t *cp, kthread_t *t, int spl) 2150Sstevel@tonic-gate { 2160Sstevel@tonic-gate cpuset_t cps; 2170Sstevel@tonic-gate int i; 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate (void) splzs(); 2200Sstevel@tonic-gate CPUSET_ALL_BUT(cps, cp->cpu_id); 2210Sstevel@tonic-gate xt_some(cps, (xcfunc_t *)idle_stop_xcall, (uint64_t)&panic_idle, NULL); 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate for (i = 0; i < NCPU; i++) { 2240Sstevel@tonic-gate if (i != cp->cpu_id && CPU_XCALL_READY(i)) { 2250Sstevel@tonic-gate int ntries = 0x10000; 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate while (!cpu[i]->cpu_m.in_prom && ntries) { 2280Sstevel@tonic-gate DELAY(50); 2290Sstevel@tonic-gate ntries--; 2300Sstevel@tonic-gate } 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate if (!cpu[i]->cpu_m.in_prom) 2330Sstevel@tonic-gate printf("panic: failed to stop cpu%d\n", i); 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate cpu[i]->cpu_flags &= ~CPU_READY; 2360Sstevel@tonic-gate cpu[i]->cpu_flags |= CPU_QUIESCED; 2370Sstevel@tonic-gate CPUSET_DEL(cpu_ready_set, cpu[i]->cpu_id); 2380Sstevel@tonic-gate } 2390Sstevel@tonic-gate } 2400Sstevel@tonic-gate } 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate /* 2430Sstevel@tonic-gate * Platform callback following each entry to panicsys(). If we've panicked at 2440Sstevel@tonic-gate * level 14, we examine t_panic_trap to see if a fatal trap occurred. If so, 2450Sstevel@tonic-gate * we disable further %tick_cmpr interrupts. If not, an explicit call to panic 2460Sstevel@tonic-gate * was made and so we re-enqueue an interrupt request structure to allow 2470Sstevel@tonic-gate * further level 14 interrupts to be processed once we lower PIL. This allows 2480Sstevel@tonic-gate * us to handle panics from the deadman() CY_HIGH_LEVEL cyclic. 2490Sstevel@tonic-gate */ 2500Sstevel@tonic-gate void 2510Sstevel@tonic-gate panic_enter_hw(int spl) 2520Sstevel@tonic-gate { 2530Sstevel@tonic-gate if (spl == ipltospl(PIL_14)) { 2540Sstevel@tonic-gate uint_t opstate = disable_vec_intr(); 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate if (curthread->t_panic_trap != NULL) { 2570Sstevel@tonic-gate tickcmpr_disable(); 2580Sstevel@tonic-gate intr_dequeue_req(PIL_14, cbe_level14_inum); 2590Sstevel@tonic-gate } else { 2600Sstevel@tonic-gate if (!tickcmpr_disabled()) 2610Sstevel@tonic-gate intr_enqueue_req(PIL_14, cbe_level14_inum); 2620Sstevel@tonic-gate /* 2630Sstevel@tonic-gate * Clear SOFTINT<14>, SOFTINT<0> (TICK_INT) 2640Sstevel@tonic-gate * and SOFTINT<16> (STICK_INT) to indicate 2650Sstevel@tonic-gate * that the current level 14 has been serviced. 2660Sstevel@tonic-gate */ 2670Sstevel@tonic-gate wr_clr_softint((1 << PIL_14) | 2685084Sjohnlev TICK_INT_MASK | STICK_INT_MASK); 2690Sstevel@tonic-gate } 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate enable_vec_intr(opstate); 2720Sstevel@tonic-gate } 2730Sstevel@tonic-gate } 2740Sstevel@tonic-gate 2750Sstevel@tonic-gate /* 2760Sstevel@tonic-gate * Miscellaneous hardware-specific code to execute after panicstr is set 2770Sstevel@tonic-gate * by the panic code: we also print and record PTL1 panic information here. 2780Sstevel@tonic-gate */ 2790Sstevel@tonic-gate /*ARGSUSED*/ 2800Sstevel@tonic-gate void 2810Sstevel@tonic-gate panic_quiesce_hw(panic_data_t *pdp) 2820Sstevel@tonic-gate { 2830Sstevel@tonic-gate extern uint_t getpstate(void); 2840Sstevel@tonic-gate extern void setpstate(uint_t); 2850Sstevel@tonic-gate 2860Sstevel@tonic-gate #ifdef TRAPTRACE 2870Sstevel@tonic-gate /* 2880Sstevel@tonic-gate * Turn off TRAPTRACE and save the current %tick value in panic_tick. 2890Sstevel@tonic-gate */ 2900Sstevel@tonic-gate if (!panic_tick) 2910Sstevel@tonic-gate panic_tick = gettick(); 2920Sstevel@tonic-gate TRAPTRACE_FREEZE; 2930Sstevel@tonic-gate #endif 2940Sstevel@tonic-gate /* 2950Sstevel@tonic-gate * For Platforms that use CPU signatures, we 2960Sstevel@tonic-gate * need to set the signature block to OS, the state to 2970Sstevel@tonic-gate * exiting, and the substate to panic for all the processors. 2980Sstevel@tonic-gate */ 2990Sstevel@tonic-gate CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_PANIC, -1); 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate /* 3020Sstevel@tonic-gate * De-activate ECC functions and disable the watchdog timer now that 3030Sstevel@tonic-gate * we've made it through the critical part of the panic code. 3040Sstevel@tonic-gate */ 3050Sstevel@tonic-gate if (watchdog_enable) 3060Sstevel@tonic-gate (void) tod_ops.tod_clear_watchdog_timer(); 3070Sstevel@tonic-gate 3080Sstevel@tonic-gate /* 3090Sstevel@tonic-gate * Disable further ECC errors from the CPU module and the bus nexus. 3100Sstevel@tonic-gate */ 3110Sstevel@tonic-gate cpu_disable_errors(); 3120Sstevel@tonic-gate (void) bus_func_invoke(BF_TYPE_ERRDIS); 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate /* 3150Sstevel@tonic-gate * Redirect all interrupts to the current CPU. 3160Sstevel@tonic-gate */ 3170Sstevel@tonic-gate intr_redist_all_cpus_shutdown(); 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate /* 3200Sstevel@tonic-gate * This call exists solely to support dumps to network 3210Sstevel@tonic-gate * devices after sync from OBP. 3220Sstevel@tonic-gate * 3230Sstevel@tonic-gate * If we came here via the sync callback, then on some 3240Sstevel@tonic-gate * platforms, interrupts may have arrived while we were 3250Sstevel@tonic-gate * stopped in OBP. OBP will arrange for those interrupts to 3260Sstevel@tonic-gate * be redelivered if you say "go", but not if you invoke a 3270Sstevel@tonic-gate * client callback like 'sync'. For some dump devices 3280Sstevel@tonic-gate * (network swap devices), we need interrupts to be 3290Sstevel@tonic-gate * delivered in order to dump, so we have to call the bus 3300Sstevel@tonic-gate * nexus driver to reset the interrupt state machines. 3310Sstevel@tonic-gate */ 3320Sstevel@tonic-gate (void) bus_func_invoke(BF_TYPE_RESINTR); 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate setpstate(getpstate() | PSTATE_IE); 3350Sstevel@tonic-gate } 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate /* 3380Sstevel@tonic-gate * Platforms that use CPU signatures need to set the signature block to OS and 3390Sstevel@tonic-gate * the state to exiting for all CPUs. PANIC_CONT indicates that we're about to 3400Sstevel@tonic-gate * write the crash dump, which tells the SSP/SMS to begin a timeout routine to 3410Sstevel@tonic-gate * reboot the machine if the dump never completes. 3420Sstevel@tonic-gate */ 3430Sstevel@tonic-gate /*ARGSUSED*/ 3440Sstevel@tonic-gate void 3450Sstevel@tonic-gate panic_dump_hw(int spl) 3460Sstevel@tonic-gate { 3470Sstevel@tonic-gate CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_DUMP, -1); 3480Sstevel@tonic-gate } 3490Sstevel@tonic-gate 3500Sstevel@tonic-gate /* 3510Sstevel@tonic-gate * for ptl1_panic 3520Sstevel@tonic-gate */ 3530Sstevel@tonic-gate void 3540Sstevel@tonic-gate ptl1_init_cpu(struct cpu *cpu) 3550Sstevel@tonic-gate { 3560Sstevel@tonic-gate ptl1_state_t *pstate = &cpu->cpu_m.ptl1_state; 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate /*CONSTCOND*/ 3590Sstevel@tonic-gate if (sizeof (struct cpu) + PTL1_SSIZE > CPU_ALLOC_SIZE) { 3600Sstevel@tonic-gate panic("ptl1_init_cpu: not enough space left for ptl1_panic " 3611009Smathue "stack, sizeof (struct cpu) = %lu", sizeof (struct cpu)); 3620Sstevel@tonic-gate } 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate pstate->ptl1_stktop = (uintptr_t)cpu + CPU_ALLOC_SIZE; 3650Sstevel@tonic-gate cpu_pa[cpu->cpu_id] = va_to_pa(cpu); 3660Sstevel@tonic-gate } 3670Sstevel@tonic-gate 3680Sstevel@tonic-gate void 3690Sstevel@tonic-gate ptl1_panic_handler(ptl1_state_t *pstate) 3700Sstevel@tonic-gate { 3710Sstevel@tonic-gate static const char *ptl1_reasons[] = { 3720Sstevel@tonic-gate #ifdef PTL1_PANIC_DEBUG 3730Sstevel@tonic-gate "trap for debug purpose", /* PTL1_BAD_DEBUG */ 3740Sstevel@tonic-gate #else 3750Sstevel@tonic-gate "unknown trap", /* PTL1_BAD_DEBUG */ 3760Sstevel@tonic-gate #endif 3770Sstevel@tonic-gate "register window trap", /* PTL1_BAD_WTRAP */ 3780Sstevel@tonic-gate "kernel MMU miss", /* PTL1_BAD_KMISS */ 3790Sstevel@tonic-gate "kernel protection fault", /* PTL1_BAD_KPROT_FAULT */ 3800Sstevel@tonic-gate "ISM MMU miss", /* PTL1_BAD_ISM */ 3810Sstevel@tonic-gate "kernel MMU trap", /* PTL1_BAD_MMUTRAP */ 3820Sstevel@tonic-gate "kernel trap handler state", /* PTL1_BAD_TRAP */ 3830Sstevel@tonic-gate "floating point trap", /* PTL1_BAD_FPTRAP */ 3840Sstevel@tonic-gate #ifdef DEBUG 3852973Sgovinda "pointer to intr_vec", /* PTL1_BAD_INTR_VEC */ 3860Sstevel@tonic-gate #else 3872973Sgovinda "unknown trap", /* PTL1_BAD_INTR_VEC */ 3880Sstevel@tonic-gate #endif 3890Sstevel@tonic-gate #ifdef TRAPTRACE 3900Sstevel@tonic-gate "TRACE_PTR state", /* PTL1_BAD_TRACE_PTR */ 3910Sstevel@tonic-gate #else 3920Sstevel@tonic-gate "unknown trap", /* PTL1_BAD_TRACE_PTR */ 3930Sstevel@tonic-gate #endif 3940Sstevel@tonic-gate "stack overflow", /* PTL1_BAD_STACK */ 3950Sstevel@tonic-gate "DTrace flags", /* PTL1_BAD_DTRACE_FLAGS */ 3960Sstevel@tonic-gate "attempt to steal locked ctx", /* PTL1_BAD_CTX_STEAL */ 3970Sstevel@tonic-gate "CPU ECC error loop", /* PTL1_BAD_ECC */ 3981270Sbs21162 "non-kernel context in sys/priv_trap() below or", 3991270Sbs21162 /* PTL1_BAD_CTX */ 4006127Ssm142603 "error raising a TSB exception", /* PTL1_BAD_RAISE_TSBEXCP */ 4016127Ssm142603 "missing shared TSB" /* PTL1_NO_SCDTSB8K */ 4020Sstevel@tonic-gate }; 4030Sstevel@tonic-gate 4040Sstevel@tonic-gate uint_t reason = pstate->ptl1_regs.ptl1_g1; 4050Sstevel@tonic-gate uint_t tl = pstate->ptl1_regs.ptl1_trap_regs[0].ptl1_tl; 4065084Sjohnlev struct panic_trap_info ti = { 0 }; 4070Sstevel@tonic-gate 4080Sstevel@tonic-gate /* 4090Sstevel@tonic-gate * Use trap_info for a place holder to call panic_savetrap() and 4100Sstevel@tonic-gate * panic_showtrap() to save and print out ptl1_panic information. 4110Sstevel@tonic-gate */ 4120Sstevel@tonic-gate if (curthread->t_panic_trap == NULL) 4130Sstevel@tonic-gate curthread->t_panic_trap = &ti; 4140Sstevel@tonic-gate 4150Sstevel@tonic-gate if (reason < sizeof (ptl1_reasons) / sizeof (ptl1_reasons[0])) 4160Sstevel@tonic-gate panic("bad %s at TL %u", ptl1_reasons[reason], tl); 4170Sstevel@tonic-gate else 4180Sstevel@tonic-gate panic("ptl1_panic reason 0x%x at TL %u", reason, tl); 4190Sstevel@tonic-gate } 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate void 4220Sstevel@tonic-gate clear_watchdog_on_exit() 4230Sstevel@tonic-gate { 4240Sstevel@tonic-gate /* 4250Sstevel@tonic-gate * Only shut down an active hardware watchdog timer if the platform 4260Sstevel@tonic-gate * has expressed an interest to. 4270Sstevel@tonic-gate */ 4280Sstevel@tonic-gate if (disable_watchdog_on_exit && watchdog_activated) { 4290Sstevel@tonic-gate prom_printf("Debugging requested; hardware watchdog " 4300Sstevel@tonic-gate "disabled; reboot to re-enable.\n"); 4310Sstevel@tonic-gate cmn_err(CE_WARN, "!Debugging requested; hardware watchdog " 4320Sstevel@tonic-gate "disabled; reboot to re-enable."); 4330Sstevel@tonic-gate mutex_enter(&tod_lock); 4340Sstevel@tonic-gate (void) tod_ops.tod_clear_watchdog_timer(); 4350Sstevel@tonic-gate mutex_exit(&tod_lock); 4360Sstevel@tonic-gate } 4370Sstevel@tonic-gate } 4380Sstevel@tonic-gate 4392036Swentaoy /* 4402036Swentaoy * This null routine is only used by sun4v watchdog timer support. 4412036Swentaoy */ 4422036Swentaoy void 4432036Swentaoy restore_watchdog_on_entry(void) 4442036Swentaoy { 4452036Swentaoy } 4462036Swentaoy 4470Sstevel@tonic-gate int 4480Sstevel@tonic-gate kdi_watchdog_disable(void) 4490Sstevel@tonic-gate { 4500Sstevel@tonic-gate if (watchdog_activated) { 4510Sstevel@tonic-gate mutex_enter(&tod_lock); 4520Sstevel@tonic-gate (void) tod_ops.tod_clear_watchdog_timer(); 4530Sstevel@tonic-gate mutex_exit(&tod_lock); 4540Sstevel@tonic-gate } 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate return (watchdog_activated); 4570Sstevel@tonic-gate } 4580Sstevel@tonic-gate 4590Sstevel@tonic-gate void 4600Sstevel@tonic-gate kdi_watchdog_restore(void) 4610Sstevel@tonic-gate { 4620Sstevel@tonic-gate if (watchdog_enable) { 4630Sstevel@tonic-gate mutex_enter(&tod_lock); 4640Sstevel@tonic-gate (void) tod_ops.tod_set_watchdog_timer(watchdog_timeout_seconds); 4650Sstevel@tonic-gate mutex_exit(&tod_lock); 4660Sstevel@tonic-gate } 4670Sstevel@tonic-gate } 4680Sstevel@tonic-gate 4690Sstevel@tonic-gate /*ARGSUSED*/ 4700Sstevel@tonic-gate void 4710Sstevel@tonic-gate mach_dump_buffer_init(void) 4720Sstevel@tonic-gate { 4730Sstevel@tonic-gate /* 4740Sstevel@tonic-gate * setup dump buffer to store extra crash information 4750Sstevel@tonic-gate * not applicable to sun4u 4760Sstevel@tonic-gate */ 4770Sstevel@tonic-gate } 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate /* 4800Sstevel@tonic-gate * xt_sync - wait for previous x-traps to finish 4810Sstevel@tonic-gate */ 4820Sstevel@tonic-gate void 4830Sstevel@tonic-gate xt_sync(cpuset_t cpuset) 4840Sstevel@tonic-gate { 4850Sstevel@tonic-gate kpreempt_disable(); 4860Sstevel@tonic-gate CPUSET_DEL(cpuset, CPU->cpu_id); 4870Sstevel@tonic-gate CPUSET_AND(cpuset, cpu_ready_set); 4880Sstevel@tonic-gate xt_some(cpuset, (xcfunc_t *)xt_sync_tl1, 0, 0); 4890Sstevel@tonic-gate kpreempt_enable(); 4900Sstevel@tonic-gate } 4913266Sjb145095 4923266Sjb145095 /* 4933266Sjb145095 * mach_soft_state_init() - dummy routine for sun4v soft state 4943266Sjb145095 */ 4953266Sjb145095 void 4963266Sjb145095 mach_soft_state_init(void) 4973266Sjb145095 {} 498