cpu_states.c revision b0fc0e77220f1fa4c933fd58a4e1dedcd650b0f1
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER START
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The contents of this file are subject to the terms of the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Common Development and Distribution License (the "License").
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You may not use this file except in compliance with the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * See the License for the specific language governing permissions
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and limitations under the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When distributing Covered Code, include this CDDL HEADER in each
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If applicable, add the following below this CDDL HEADER, with the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * fields enclosed by brackets "[]" replaced with your own identifying
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * information: Portions Copyright [yyyy] [name of copyright owner]
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER END
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Use is subject to license terms.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#pragma ident "%Z%%M% %I% %E% SMI"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* TRAPTRACE */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysextern void audit_exitprom();
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* C2_AUDIT */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Platforms that use CPU signatures need to set cpu_sgn_func
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * to point to a platform specific function. This needs to
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * be done in set_platform_defaults() within the platmod.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysvoid (*cpu_sgn_func)(ushort_t, uchar_t, uchar_t, int) = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * abort_seq_handler required by sysctrl.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Platform tunable to disable the h/w watchdog timer.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysextern void clear_watchdog_on_exit(void);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * On sun4u platform, abort_sequence_enter() can be called at high PIL
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and we can't afford to acquire any adaptive mutex or use any
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * condition variables as we are not allowed to sleep while running
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * on interrupt stack. We work around this problem by posting a level
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * 10 soft interrupt and then invoking the "abort_seq_handler" within
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * that soft interrupt context.
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * This has the side effect of not allowing us to drop into debugger
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * when the kernel is stuck at high PIL (PIL > 10). It's better to
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * be able to break into a hung system even if it means crashing the
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * system. If a user presses L1-A more than once within a 15 seconds
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * window, and the previous L1-A soft interrupt is still pending, then
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * we directly invoke the abort_sequence_enter.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Since the "msg" argument passed to abort_sequence_enter can refer
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * to a message anywhere in memory, including stack, it's copied into
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * abort_seq_msgbuf buffer for processing by the soft interrupt.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define FORCE_ABORT_SEQ_INTERVAL ((hrtime_t)15 * NANOSEC)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic uint64_t abort_seq_inum; /* abort seq softintr # */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic hrtime_t abort_seq_tstamp; /* hrtime of last abort seq */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllysstatic size_t abort_seq_msglen; /* abort seq message length */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*ARGSUSED0*/
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* C2_AUDIT */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif /* C2_AUDIT */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys#endif /* C2_AUDIT */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys return (1);
a44b45c8fa54b3a79a2de076aa2d8c48cd75dee4Huie-Ying Lee mutex_init(&abort_seq_lock, NULL, MUTEX_SPIN, (void *)PIL_12);
a44b45c8fa54b3a79a2de076aa2d8c48cd75dee4Huie-Ying Lee (softintrfunc)abort_seq_softintr, NULL, SOFTINT_ST);
a44b45c8fa54b3a79a2de076aa2d8c48cd75dee4Huie-Ying Lee * Machine dependent abort sequence handling
a44b45c8fa54b3a79a2de076aa2d8c48cd75dee4Huie-Ying Lee on_intr = CPU_ON_INTR(CPU) || (spltoipl(s) > LOCK_LEVEL);
a44b45c8fa54b3a79a2de076aa2d8c48cd75dee4Huie-Ying Lee * If we are on an interrupt stack and/or running at
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * PIL > LOCK_LEVEL, then we post a softint and invoke
a44b45c8fa54b3a79a2de076aa2d8c48cd75dee4Huie-Ying Lee * abort_seq_handler from there as we can't afford to
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * acquire any adaptive mutex here. However, if we
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * already have a pending softint, which was posted
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * within FORCE_ABORT_SEQ_INTERVAL duration, then we
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * bypass softint approach as our softint may be blocked
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and the user really wants to drop into the debugger.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Ignore any pending abort sequence softint
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * as we are invoking the abort_seq_handler
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* C2_AUDIT */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#endif /* C2_AUDIT */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll#endif /* C2_AUDIT */
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * Enter debugger. Called when the user types L1-A or break or whenever
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * code wants to enter the debugger and possibly resume later.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If the debugger isn't present, enter the PROM monitor.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If console is a framebuffer which is powered off, it will be powered up
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * before jumping to the debugger. If we are called above lock level, a
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * softint is triggered to reenter this code and allow the fb to be powered
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * up as in the less than lock level case. If this code is entered at greater
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * than lock level and the fb is not already powered up, the msg argument
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * will not be displayed.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys extern void pm_cfb_powerup(void);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys extern void pm_cfb_rele(void);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys extern void pm_cfb_trigger(void);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys extern int pm_cfb_check_and_hold(void);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * For platforms that use CPU signatures, update the signature
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * to indicate that we are entering the debugger if we are in
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * the middle of a panic flow.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_DEBUG, -1);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_PANIC_CONT, -1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Halt the machine and return to the monitor
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys stop_other_cpus(); /* send stop signal to other CPUs */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * For Platforms that use CPU signatures, we
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * need to set the signature block to OS and
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * the state to exiting for all the processors.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_HALT, -1);
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll /*NOTREACHED*/
e65e5c2d2f32a99e8c5f740cabae9075dab03ce7Wyllys Ingersoll * Halt the machine and power off the system.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyspower_down(const char *s)
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys stop_other_cpus(); /* send stop signal to other CPUs */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * For platforms that use CPU signatures, we need to set up the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * signature blocks to indicate that we have an environmental
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * interrupt request to power down, and then exit to the prom monitor.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_ENVIRON, -1);
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * If here is reached, for some reason prom's power-off command failed.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * Prom should have already printed out error messages. Exit to
d00756ccb34596a328f8a15d1965da5412d366d0wyllys * firmware.
d00756ccb34596a328f8a15d1965da5412d366d0wyllys /*NOTREACHED*/
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * If we're still booting and init(1) isn't set up yet, simply halt.
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys extern void halt(char *);
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * else, graceful shutdown with inittab and all getting involved