1 /*
2 * Copyright (c) 2012 Google, Inc.
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <lk/debug.h>
9 #include <lk/err.h>
10 #include <lk/compiler.h>
11 #include <lk/console_cmd.h>
12 #include <platform.h>
13 #include <platform/debug.h>
14 #include <kernel/thread.h>
15
16 #if WITH_LIB_CONSOLE
17 #include <lib/console.h>
18 #endif
19
20 // Default implementation of the system halt and reset function. Platforms may use
21 // this as a helper to implement the logic by passing in a few hooks to do the
22 // actual shutdown or reboot.
platform_halt_default(platform_halt_action suggested_action,platform_halt_reason reason,platform_reboot_hook prh,platform_shutdown_hook psh)23 void platform_halt_default(platform_halt_action suggested_action,
24 platform_halt_reason reason,
25 platform_reboot_hook prh,
26 platform_shutdown_hook psh) {
27 const char *reason_string = platform_halt_reason_string(reason);
28 switch (suggested_action) {
29 case HALT_ACTION_SHUTDOWN:
30 if (psh) {
31 dprintf(ALWAYS, "Shutting down, reason '%s'\n", reason_string);
32 psh();
33 }
34 break;
35 case HALT_ACTION_REBOOT:
36 if (prh) {
37 dprintf(ALWAYS, "Rebooting, reason '%s'\n", reason_string);
38 prh();
39 }
40 break;
41 case HALT_ACTION_HALT:
42 #if ENABLE_PANIC_SHELL
43 if (reason == HALT_REASON_SW_PANIC) {
44 dprintf(ALWAYS, "CRASH: starting debug shell, reason '%s'\n", reason_string);
45 arch_disable_ints();
46 panic_shell_start();
47 }
48 #endif // ENABLE_PANIC_SHELL
49 break;
50 }
51
52 dprintf(ALWAYS, "HALT: spinning forever, reason '%s'\n", reason_string);
53 arch_disable_ints();
54 for (;;)
55 arch_idle();
56 }
57
58 // Default implementation of platform halt, which simply start the debug shell or spins forever.
platform_halt(platform_halt_action suggested_action,platform_halt_reason reason)59 __WEAK void platform_halt(platform_halt_action suggested_action,
60 platform_halt_reason reason) {
61 platform_halt_default(suggested_action, reason, NULL, NULL);
62 }
63
platform_get_reboot_reason(void)64 __WEAK platform_halt_reason platform_get_reboot_reason(void) {
65 return HALT_REASON_UNKNOWN;
66 }
67
platform_halt_action_string(platform_halt_action action)68 const char *platform_halt_action_string(platform_halt_action action) {
69 switch(action) {
70 case HALT_ACTION_HALT:
71 return "halt";
72 case HALT_ACTION_REBOOT:
73 return "reboot";
74 case HALT_ACTION_SHUTDOWN:
75 return "shutdown";
76 }
77 return "unknown";
78 }
79
platform_halt_reason_string(platform_halt_reason reason)80 const char *platform_halt_reason_string(platform_halt_reason reason) {
81 switch(reason) {
82 case HALT_REASON_UNKNOWN:
83 return "unknown";
84 case HALT_REASON_POR:
85 return "power on reset";
86 case HALT_REASON_HW_WATCHDOG:
87 return "hardware watchdog";
88 case HALT_REASON_LOWVOLTAGE:
89 return "low voltage";
90 case HALT_REASON_HIGHVOLTAGE:
91 return "high voltage";
92 case HALT_REASON_THERMAL:
93 return "thermal";
94 case HALT_REASON_OTHER_HW:
95 return "other hardware";
96 case HALT_REASON_SW_RESET:
97 return "software reset";
98 case HALT_REASON_SW_WATCHDOG:
99 return "software watchdog";
100 case HALT_REASON_SW_PANIC:
101 return "software panic";
102 case HALT_REASON_SW_UPDATE:
103 return "software update";
104 }
105 return "unknown";
106 }
107
cmd_reboot(int argc,const console_cmd_args * argv)108 static int cmd_reboot(int argc, const console_cmd_args *argv) {
109 platform_halt(HALT_ACTION_REBOOT, HALT_REASON_SW_RESET);
110 return 0;
111 }
112
cmd_poweroff(int argc,const console_cmd_args * argv)113 static int cmd_poweroff(int argc, const console_cmd_args *argv) {
114 platform_halt(HALT_ACTION_SHUTDOWN, HALT_REASON_SW_RESET);
115 return 0;
116 }
117
118 STATIC_COMMAND_START
119 #if LK_DEBUGLEVEL > 1
120 STATIC_COMMAND("reboot", "soft reset", &cmd_reboot)
121 STATIC_COMMAND("poweroff", "powerdown", &cmd_poweroff)
122 #endif
123 STATIC_COMMAND_END(platform_power);
124