]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/arm/include/asm/jailhouse_hypercall.h
arm: exit statistics
[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
21 /* CPU statistics */
22 #define JAILHOUSE_CPU_STAT_VMEXITS_MAINTENANCE  JAILHOUSE_GENERIC_CPU_STATS
23 #define JAILHOUSE_CPU_STAT_VMEXITS_VIRQ         JAILHOUSE_GENERIC_CPU_STATS + 1
24 #define JAILHOUSE_CPU_STAT_VMEXITS_VSGI         JAILHOUSE_GENERIC_CPU_STATS + 2
25 #define JAILHOUSE_NUM_CPU_STATS                 JAILHOUSE_GENERIC_CPU_STATS + 3
26
27 #ifndef __asmeq
28 #define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
29 #endif
30
31 #ifndef __ASSEMBLY__
32
33 struct jailhouse_comm_region {
34         COMM_REGION_GENERIC_HEADER;
35 };
36
37 static inline __u32 jailhouse_call(__u32 num)
38 {
39         register __u32 num_result asm(JAILHOUSE_CALL_NUM_RESULT) = num;
40
41         asm volatile(
42                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%0")
43                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%1")
44                 JAILHOUSE_CALL_INS
45                 : "=r" (num_result)
46                 : "r" (num_result)
47                 : "memory");
48         return num_result;
49 }
50
51 static inline __u32 jailhouse_call_arg1(__u32 num, __u32 arg1)
52 {
53         register __u32 num_result asm(JAILHOUSE_CALL_NUM_RESULT) = num;
54         register __u32 __arg1 asm(JAILHOUSE_CALL_ARG1) = arg1;
55
56         asm volatile(
57                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%0")
58                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%1")
59                 __asmeq(JAILHOUSE_CALL_ARG1, "%2")
60                 JAILHOUSE_CALL_INS
61                 : "=r" (num_result)
62                 : "r" (num_result), "r" (__arg1)
63                 : "memory");
64         return num_result;
65 }
66
67 static inline __u32 jailhouse_call_arg2(__u32 num, __u32 arg1, __u32 arg2)
68 {
69         register __u32 num_result asm(JAILHOUSE_CALL_NUM_RESULT) = num;
70         register __u32 __arg1 asm(JAILHOUSE_CALL_ARG1) = arg1;
71         register __u32 __arg2 asm(JAILHOUSE_CALL_ARG2) = arg2;
72
73         asm volatile(
74                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%0")
75                 __asmeq(JAILHOUSE_CALL_NUM_RESULT, "%1")
76                 __asmeq(JAILHOUSE_CALL_ARG1, "%2")
77                 __asmeq(JAILHOUSE_CALL_ARG2, "%3")
78                 JAILHOUSE_CALL_INS
79                 : "=r" (num_result)
80                 : "r" (num_result), "r" (__arg1), "r" (__arg2)
81                 : "memory");
82         return num_result;
83 }
84
85 static inline void
86 jailhouse_send_msg_to_cell(struct jailhouse_comm_region *comm_region,
87                            __u32 msg)
88 {
89         comm_region->reply_from_cell = JAILHOUSE_MSG_NONE;
90         /* ensure reply was cleared before sending new message */
91         asm volatile("dmb ishst" : : : "memory");
92         comm_region->msg_to_cell = msg;
93 }
94
95 static inline void
96 jailhouse_send_reply_from_cell(struct jailhouse_comm_region *comm_region,
97                                __u32 reply)
98 {
99         comm_region->msg_to_cell = JAILHOUSE_MSG_NONE;
100         /* ensure message was cleared before sending reply */
101         asm volatile("dmb ishst" : : : "memory");
102         comm_region->reply_from_cell = reply;
103 }
104
105 #endif /* !__ASSEMBLY__ */