1 /*
2  * Copyright (C) 2018 Kernkonzept GmbH.
3  * Author(s): Sarah Hoffmann <sarah.hoffmann@kernkonzept.com>
4  *
5  * This file is distributed under the terms of the GNU General Public
6  * License, version 2.  Please see the COPYING-GPL-2 file for details.
7  */
8 #pragma once
9 
10 #include <l4/sys/types.h>
11 #include <l4/sys/utcb.h>
12 
13 L4_INLINE l4_msgtag_t
14 l4_arm_smccc_call(l4_cap_idx_t pfc, l4_umword_t func, l4_umword_t in0,
15                   l4_umword_t in1, l4_umword_t in2, l4_umword_t in3,
16                   l4_umword_t in4, l4_umword_t in5, l4_umword_t *out0,
17                   l4_umword_t *out1, l4_umword_t *out2, l4_umword_t *out3,
18                   l4_umword_t client_id) L4_NOTHROW;
19 
20 L4_INLINE l4_msgtag_t
21 l4_arm_smccc_call_u(l4_cap_idx_t pfc, l4_umword_t func, l4_umword_t in0,
22                     l4_umword_t in1, l4_umword_t in2, l4_umword_t in3,
23                     l4_umword_t in4, l4_umword_t in5, l4_umword_t *out0,
24                     l4_umword_t *out1, l4_umword_t *out2, l4_umword_t *out3,
25                     l4_umword_t client_id, l4_utcb_t *utcb) L4_NOTHROW;
26 
27 /* IMPLEMENTATION -----------------------------------------------------------*/
28 
29 #include <l4/sys/ipc.h>
30 
31 L4_INLINE l4_msgtag_t
l4_arm_smccc_call(l4_cap_idx_t pfc,l4_umword_t func,l4_umword_t in0,l4_umword_t in1,l4_umword_t in2,l4_umword_t in3,l4_umword_t in4,l4_umword_t in5,l4_umword_t * out0,l4_umword_t * out1,l4_umword_t * out2,l4_umword_t * out3,l4_umword_t client)32 l4_arm_smccc_call(l4_cap_idx_t pfc, l4_umword_t func,
33                   l4_umword_t in0, l4_umword_t in1,
34                   l4_umword_t in2, l4_umword_t in3,
35                   l4_umword_t in4, l4_umword_t in5,
36                   l4_umword_t *out0, l4_umword_t *out1,
37                   l4_umword_t *out2, l4_umword_t *out3,
38                   l4_umword_t client) L4_NOTHROW
39 {
40   return l4_arm_smccc_call_u(pfc, func, in0, in1, in2, in3, in4, in5,
41                              out0, out1, out2, out3, client, l4_utcb());
42 }
43 
44 
45 L4_INLINE l4_msgtag_t
l4_arm_smccc_call_u(l4_cap_idx_t pfc,l4_umword_t func,l4_umword_t in0,l4_umword_t in1,l4_umword_t in2,l4_umword_t in3,l4_umword_t in4,l4_umword_t in5,l4_umword_t * out0,l4_umword_t * out1,l4_umword_t * out2,l4_umword_t * out3,l4_umword_t client_id,l4_utcb_t * utcb)46 l4_arm_smccc_call_u(l4_cap_idx_t pfc, l4_umword_t func, l4_umword_t in0,
47                     l4_umword_t in1, l4_umword_t in2, l4_umword_t in3,
48                     l4_umword_t in4, l4_umword_t in5, l4_umword_t *out0,
49                     l4_umword_t *out1, l4_umword_t *out2, l4_umword_t *out3,
50                     l4_umword_t client_id, l4_utcb_t *utcb) L4_NOTHROW
51 {
52   l4_msgtag_t ret;
53   l4_msg_regs_t *v = l4_utcb_mr_u(utcb);
54   v->mr[0] = func;
55   v->mr[1] = in0;
56   v->mr[2] = in1;
57   v->mr[3] = in2;
58   v->mr[4] = in3;
59   v->mr[5] = in4;
60   v->mr[6] = in5;
61   v->mr[7] = client_id;
62 
63   ret = l4_ipc_call(pfc, utcb, l4_msgtag(L4_PROTO_SMCCC, 8, 0, 0),
64                     L4_IPC_NEVER);
65 
66   if (l4_error(ret) >= 0)
67     {
68       *out0 = v->mr[0];
69       *out1 = v->mr[1];
70       *out2 = v->mr[2];
71       *out3 = v->mr[3];
72     }
73 
74   return ret;
75 }
76