18 #include <linux/slab.h>
20 #include <linux/module.h>
22 #include <linux/errno.h>
25 #include <asm/cacheflush.h>
30 #define CACHELINESIZE 32
33 #define SCM_EOPNOTSUPP -4
34 #define SCM_EINVAL_ADDR -3
35 #define SCM_EINVAL_ARG -2
37 #define SCM_INTERRUPTED 1
105 cmd->resp_hdr_offset = cmd->buf_offset +
cmd_size;
127 static inline struct scm_response *scm_command_to_response(
139 static inline void *scm_get_command_buffer(
const struct scm_command *cmd)
141 return (
void *)cmd->
buf;
150 static inline void *scm_get_response_buffer(
const struct scm_response *
rsp)
155 static int scm_remap_error(
int err)
174 register u32 r0 asm(
"r0") = 1;
175 register u32 r1 asm(
"r1") = (
u32)&context_id;
176 register u32 r2 asm(
"r2") = cmd_addr;
184 ".arch_extension sec\n"
186 "smc #0 @ switch to secure world\n"
188 :
"r" (
r0),
"r" (
r1),
"r" (
r2)
195 static int __scm_call(
const struct scm_command *cmd)
208 ret = scm_remap_error(ret);
231 cmd = alloc_scm_command(cmd_len, resp_len);
235 cmd->
id = (svc_id << 10) | cmd_id;
237 memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
240 ret = __scm_call(cmd);
245 rsp = scm_command_to_response(cmd);
250 while (start < end) {
251 asm (
"mcr p15, 0, %0, c7, c6, 1" : :
"r" (
start)
258 memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
260 free_scm_command(cmd);
269 register u32 r0 asm(
"r0");
270 register u32 r1 asm(
"r1");
278 r1 = (
u32)&context_id;
286 ".arch_extension sec\n"
288 "smc #0 @ switch to secure world\n"
289 :
"=r" (
r0),
"=r" (
r1)