123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /*
- * Copyright (c) 2017 Richard Braun.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <stdio.h>
- #include <kern/init.h>
- #include <kern/plist.h>
- #include <kern/shell.h>
- #include <kern/shutdown.h>
- #include <machine/boot.h>
- #include <machine/cpu.h>
- static struct plist shutdown_ops_list;
- #ifdef CONFIG_SHELL
- static void
- shutdown_shell_halt (struct shell *shell __unused,
- int argc __unused, char **argv __unused)
- {
- shutdown_halt ();
- }
- static void
- shutdown_shell_reboot (struct shell *shell __unused,
- int argc __unused, char **argv __unused)
- {
- shutdown_reboot ();
- }
- static struct shell_cmd shutdown_shell_cmds[] =
- {
- SHELL_CMD_INITIALIZER ("shutdown_halt", shutdown_shell_halt,
- "shutdown_halt",
- "halt the system"),
- SHELL_CMD_INITIALIZER ("shutdown_reboot", shutdown_shell_reboot,
- "shutdown_reboot",
- "reboot the system"),
- };
- static int __init
- shutdown_setup_shell (void)
- {
- SHELL_REGISTER_CMDS (shutdown_shell_cmds, shell_get_main_cmd_set ());
- return (0);
- }
- INIT_OP_DEFINE (shutdown_setup_shell,
- INIT_OP_DEP (shell_setup, true),
- INIT_OP_DEP (shutdown_setup, true));
- #endif
- static int __init
- shutdown_bootstrap (void)
- {
- plist_init (&shutdown_ops_list);
- return (0);
- }
- INIT_OP_DEFINE (shutdown_bootstrap);
- static int __init
- shutdown_setup (void)
- {
- return (0);
- }
- INIT_OP_DEFINE (shutdown_setup,
- INIT_OP_DEP (boot_setup_shutdown, true),
- INIT_OP_DEP (cpu_setup, true),
- INIT_OP_DEP (printf_setup, true),
- INIT_OP_DEP (shutdown_bootstrap, true));
- void __init
- shutdown_register (struct shutdown_ops *ops, unsigned int priority)
- {
- plist_node_init (&ops->node, priority);
- plist_add (&shutdown_ops_list, &ops->node);
- }
- static void
- shutdown_halt_other_cpus (void)
- {
- cpu_intr_disable ();
- cpu_halt_broadcast ();
- }
- void
- shutdown_halt (void)
- {
- shutdown_halt_other_cpus();
- printf ("shutdown: system halted\n");
- cpu_halt ();
- }
- void
- shutdown_reboot (void)
- {
- if (plist_empty (&shutdown_ops_list))
- {
- printf ("shutdown: no reset operation available, halting\n");
- shutdown_halt();
- }
- shutdown_halt_other_cpus ();
- printf ("shutdown: rebooting...\n");
- struct shutdown_ops *ops;
- plist_for_each_entry_reverse (&shutdown_ops_list, ops, node)
- ops->reset ();
- cpu_halt ();
- }
|