]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/arm/include/asm/jailhouse_hypercall.h
core/driver: Switch hypervisor to fixed virtual address layout
[jailhouse.git] / hypervisor / arch / arm / include / asm / jailhouse_hypercall.h
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) Siemens AG, 2013
5  *
6  * Authors:
7  *  Jan Kiszka <jan.kiszka@siemens.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #define JAILHOUSE_BASE                  0xf0000000
14
15 #define JAILHOUSE_CALL_INS              ".arch_extension virt\n\t" \
16                                         "hvc #0x4a48"
17 #define JAILHOUSE_CALL_NUM_RESULT       "r0"
18 #define JAILHOUSE_CALL_ARG1             "r1"
19 #define JAILHOUSE_CALL_ARG2             "r2"
20 #define JAILHOUSE_CALL_ARG3             "r3"
21 #define JAILHOUSE_CALL_ARG4             "r4"
22
23 #ifndef __asmeq
24 #define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
25 #endif
26
27 #ifndef __ASSEMBLY__
28
29 static inline __u32 jailhouse_call0(__u32 num)
30 {
31         register __u32 num_result asm(JAILHOUSE_CALL_NUM_RESULT) = num;
32
33         asm volatile(
34                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%0")
35                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%1")
36                 JAILHOUSE_CALL_INS
37                 : "=r" (num_result)
38                 : "r" (num_result)
39                 : "memory");
40         return num_result;
41 }
42
43 static inline __u32 jailhouse_call1(__u32 num, __u32 arg1)
44 {
45         register __u32 num_result asm(JAILHOUSE_CALL_NUM_RESULT) = num;
46         register __u32 __arg1 asm(JAILHOUSE_CALL_ARG1) = arg1;
47
48         asm volatile(
49                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%0")
50                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%1")
51                 __asmeq(JAILHOUSE_CALL_ARG1, "%2")
52                 JAILHOUSE_CALL_INS
53                 : "=r" (num_result)
54                 : "r" (num_result), "r" (__arg1)
55                 : "memory");
56         return num_result;
57 }
58
59 static inline __u32 jailhouse_call2(__u32 num, __u32 arg1, __u32 arg2)
60 {
61         register __u32 num_result asm(JAILHOUSE_CALL_NUM_RESULT) = num;
62         register __u32 __arg1 asm(JAILHOUSE_CALL_ARG1) = arg1;
63         register __u32 __arg2 asm(JAILHOUSE_CALL_ARG2) = arg2;
64
65         asm volatile(
66                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%0")
67                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%1")
68                 __asmeq(JAILHOUSE_CALL_ARG1, "%2")
69                 __asmeq(JAILHOUSE_CALL_ARG2, "%3")
70                 JAILHOUSE_CALL_INS
71                 : "=r" (num_result)
72                 : "r" (num_result), "r" (__arg1), "r" (__arg2)
73                 : "memory");
74         return num_result;
75 }
76
77 static inline __u32 jailhouse_call3(__u32 num, __u32 arg1, __u32 arg2,
78                                    __u32 arg3)
79 {
80         register __u32 num_result asm(JAILHOUSE_CALL_NUM_RESULT) = num;
81         register __u32 __arg1 asm(JAILHOUSE_CALL_ARG1) = arg1;
82         register __u32 __arg2 asm(JAILHOUSE_CALL_ARG2) = arg2;
83         register __u32 __arg3 asm(JAILHOUSE_CALL_ARG3) = arg3;
84
85         asm volatile(
86                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%0")
87                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%1")
88                 __asmeq(JAILHOUSE_CALL_ARG1, "%2")
89                 __asmeq(JAILHOUSE_CALL_ARG2, "%3")
90                 __asmeq(JAILHOUSE_CALL_ARG3, "%4")
91                 JAILHOUSE_CALL_INS
92                 : "=r" (num_result)
93                 : "r" (num_result), "r" (__arg1), "r" (__arg2), "r" (__arg3)
94                 : "memory");
95         return num_result;
96 }
97
98 static inline __u32 jailhouse_call4(__u32 num, __u32 arg1, __u32 arg2,
99                                    __u32 arg3, __u32 arg4)
100 {
101         register __u32 num_result asm(JAILHOUSE_CALL_NUM_RESULT) = num;
102         register __u32 __arg1 asm(JAILHOUSE_CALL_ARG1) = arg1;
103         register __u32 __arg2 asm(JAILHOUSE_CALL_ARG2) = arg2;
104         register __u32 __arg3 asm(JAILHOUSE_CALL_ARG3) = arg3;
105         register __u32 __arg4 asm(JAILHOUSE_CALL_ARG4) = arg4;
106
107         asm volatile(
108                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%0")
109                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%1")
110                 __asmeq(JAILHOUSE_CALL_ARG1, "%2")
111                 __asmeq(JAILHOUSE_CALL_ARG2, "%3")
112                 __asmeq(JAILHOUSE_CALL_ARG3, "%4")
113                 __asmeq(JAILHOUSE_CALL_ARG4, "%5")
114                 JAILHOUSE_CALL_INS
115                 : "=r" (num_result)
116                 : "r" (num_result), "r" (__arg1), "r" (__arg2), "r" (__arg3),
117                   "r" (__arg4)
118                 : "memory");
119         return num_result;
120 }
121
122 static inline void
123 jailhouse_send_msg_to_cell(struct jailhouse_comm_region *comm_region,
124                            __u32 msg)
125 {
126         comm_region->reply_from_cell = JAILHOUSE_MSG_NONE;
127         /* ensure reply was cleared before sending new message */
128         asm volatile("dmb ishst" : : : "memory");
129         comm_region->msg_to_cell = msg;
130 }
131
132 static inline void
133 jailhouse_send_reply_from_cell(struct jailhouse_comm_region *comm_region,
134                                __u32 reply)
135 {
136         comm_region->msg_to_cell = JAILHOUSE_MSG_NONE;
137         /* ensure message was cleared before sending reply */
138         asm volatile("dmb ishst" : : : "memory");
139         comm_region->reply_from_cell = reply;
140 }
141
142 #endif /* !__ASSEMBLY__ */