/
inmate.h
259 lines (200 loc) · 5.65 KB
/
inmate.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*
* Jailhouse, a Linux-based partitioning hypervisor
*
* Copyright (c) Siemens AG, 2013
*
* Authors:
* Jan Kiszka <jan.kiszka@siemens.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/
#define NULL ((void *)0)
#define HEAP_BASE 0x000000
#define FSEGMENT_BASE 0x0f0000
#define COMM_REGION_BASE 0x100000
#define INMATE_CS32 0x8
#define INMATE_CS64 0x10
#define INMATE_DS32 0x18
#define NS_PER_USEC 1000UL
#define NS_PER_MSEC 1000000UL
#define NS_PER_SEC 1000000000UL
#define PAGE_SIZE (4 * 1024ULL)
#ifdef __x86_64__
#define BITS_PER_LONG 64
#define HUGE_PAGE_SIZE (2 * 1024 * 1024ULL)
#else
#define BITS_PER_LONG 32
#define HUGE_PAGE_SIZE (4 * 1024 * 1024ULL)
#endif
#define PAGE_MASK (~(PAGE_SIZE - 1))
#define HUGE_PAGE_MASK (~(HUGE_PAGE_SIZE - 1))
#define X2APIC_ID 0x802
#define X2APIC_ICR 0x830
#define APIC_LVL_ASSERT (1 << 14)
#define PCI_CFG_VENDOR_ID 0x000
#define PCI_CFG_DEVICE_ID 0x002
#define PCI_CFG_COMMAND 0x004
# define PCI_CMD_IO (1 << 0)
# define PCI_CMD_MEM (1 << 1)
# define PCI_CMD_MASTER (1 << 2)
# define PCI_CMD_INTX_OFF (1 << 10)
#define PCI_CFG_STATUS 0x006
# define PCI_STS_INT (1 << 3)
# define PCI_STS_CAPS (1 << 4)
#define PCI_CFG_BAR 0x010
# define PCI_BAR_64BIT 0x4
#define PCI_CFG_CAP_PTR 0x034
#define PCI_ID_ANY 0xffff
#define PCI_CAP_MSI 0x05
#define PCI_CAP_MSIX 0x11
#define MSIX_CTRL_ENABLE 0x8000
#define MSIX_CTRL_FMASK 0x4000
#define SMP_MAX_CPUS 255
#ifndef __ASSEMBLY__
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
typedef s8 __s8;
typedef u8 __u8;
typedef s16 __s16;
typedef u16 __u16;
typedef s32 __s32;
typedef u32 __u32;
typedef s64 __s64;
typedef u64 __u64;
typedef enum { true=1, false=0 } bool;
static inline void cpu_relax(void)
{
asm volatile("rep; nop" : : : "memory");
}
static inline void outb(u8 v, u16 port)
{
asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
}
static inline void outw(u16 v, u16 port)
{
asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
}
static inline void outl(u32 v, u16 port)
{
asm volatile("outl %0,%1" : : "a" (v), "dN" (port));
}
static inline u8 inb(u16 port)
{
u8 v;
asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
return v;
}
static inline u16 inw(u16 port)
{
u16 v;
asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
return v;
}
static inline u32 inl(u16 port)
{
u32 v;
asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
return v;
}
static inline u8 mmio_read8(void *address)
{
return *(volatile u8 *)address;
}
static inline u16 mmio_read16(void *address)
{
return *(volatile u16 *)address;
}
static inline u32 mmio_read32(void *address)
{
u32 value;
/* assembly-encoded to match the hypervisor MMIO parser support */
asm volatile("movl (%1),%0" : "=r" (value) : "r" (address));
return value;
}
static inline u64 mmio_read64(void *address)
{
return *(volatile u64 *)address;
}
static inline void mmio_write8(void *address, u8 value)
{
*(volatile u8 *)address = value;
}
static inline void mmio_write16(void *address, u16 value)
{
*(volatile u16 *)address = value;
}
static inline void mmio_write32(void *address, u32 value)
{
/* assembly-encoded to match the hypervisor MMIO parser support */
asm volatile("movl %0,(%1)" : : "r" (value), "r" (address));
}
static inline void mmio_write64(void *address, u64 value)
{
*(volatile u64 *)address = value;
}
static inline u64 read_msr(unsigned int msr)
{
u32 low, high;
asm volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr));
return low | ((u64)high << 32);
}
static inline void write_msr(unsigned int msr, u64 val)
{
asm volatile("wrmsr"
: /* no output */
: "c" (msr), "a" ((u32)val), "d" ((u32)(val >> 32))
: "memory");
}
static inline unsigned int cpu_id(void)
{
return read_msr(X2APIC_ID);
}
#include <jailhouse/hypercall.h>
#define comm_region ((struct jailhouse_comm_region *)COMM_REGION_BASE)
extern unsigned int printk_uart_base;
void printk(const char *fmt, ...);
void *memset(void *s, int c, unsigned long n);
void *memcpy(void *d, const void *s, unsigned long n);
typedef void(*int_handler_t)(void);
void int_init(void);
void int_set_handler(unsigned int vector, int_handler_t handler);
void int_send_ipi(unsigned int cpu_id, unsigned int vector);
enum ioapic_trigger_mode {
TRIGGER_EDGE = 0,
TRIGGER_LEVEL_ACTIVE_HIGH = 1 << 15,
TRIGGER_LEVEL_ACTIVE_LOW = (1 << 15) | (1 << 13),
};
void ioapic_init(void);
void ioapic_pin_set_vector(unsigned int pin,
enum ioapic_trigger_mode trigger_mode,
unsigned int vector);
void inmate_main(void);
void hypercall_init(void);
unsigned long pm_timer_read(void);
unsigned long tsc_read(void);
unsigned long tsc_init(void);
void delay_us(unsigned long microsecs);
unsigned long apic_timer_init(unsigned int vector);
void apic_timer_set(unsigned long timeout_ns);
enum map_type { MAP_CACHED, MAP_UNCACHED };
void *alloc(unsigned long size, unsigned long align);
void map_range(void *start, unsigned long size, enum map_type map_type);
u32 pci_read_config(u16 bdf, unsigned int addr, unsigned int size);
void pci_write_config(u16 bdf, unsigned int addr, u32 value,
unsigned int size);
int pci_find_device(u16 vendor, u16 device, u16 start_bdf);
int pci_find_cap(u16 bdf, u16 cap);
void pci_msi_set_vector(u16 bdf, unsigned int vector);
void pci_msix_set_vector(u16 bdf, unsigned int vector, u32 index);
extern volatile u32 smp_num_cpus;
extern u8 smp_cpu_ids[SMP_MAX_CPUS];
void smp_wait_for_all_cpus(void);
void smp_start_cpu(unsigned int cpu_id, void (*entry)(void));
#endif