1 /*
2  * Copyright (c) 2023 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/shell/shell.h>
8 #include <zephyr/drivers/pm_cpu_ops.h>
9 
10 /* Zephyr kernel start address. */
11 extern void __start(void);
12 
cmd_reboot_warm(const struct shell * shctx,size_t argc,char ** argv)13 static int cmd_reboot_warm(const struct shell *shctx, size_t argc, char **argv)
14 {
15 	ARG_UNUSED(shctx);
16 	ARG_UNUSED(argc);
17 	ARG_UNUSED(argv);
18 	int ret;
19 
20 	ret = pm_system_reset(SYS_WARM_RESET);
21 	if (ret != 0) {
22 		shell_error(shctx, "Failed to perform system warm reset");
23 	}
24 
25 	return ret;
26 }
27 
cmd_reboot_cold(const struct shell * shctx,size_t argc,char ** argv)28 static int cmd_reboot_cold(const struct shell *shctx, size_t argc, char **argv)
29 {
30 	ARG_UNUSED(shctx);
31 	ARG_UNUSED(argc);
32 	ARG_UNUSED(argv);
33 	int ret;
34 
35 	ret = pm_system_reset(SYS_COLD_RESET);
36 	if (ret != 0) {
37 		shell_error(shctx, "Failed to perform system cold reset");
38 	}
39 
40 	return ret;
41 }
42 
cmd_psci_cpuon(const struct shell * shctx,size_t argc,char ** argv)43 static int cmd_psci_cpuon(const struct shell *shctx, size_t argc, char **argv)
44 {
45 	ARG_UNUSED(shctx);
46 	ARG_UNUSED(argc);
47 	long cpu_id;
48 	int result;
49 
50 	errno = 0;
51 	cpu_id = strtol(argv[1], NULL, 10);
52 	if (cpu_id == 0 || cpu_id == LONG_MIN || cpu_id == LONG_MAX) {
53 		if (errno != 0) {
54 			shell_error(shctx, "psci: invalid input:%ld", cpu_id);
55 			return -EINVAL;
56 		}
57 	}
58 
59 	result = pm_cpu_on((unsigned long)cpu_id, (uintptr_t)&__start);
60 
61 	return result;
62 }
63 
64 SHELL_STATIC_SUBCMD_SET_CREATE(
65 	sub_reboot,
66 	SHELL_CMD_ARG(warm, NULL, "System warm reset. Usage: <psci warm>", cmd_reboot_warm, 1, 0),
67 	SHELL_CMD_ARG(cold, NULL, "System cold reset. Usage: <psci cold>", cmd_reboot_cold, 1, 0),
68 	SHELL_CMD_ARG(cpuon, NULL, "Power-up the secondary CPU. Usage: <psci cpuon <cpuid>>",
69 		      cmd_psci_cpuon, 2, 0),
70 	SHELL_SUBCMD_SET_END /* Array terminated. */
71 );
72 
73 SHELL_CMD_REGISTER(psci, &sub_reboot, "ARM PSCI interface commands", NULL);
74