1#![no_std]
15
16pub mod arch;
17pub mod error;
18pub mod psci;
19
20#[cfg(target_arch = "aarch64")]
22pub struct Hvc;
23
24#[cfg(target_arch = "aarch64")]
26pub struct Smc;
27
28pub trait Call {
30 fn call32(function: u32, args: [u32; 7]) -> [u32; 8];
32 fn call64(function: u32, args: [u64; 17]) -> [u64; 18];
34}
35
36#[cfg(target_arch = "aarch64")]
37impl Call for Hvc {
38 fn call32(function: u32, args: [u32; 7]) -> [u32; 8] {
39 hvc32(function, args)
40 }
41
42 fn call64(function: u32, args: [u64; 17]) -> [u64; 18] {
43 hvc64(function, args)
44 }
45}
46
47#[cfg(target_arch = "aarch64")]
48impl Call for Smc {
49 fn call32(function: u32, args: [u32; 7]) -> [u32; 8] {
50 smc32(function, args)
51 }
52
53 fn call64(function: u32, args: [u64; 17]) -> [u64; 18] {
54 smc64(function, args)
55 }
56}
57
58#[cfg(target_arch = "aarch64")]
60#[inline(always)]
61pub fn hvc32(function: u32, args: [u32; 7]) -> [u32; 8] {
62 unsafe {
63 let mut ret = [0; 8];
64
65 core::arch::asm!(
66 "hvc #0",
67 inout("w0") function => ret[0],
68 inout("w1") args[0] => ret[1],
69 inout("w2") args[1] => ret[2],
70 inout("w3") args[2] => ret[3],
71 inout("w4") args[3] => ret[4],
72 inout("w5") args[4] => ret[5],
73 inout("w6") args[5] => ret[6],
74 inout("w7") args[6] => ret[7],
75 options(nomem, nostack)
76 );
77
78 ret
79 }
80}
81
82#[cfg(target_arch = "aarch64")]
84#[inline(always)]
85pub fn smc32(function: u32, args: [u32; 7]) -> [u32; 8] {
86 unsafe {
87 let mut ret = [0; 8];
88
89 core::arch::asm!(
90 "smc #0",
91 inout("w0") function => ret[0],
92 inout("w1") args[0] => ret[1],
93 inout("w2") args[1] => ret[2],
94 inout("w3") args[2] => ret[3],
95 inout("w4") args[3] => ret[4],
96 inout("w5") args[4] => ret[5],
97 inout("w6") args[5] => ret[6],
98 inout("w7") args[6] => ret[7],
99 options(nomem, nostack)
100 );
101
102 ret
103 }
104}
105
106#[cfg(target_arch = "aarch64")]
108#[inline(always)]
109pub fn hvc64(function: u32, args: [u64; 17]) -> [u64; 18] {
110 unsafe {
111 let mut ret = [0; 18];
112
113 core::arch::asm!(
114 "hvc #0",
115 inout("x0") function as u64 => ret[0],
116 inout("x1") args[0] => ret[1],
117 inout("x2") args[1] => ret[2],
118 inout("x3") args[2] => ret[3],
119 inout("x4") args[3] => ret[4],
120 inout("x5") args[4] => ret[5],
121 inout("x6") args[5] => ret[6],
122 inout("x7") args[6] => ret[7],
123 inout("x8") args[7] => ret[8],
124 inout("x9") args[8] => ret[9],
125 inout("x10") args[9] => ret[10],
126 inout("x11") args[10] => ret[11],
127 inout("x12") args[11] => ret[12],
128 inout("x13") args[12] => ret[13],
129 inout("x14") args[13] => ret[14],
130 inout("x15") args[14] => ret[15],
131 inout("x16") args[15] => ret[16],
132 inout("x17") args[16] => ret[17],
133 options(nomem, nostack)
134 );
135
136 ret
137 }
138}
139
140#[cfg(target_arch = "aarch64")]
142#[inline(always)]
143pub fn smc64(function: u32, args: [u64; 17]) -> [u64; 18] {
144 unsafe {
145 let mut ret = [0; 18];
146
147 core::arch::asm!(
148 "smc #0",
149 inout("x0") function as u64 => ret[0],
150 inout("x1") args[0] => ret[1],
151 inout("x2") args[1] => ret[2],
152 inout("x3") args[2] => ret[3],
153 inout("x4") args[3] => ret[4],
154 inout("x5") args[4] => ret[5],
155 inout("x6") args[5] => ret[6],
156 inout("x7") args[6] => ret[7],
157 inout("x8") args[7] => ret[8],
158 inout("x9") args[8] => ret[9],
159 inout("x10") args[9] => ret[10],
160 inout("x11") args[10] => ret[11],
161 inout("x12") args[11] => ret[12],
162 inout("x13") args[12] => ret[13],
163 inout("x14") args[13] => ret[14],
164 inout("x15") args[14] => ret[15],
165 inout("x16") args[15] => ret[16],
166 inout("x17") args[16] => ret[17],
167 options(nomem, nostack)
168 );
169
170 ret
171 }
172}