1 #ifndef __HVMLOADER_UTIL_H__
2 #define __HVMLOADER_UTIL_H__
3 
4 #include <stdarg.h>
5 #include <stdint.h>
6 #include <stddef.h>
7 #include <stdbool.h>
8 #include <xen/xen.h>
9 #include <xen/hvm/hvm_info_table.h>
10 #include "config.h"
11 #include "e820.h"
12 
13 #include <xen-tools/common-macros.h>
14 
15 /* Request un-prefixed values from errno.h. */
16 #define XEN_ERRNO(name, value) name = value,
17 enum {
18 #include <xen/errno.h>
19 };
20 
21 /* Cause xs_wire.h to give us xsd_errors[]. */
22 #define EINVAL EINVAL
23 
24 #define __STR(...) #__VA_ARGS__
25 #define STR(...) __STR(__VA_ARGS__)
26 
27 /* GDT selector values. */
28 #define SEL_CODE16          0x0008
29 #define SEL_DATA16          0x0010
30 #define SEL_CODE32          0x0018
31 #define SEL_DATA32          0x0020
32 #define SEL_CODE64          0x0028
33 
34 void __assert_failed(const char *assertion, const char *file, int line)
35     __attribute__((noreturn));
36 #define ASSERT(p) \
37     do { if (!(p)) __assert_failed(#p, __FILE__, __LINE__); } while (0)
38 void __bug(const char *file, int line) __attribute__((noreturn));
39 #define BUG() __bug(__FILE__, __LINE__)
40 #define BUG_ON(p) do { if (p) BUG(); } while (0)
41 
test_bit(unsigned int b,const void * p)42 static inline int test_bit(unsigned int b, const void *p)
43 {
44     return !!(((const uint8_t *)p)[b>>3] & (1u<<(b&7)));
45 }
46 
test_and_clear_bit(int nr,volatile void * addr)47 static inline int test_and_clear_bit(int nr, volatile void *addr)
48 {
49     int oldbit;
50     asm volatile (
51         "lock ; btrl %2,%1 ; sbbl %0,%0"
52         : "=r" (oldbit), "=m" (*(volatile long *)addr)
53         : "Ir" (nr), "m" (*(volatile long *)addr) : "memory");
54     return oldbit;
55 }
56 
57 /* MSR access */
wrmsr(uint32_t idx,uint64_t v)58 static inline void wrmsr(uint32_t idx, uint64_t v)
59 {
60     asm volatile ( "wrmsr" :: "c" (idx), "A" (v) );
61 }
62 
rdmsr(uint32_t idx)63 static inline uint64_t rdmsr(uint32_t idx)
64 {
65     uint64_t res;
66 
67     asm volatile ( "rdmsr" : "=A" (res) : "c" (idx) );
68 
69     return res;
70 }
71 
72 /* I/O output */
outb(uint16_t port,uint8_t val)73 static inline void outb(uint16_t port, uint8_t val)
74 {
75     asm volatile ( "outb %[val], %[port]"
76                    :
77                    : [port] "Nd" (port),
78                      [val] "a" (val)
79                    : "memory" );
80 }
81 
outw(uint16_t port,uint16_t val)82 static inline void outw(uint16_t port, uint16_t val)
83 {
84     asm volatile ( "outw %[val], %[port]"
85                    :
86                    : [port] "Nd" (port),
87                      [val] "a" (val)
88                    : "memory" );
89 }
90 
outl(uint16_t port,uint32_t val)91 static inline void outl(uint16_t port, uint32_t val)
92 {
93     asm volatile ( "outl %[val], %[port]"
94                    :
95                    : [port] "Nd" (port),
96                      [val] "a" (val)
97                    : "memory" );
98 }
99 
100 /* I/O input */
inb(uint16_t port)101 static inline uint8_t inb(uint16_t port)
102 {
103     uint8_t val;
104 
105     asm volatile ( "inb %[port], %[val]"
106                    : [val] "=a" (val)
107                    : [port] "Nd" (port)
108                    : "memory" );
109 
110     return val;
111 }
112 
inw(uint16_t port)113 static inline uint16_t inw(uint16_t port)
114 {
115     uint16_t val;
116 
117     asm volatile ( "inw %[port], %[val]"
118                    : [val] "=a" (val)
119                    : [port] "Nd" (port)
120                    : "memory" );
121 
122     return val;
123 }
124 
inl(uint16_t port)125 static inline uint32_t inl(uint16_t port)
126 {
127     uint32_t val;
128 
129     asm volatile ( "inl %[port], %[val]"
130                    : [val] "=a" (val)
131                    : [port] "Nd" (port)
132                    : "memory" );
133 
134     return val;
135 }
136 
137 /* CMOS access */
138 uint8_t cmos_inb(uint8_t idx);
139 void cmos_outb(uint8_t idx, uint8_t val);
140 
141 /* APIC access */
142 #define IOAPIC_BASE_ADDRESS 0xfec00000
ioapic_read(uint32_t reg)143 static inline uint32_t ioapic_read(uint32_t reg)
144 {
145     *(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x00) = reg;
146     return *(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x10);
147 }
148 
ioapic_write(uint32_t reg,uint32_t val)149 static inline void ioapic_write(uint32_t reg, uint32_t val)
150 {
151     *(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x00) = reg;
152     *(volatile uint32_t *)(IOAPIC_BASE_ADDRESS + 0x10) = val;
153 }
154 
155 #define LAPIC_BASE_ADDRESS  0xfee00000
lapic_read(uint32_t reg)156 static inline uint32_t lapic_read(uint32_t reg)
157 {
158     return *(volatile uint32_t *)(LAPIC_BASE_ADDRESS + reg);
159 }
160 
lapic_write(uint32_t reg,uint32_t val)161 static inline void lapic_write(uint32_t reg, uint32_t val)
162 {
163     *(volatile uint32_t *)(LAPIC_BASE_ADDRESS + reg) = val;
164 }
165 
166 /* PCI access */
167 uint32_t pci_read(uint32_t devfn, uint32_t reg, uint32_t len);
168 #define pci_readb(devfn, reg) ((uint8_t) pci_read(devfn, reg, 1))
169 #define pci_readw(devfn, reg) ((uint16_t)pci_read(devfn, reg, 2))
170 #define pci_readl(devfn, reg) ((uint32_t)pci_read(devfn, reg, 4))
171 void pci_write(uint32_t devfn, uint32_t reg, uint32_t len, uint32_t val);
172 #define pci_writeb(devfn, reg, val) pci_write(devfn, reg, 1, (uint8_t) (val))
173 #define pci_writew(devfn, reg, val) pci_write(devfn, reg, 2, (uint16_t)(val))
174 #define pci_writel(devfn, reg, val) pci_write(devfn, reg, 4, (uint32_t)(val))
175 
176 /* Get a pointer to the shared-info page */
177 struct shared_info *get_shared_info(void) __attribute__ ((const));
178 
179 /* Get CPU speed in MHz. */
180 uint16_t get_cpu_mhz(void);
181 
182 /* Hardware detection. */
183 int uart_exists(uint16_t uart_base);
184 int lpt_exists(uint16_t lpt_base);
185 int hpet_exists(unsigned long hpet_base);
186 
187 /* Do cpuid instruction, with operation 'idx' */
188 void cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx,
189            uint32_t *ecx, uint32_t *edx);
190 
191 /* Read the TSC register. */
rdtsc(void)192 static inline uint64_t rdtsc(void)
193 {
194     uint64_t tsc;
195     asm volatile ( "rdtsc" : "=A" (tsc) );
196     return tsc;
197 }
198 
199 /* Relax the CPU and let the compiler know that time passes. */
cpu_relax(void)200 static inline void cpu_relax(void)
201 {
202     asm volatile ( "rep ; nop" : : : "memory" );
203 }
204 
205 /* Memory barriers. */
206 #define barrier() asm volatile ( "" : : : "memory" )
207 #define rmb()     barrier()
208 #define wmb()     barrier()
209 #define mb()      asm volatile ( "lock addl $0, -4(%%esp)" ::: "memory" )
210 
211 /*
212  * Divide a 64-bit dividend by a 32-bit divisor.
213  * (1) Overwrites the 64-bit dividend _in_place_ with the quotient
214  * (2) Returns the 32-bit remainder
215  */
216 #define do_div(n, base) ({                                      \
217     unsigned long __upper, __low, __high, __mod, __base;        \
218     __base = (base);                                            \
219     asm ( "" : "=a" (__low), "=d" (__high) : "A" (n) );         \
220     __upper = __high;                                           \
221     if ( __high )                                               \
222     {                                                           \
223         __upper = __high % (__base);                            \
224         __high = __high / (__base);                             \
225     }                                                           \
226     asm ( "divl %2"                                             \
227           : "=a" (__low), "=d" (__mod)                          \
228           : "rm" (__base), "0" (__low), "1" (__upper) );        \
229     asm ( "" : "=A" (n) : "a" (__low), "d" (__high) );          \
230     __mod;                                                      \
231 })
232 
233 /* HVM-builder info. */
234 struct hvm_info_table *get_hvm_info_table(void) __attribute__ ((const));
235 #define hvm_info (get_hvm_info_table())
236 
237 /* HVM start info */
238 extern const struct hvm_start_info *hvm_start_info;
239 
240 /* String and memory functions */
241 int strcmp(const char *cs, const char *ct);
242 int strncmp(const char *s1, const char *s2, uint32_t n);
243 char *strcpy(char *dest, const char *src);
244 char *strncpy(char *dest, const char *src, unsigned n);
245 unsigned strlen(const char *s);
246 long long strtoll(const char *s, char **end, int base);
247 int memcmp(const void *s1, const void *s2, unsigned n);
248 void *memcpy(void *dest, const void *src, unsigned n);
249 void *memmove(void *dest, const void *src, unsigned n);
250 void *memset(void *s, int c, unsigned n);
251 char *itoa(char *a, unsigned int i);
252 
253 /* convert a byte to two lowercase hex digits, with no terminating NUL
254    character.  digits[] must have at least two elements. */
255 void byte_to_hex(char *digits, uint8_t byte);
256 
257 /* Convert an array of 16 unsigned bytes to a DCE/OSF formatted UUID
258    string. Pre-condition: sizeof(dest) >= 37 */
259 void uuid_to_string(char *dest, uint8_t *uuid);
260 
261 /* Debug output */
262 #define PRIllx "%x%08x"
263 #define PRIllx_arg(ll) (uint32_t)((ll)>>32), (uint32_t)(ll)
264 int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
265 int vprintf(const char *fmt, va_list ap);
266 
267 /* Buffer output */
268 int snprintf(char *buf, size_t size, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
269 
270 /* Populate specified memory hole with RAM. */
271 void mem_hole_populate_ram(xen_pfn_t mfn, uint32_t nr_mfns);
272 
273 /* Allocate a memory hole below 4GB. */
274 xen_pfn_t mem_hole_alloc(uint32_t nr_mfns);
275 
276 /* Allocate memory in a reserved region below 4GB. */
277 void *mem_alloc(uint32_t size, uint32_t align);
278 #define virt_to_phys(v) ((unsigned long)(v))
279 
280 /* Allocate memory in a scratch region */
281 void *scratch_alloc(uint32_t size, uint32_t align);
282 
283 /* Connect our xenbus client to the backend.
284  * Call once, before any other xenbus actions. */
285 void xenbus_setup(void);
286 
287 /* Reset the xenbus connection so the next kernel can start again. */
288 void xenbus_shutdown(void);
289 
290 /* Read a xenstore key.  Returns a nul-terminated string (even if the XS
291  * data wasn't nul-terminated) or NULL.  The returned string is in a
292  * static buffer, so only valid until the next xenstore/xenbus operation.
293  * If @default_resp is specified, it is returned in preference to a NULL or
294  * empty string received from xenstore.
295  */
296 const char *xenstore_read(const char *path, const char *default_resp);
297 
298 /* Write a xenstore key.  @value must be a nul-terminated string. Returns
299  * zero on success or a xenstore error code on failure.
300  */
301 int xenstore_write(const char *path, const char *value);
302 
303 
304 /* Get a HVM param.
305  */
306 int hvm_param_get(uint32_t index, uint64_t *value);
307 
308 /* Set a HVM param.
309  */
310 int hvm_param_set(uint32_t index, uint64_t value);
311 
312 /* Setup PCI bus */
313 void pci_setup(void);
314 
315 /* Setup memory map  */
316 void memory_map_setup(void);
317 
318 /* Sync memory map */
319 void adjust_memory_map(void);
320 
321 /* Prepare the 32bit BIOS */
322 uint32_t rombios_highbios_setup(void);
323 
324 /* Miscellaneous. */
325 unsigned int cpu_phys_addr(void);
326 void cacheattr_init(void);
327 unsigned long create_mp_tables(void *table);
328 void hvm_write_smbios_tables(
329     unsigned long ep, unsigned long smbios_start, unsigned long smbios_end);
330 unsigned long create_pir_tables(void);
331 
332 void smp_initialise(void);
333 
334 #include "e820.h"
335 int build_e820_table(struct e820entry *e820,
336                      unsigned int lowmem_reserved_base,
337                      unsigned int bios_image_base);
338 void dump_e820_table(struct e820entry *e820, unsigned int nr);
339 
340 #ifndef NDEBUG
341 void perform_tests(void);
342 #else
343 #define perform_tests() ((void)0)
344 #endif
345 
346 extern char _start[], _end[];
347 
348 int get_mem_mapping_layout(struct e820entry entries[],
349                            unsigned int *max_entries);
350 
351 extern struct e820map memory_map;
352 bool check_overlap(uint64_t start, uint64_t size,
353                    uint64_t reserved_start, uint64_t reserved_size);
354 
355 extern const unsigned char dsdt_anycpu_qemu_xen[], dsdt_anycpu[], dsdt_15cpu[];
356 extern const int dsdt_anycpu_qemu_xen_len, dsdt_anycpu_len, dsdt_15cpu_len;
357 
358 unsigned long acpi_pages_allocated(void);
359 
360 struct acpi_config;
361 void hvmloader_acpi_build_tables(struct acpi_config *config,
362                                  unsigned int physical);
363 
364 #endif /* __HVMLOADER_UTIL_H__ */
365 
366 /*
367  * Local variables:
368  * mode: C
369  * c-file-style: "BSD"
370  * c-basic-offset: 4
371  * tab-width: 4
372  * indent-tabs-mode: nil
373  * End:
374  */
375