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