]>
Commit | Line | Data |
---|---|---|
a5b9fa30 ST |
1 | /** |
2 | * (C) Copyright 2014, Cavium Inc. | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | **/ | |
6 | ||
7 | #include <asm-offsets.h> | |
8 | #include <config.h> | |
9 | #include <version.h> | |
10 | #include <asm/macro.h> | |
5a07abb3 | 11 | #include <asm/psci.h> |
a5b9fa30 ST |
12 | #include <asm/system.h> |
13 | ||
14 | /* | |
15 | * Issue the hypervisor call | |
16 | * | |
17 | * x0~x7: input arguments | |
18 | * x0~x3: output arguments | |
19 | */ | |
51bfb5b6 | 20 | static void hvc_call(struct pt_regs *args) |
a5b9fa30 ST |
21 | { |
22 | asm volatile( | |
23 | "ldr x0, %0\n" | |
24 | "ldr x1, %1\n" | |
25 | "ldr x2, %2\n" | |
26 | "ldr x3, %3\n" | |
27 | "ldr x4, %4\n" | |
28 | "ldr x5, %5\n" | |
29 | "ldr x6, %6\n" | |
30 | "ldr x7, %7\n" | |
31 | "hvc #0\n" | |
32 | "str x0, %0\n" | |
33 | "str x1, %1\n" | |
34 | "str x2, %2\n" | |
35 | "str x3, %3\n" | |
36 | : "+m" (args->regs[0]), "+m" (args->regs[1]), | |
37 | "+m" (args->regs[2]), "+m" (args->regs[3]) | |
38 | : "m" (args->regs[4]), "m" (args->regs[5]), | |
39 | "m" (args->regs[6]), "m" (args->regs[7]) | |
40 | : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", | |
41 | "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", | |
42 | "x16", "x17"); | |
43 | } | |
44 | ||
45 | /* | |
46 | * void smc_call(arg0, arg1...arg7) | |
47 | * | |
48 | * issue the secure monitor call | |
49 | * | |
50 | * x0~x7: input arguments | |
51 | * x0~x3: output arguments | |
52 | */ | |
53 | ||
54 | void smc_call(struct pt_regs *args) | |
55 | { | |
56 | asm volatile( | |
57 | "ldr x0, %0\n" | |
58 | "ldr x1, %1\n" | |
59 | "ldr x2, %2\n" | |
60 | "ldr x3, %3\n" | |
61 | "ldr x4, %4\n" | |
62 | "ldr x5, %5\n" | |
63 | "ldr x6, %6\n" | |
64 | "smc #0\n" | |
65 | "str x0, %0\n" | |
66 | "str x1, %1\n" | |
67 | "str x2, %2\n" | |
68 | "str x3, %3\n" | |
69 | : "+m" (args->regs[0]), "+m" (args->regs[1]), | |
70 | "+m" (args->regs[2]), "+m" (args->regs[3]) | |
71 | : "m" (args->regs[4]), "m" (args->regs[5]), | |
72 | "m" (args->regs[6]) | |
73 | : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", | |
74 | "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", | |
75 | "x16", "x17"); | |
76 | } | |
5a07abb3 | 77 | |
51bfb5b6 AG |
78 | /* |
79 | * For now, all systems we support run at least in EL2 and thus | |
80 | * trigger PSCI calls to EL3 using SMC. If anyone ever wants to | |
81 | * use PSCI on U-Boot running below a hypervisor, please detect | |
82 | * this and set the flag accordingly. | |
83 | */ | |
84 | static const bool use_smc_for_psci = true; | |
85 | ||
86 | void __noreturn psci_system_reset(void) | |
5a07abb3 BG |
87 | { |
88 | struct pt_regs regs; | |
89 | ||
90 | regs.regs[0] = ARM_PSCI_0_2_FN_SYSTEM_RESET; | |
91 | ||
51bfb5b6 | 92 | if (use_smc_for_psci) |
5a07abb3 BG |
93 | smc_call(®s); |
94 | else | |
95 | hvc_call(®s); | |
96 | ||
97 | while (1) | |
98 | ; | |
99 | } | |
3ee655ed AG |
100 | |
101 | void __noreturn psci_system_off(void) | |
102 | { | |
103 | struct pt_regs regs; | |
104 | ||
105 | regs.regs[0] = ARM_PSCI_0_2_FN_SYSTEM_OFF; | |
106 | ||
107 | if (use_smc_for_psci) | |
108 | smc_call(®s); | |
109 | else | |
110 | hvc_call(®s); | |
111 | ||
112 | while (1) | |
113 | ; | |
114 | } |