-
Notifications
You must be signed in to change notification settings - Fork 1
/
hypercall.h
118 lines (106 loc) · 3.82 KB
/
hypercall.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#define DECLARE_REGISTER(x,y,z) register unsigned long reg##x asm(#y) = z;
#define COMMA ,
#if defined(CONFIG_ARM64) || defined(__aarch64__)
#define REGISTER1 DECLARE_REGISTER(0,x8,num)
#define REGISTER2 REGISTER1 DECLARE_REGISTER(1,x0,arg1)
#define REGISTER3 REGISTER2 DECLARE_REGISTER(2,x1,arg2)
#define REGISTER4 REGISTER3 DECLARE_REGISTER(3,x2,arg3)
#define REGISTER5 REGISTER4 DECLARE_REGISTER(4,x3,arg4)
#define ASM(x) asm volatile(\
"msr S0_0_c5_c0_0, xzr"\
: "+r"(reg1)\
: "r"(reg0) x \
: "memory" \
);
#define RETURN return reg1;
#elif defined(CONFIG_ARM) || defined(__arm__)
#define REGISTER1 DECLARE_REGISTER(0,r7,num)
#define REGISTER2 REGISTER1 DECLARE_REGISTER(1,r0,arg1)
#define REGISTER3 REGISTER2 DECLARE_REGISTER(2,r1,arg2)
#define REGISTER4 REGISTER3 DECLARE_REGISTER(3,r2,arg3)
#define REGISTER5 REGISTER4 DECLARE_REGISTER(4,r3,arg4)
#define ASM(x) asm volatile(\
"mcr p7, 0, r0, c0, c0, 0"\
: "+r"(reg1)\
: "r"(reg0) x \
: "memory" \
);
#define RETURN return reg1;
#elif defined(CONFIG_MIPS) || defined(mips) || defined(__mips__) || defined(__mips) || defined(__mips64)
#define REGISTER1 DECLARE_REGISTER(0,v0,num)
#define REGISTER2 REGISTER1 DECLARE_REGISTER(1,a0,arg1)
#define REGISTER3 REGISTER2 DECLARE_REGISTER(2,a1,arg2)
#define REGISTER4 REGISTER3 DECLARE_REGISTER(3,a2,arg3)
#define REGISTER5 REGISTER4 DECLARE_REGISTER(4,a3,arg4)
#define ASM(x) asm volatile(\
"movz $0, $0, $0"\
: "+r"(reg0) \
: "r"(reg1) x \
: "memory" \
);
#define RETURN return reg0;
#elif defined(CONFIG_X86_64) || defined(__x86_64__)
#define REGISTER1 DECLARE_REGISTER(0,rax,num)
#define REGISTER2 REGISTER1 DECLARE_REGISTER(1,rdi,arg1)
#define REGISTER3 REGISTER2 DECLARE_REGISTER(2,rsi,arg2)
#define REGISTER4 REGISTER3 DECLARE_REGISTER(3,rdx,arg3)
#define REGISTER5 REGISTER4 DECLARE_REGISTER(4,r10,arg4)
#define ASM(x) asm volatile(\
"cpuid"\
: "+r"(reg0) \
: "r"(reg1) x \
: "memory" );
#define RETURN return reg0;
#elif defined(CONFIG_I386) || (defined(__i386__) && !defined(__x86_64__))
#define REGISTER1 DECLARE_REGISTER(0,eax,num)
#define REGISTER2 REGISTER1 DECLARE_REGISTER(1,ebx,arg1)
#define REGISTER3 REGISTER2 DECLARE_REGISTER(2,ecx,arg2)
#define REGISTER4 REGISTER3 DECLARE_REGISTER(3,edx,arg3)
#define REGISTER5 REGISTER4 DECLARE_REGISTER(4,esi,arg4)
#define ASM(x) asm volatile(\
"cpuid"\
: "+r"(reg0) \
: "r"(reg1) x \
: "memory" \
);
#define RETURN return reg0;
#else
#error "not supported"
#endif
static inline unsigned long igloo_hypercall(unsigned long num, unsigned long arg1){
REGISTER2
ASM()
RETURN
}
static inline unsigned long igloo_hypercall2(unsigned long num, unsigned long arg1, unsigned long arg2){
REGISTER3
ASM(COMMA"r"(reg2))
RETURN
}
static inline unsigned long igloo_hypercall3(unsigned long num, unsigned long arg1, unsigned long arg2, unsigned long arg3){
REGISTER4
ASM(COMMA "r"(reg2)COMMA "r"(reg3))
RETURN
}
static inline unsigned long igloo_hypercall4(unsigned long num, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4){
REGISTER5
ASM(COMMA "r"(reg2)COMMA "r"(reg3)COMMA "r"(reg4))
RETURN
}
#ifdef MAGIC_VALUE
#define RETRY 0xDEADBEEF
static inline int hc(int hc_type, void **s,int len) {
uint64_t ret = hc_type;
int y = 0;
do {
ret = MAGIC_VALUE;
volatile int x = 0;
for(int i = 0; i< len; i++) {
x |= *(((int*)s[i])+y);
}
y++;
ret = igloo_hypercall3(MAGIC_VALUE,(unsigned long)hc_type,(unsigned long)s,(unsigned long)len);
} while (ret == RETRY);
return ret;
}
#endif