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