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