1 /* $NetBSD: xen.h,v 1.26 2008/01/11 20:00:41 bouyer Exp $ */ 2 3 /* 4 * 5 * Copyright (c) 2003, 2004 Keir Fraser (on behalf of the Xen team) 6 * All rights reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to 10 * deal in the Software without restriction, including without limitation the 11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 * sell copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 * DEALINGS IN THE SOFTWARE. 25 */ 26 27 28 #ifndef _XEN_H 29 #define _XEN_H 30 #include "opt_xen.h" 31 32 33 #ifndef _LOCORE 34 35 #include <machine/cpufunc.h> 36 37 struct xen_netinfo { 38 uint32_t xi_ifno; 39 char *xi_root; 40 uint32_t xi_ip[5]; 41 }; 42 43 union xen_cmdline_parseinfo { 44 char xcp_bootdev[16]; /* sizeof(dv_xname) */ 45 struct xen_netinfo xcp_netinfo; 46 char xcp_console[16]; 47 }; 48 49 #define XEN_PARSE_BOOTDEV 0 50 #define XEN_PARSE_NETINFO 1 51 #define XEN_PARSE_CONSOLE 2 52 #define XEN_PARSE_BOOTFLAGS 3 53 54 void xen_parse_cmdline(int, union xen_cmdline_parseinfo *); 55 56 void xenconscn_attach(void); 57 58 void xenprivcmd_init(void); 59 60 void xbdback_init(void); 61 void xennetback_init(void); 62 void xen_shm_init(void); 63 64 void xenevt_event(int); 65 void xenevt_notify(void); 66 67 void idle_block(void); 68 69 #if defined(XENDEBUG) || 1 /* XXX */ 70 void printk(const char *, ...); 71 void vprintk(const char *, _BSD_VA_LIST_); 72 #endif 73 74 #endif 75 76 #endif /* _XEN_H */ 77 78 /****************************************************************************** 79 * os.h 80 * 81 * random collection of macros and definition 82 */ 83 84 #ifndef _OS_H_ 85 #define _OS_H_ 86 87 /* 88 * These are the segment descriptors provided for us by the hypervisor. 89 * For now, these are hardwired -- guest OSes cannot update the GDT 90 * or LDT. 91 * 92 * It shouldn't be hard to support descriptor-table frobbing -- let me 93 * know if the BSD or XP ports require flexibility here. 94 */ 95 96 97 /* 98 * these are also defined in xen-public/xen.h but can't be pulled in as 99 * they are used in start of day assembly. Need to clean up the .h files 100 * a bit more... 101 */ 102 103 #ifdef XEN3 104 #ifndef FLAT_RING1_CS 105 #define FLAT_RING1_CS 0xe019 /* GDT index 259 */ 106 #define FLAT_RING1_DS 0xe021 /* GDT index 260 */ 107 #define FLAT_RING1_SS 0xe021 /* GDT index 260 */ 108 #define FLAT_RING3_CS 0xe02b /* GDT index 261 */ 109 #define FLAT_RING3_DS 0xe033 /* GDT index 262 */ 110 #define FLAT_RING3_SS 0xe033 /* GDT index 262 */ 111 #endif 112 #else /* XEN3 */ 113 #ifndef FLAT_RING1_CS 114 #define FLAT_RING1_CS 0x0819 115 #define FLAT_RING1_DS 0x0821 116 #define FLAT_RING3_CS 0x082b 117 #define FLAT_RING3_DS 0x0833 118 #endif 119 #endif /* XEN3 */ 120 121 #define __KERNEL_CS FLAT_RING1_CS 122 #define __KERNEL_DS FLAT_RING1_DS 123 124 /* Everything below this point is not included by assembler (.S) files. */ 125 #ifndef _LOCORE 126 127 /* some function prototypes */ 128 void trap_init(void); 129 void xpq_flush_cache(void); 130 131 132 /* 133 * STI/CLI equivalents. These basically set and clear the virtual 134 * event_enable flag in the shared_info structure. Note that when 135 * the enable bit is set, there may be pending events to be handled. 136 * We may therefore call into do_hypervisor_callback() directly. 137 */ 138 139 #define __save_flags(x) \ 140 do { \ 141 (x) = HYPERVISOR_shared_info->vcpu_info[0].evtchn_upcall_mask; \ 142 } while (0) 143 144 #define __restore_flags(x) \ 145 do { \ 146 volatile shared_info_t *_shared = HYPERVISOR_shared_info; \ 147 __insn_barrier(); \ 148 if ((_shared->vcpu_info[0].evtchn_upcall_mask = (x)) == 0) { \ 149 x86_lfence(); \ 150 if (__predict_false(_shared->vcpu_info[0].evtchn_upcall_pending)) \ 151 hypervisor_force_callback(); \ 152 } \ 153 } while (0) 154 155 #define __cli() \ 156 do { \ 157 HYPERVISOR_shared_info->vcpu_info[0].evtchn_upcall_mask = 1; \ 158 x86_lfence(); \ 159 } while (0) 160 161 #define __sti() \ 162 do { \ 163 volatile shared_info_t *_shared = HYPERVISOR_shared_info; \ 164 __insn_barrier(); \ 165 _shared->vcpu_info[0].evtchn_upcall_mask = 0; \ 166 x86_lfence(); /* unmask then check (avoid races) */ \ 167 if (__predict_false(_shared->vcpu_info[0].evtchn_upcall_pending)) \ 168 hypervisor_force_callback(); \ 169 } while (0) 170 171 #define cli() __cli() 172 #define sti() __sti() 173 #define save_flags(x) __save_flags(x) 174 #define restore_flags(x) __restore_flags(x) 175 #define save_and_cli(x) do { \ 176 __save_flags(x); \ 177 __cli(); \ 178 } while (/* CONSTCOND */ 0) 179 #define save_and_sti(x) __save_and_sti(x) 180 181 /* 182 * always assume we're on multiprocessor. We don't know how many CPU the 183 * underlying hardware has. 184 */ 185 #define __LOCK_PREFIX "lock; " 186 187 #ifdef XEN3 188 #define XATOMIC_T long 189 #else 190 #define XATOMIC_T uint32_t 191 #endif 192 static __inline XATOMIC_T 193 xen_atomic_xchg(volatile XATOMIC_T *ptr, unsigned long val) 194 { 195 unsigned long result; 196 197 __asm volatile(__LOCK_PREFIX 198 #ifdef __x86_64__ 199 "xchgq %0,%1" 200 #else 201 "xchgl %0,%1" 202 #endif 203 :"=r" (result) 204 :"m" (*ptr), "0" (val) 205 :"memory"); 206 207 return result; 208 } 209 210 static inline uint16_t 211 xen_atomic_cmpxchg16(volatile uint16_t *ptr, uint16_t val, uint16_t newval) 212 { 213 unsigned long result; 214 215 __asm volatile(__LOCK_PREFIX 216 "cmpxchgw %w1,%2" 217 :"=a" (result) 218 :"q"(newval), "m" (*ptr), "0" (val) 219 :"memory"); 220 221 return result; 222 } 223 224 static __inline void 225 xen_atomic_setbits_l (volatile XATOMIC_T *ptr, unsigned long bits) { 226 #ifdef __x86_64__ 227 __asm volatile("lock ; orq %1,%0" : "=m" (*ptr) : "ir" (bits)); 228 #else 229 __asm volatile("lock ; orl %1,%0" : "=m" (*ptr) : "ir" (bits)); 230 #endif 231 } 232 233 static __inline void 234 xen_atomic_clearbits_l (volatile XATOMIC_T *ptr, unsigned long bits) { 235 #ifdef __x86_64__ 236 __asm volatile("lock ; andq %1,%0" : "=m" (*ptr) : "ir" (~bits)); 237 #else 238 __asm volatile("lock ; andl %1,%0" : "=m" (*ptr) : "ir" (~bits)); 239 #endif 240 } 241 242 static __inline XATOMIC_T 243 xen_atomic_test_and_clear_bit(volatile void *ptr, unsigned long bitno) 244 { 245 int result; 246 247 __asm volatile(__LOCK_PREFIX 248 #ifdef __x86_64__ 249 "btrq %2,%1 ;" 250 "sbbq %0,%0" 251 #else 252 "btrl %2,%1 ;" 253 "sbbl %0,%0" 254 #endif 255 :"=r" (result), "=m" (*(volatile XATOMIC_T *)(ptr)) 256 :"Ir" (bitno) : "memory"); 257 return result; 258 } 259 260 static __inline XATOMIC_T 261 xen_atomic_test_and_set_bit(volatile void *ptr, unsigned long bitno) 262 { 263 long result; 264 265 __asm volatile(__LOCK_PREFIX 266 #ifdef __x86_64__ 267 "btsq %2,%1 ;" 268 "sbbq %0,%0" 269 #else 270 "btsl %2,%1 ;" 271 "sbbl %0,%0" 272 #endif 273 :"=r" (result), "=m" (*(volatile XATOMIC_T *)(ptr)) 274 :"Ir" (bitno) : "memory"); 275 return result; 276 } 277 278 static __inline int 279 xen_constant_test_bit(const volatile void *ptr, unsigned long bitno) 280 { 281 return ((1UL << (bitno & 31)) & 282 (((const volatile XATOMIC_T *) ptr)[bitno >> 5])) != 0; 283 } 284 285 static __inline XATOMIC_T 286 xen_variable_test_bit(const volatile void *ptr, unsigned long bitno) 287 { 288 long result; 289 290 __asm volatile( 291 #ifdef __x86_64__ 292 "btq %2,%1 ;" 293 "sbbq %0,%0" 294 #else 295 "btl %2,%1 ;" 296 "sbbl %0,%0" 297 #endif 298 :"=r" (result) 299 :"m" (*(const volatile XATOMIC_T *)(ptr)), "Ir" (bitno)); 300 return result; 301 } 302 303 #define xen_atomic_test_bit(ptr, bitno) \ 304 (__builtin_constant_p(bitno) ? \ 305 xen_constant_test_bit((ptr),(bitno)) : \ 306 xen_variable_test_bit((ptr),(bitno))) 307 308 static __inline void 309 xen_atomic_set_bit(volatile void *ptr, unsigned long bitno) 310 { 311 __asm volatile(__LOCK_PREFIX 312 #ifdef __x86_64__ 313 "btsq %1,%0" 314 #else 315 "btsl %1,%0" 316 #endif 317 :"=m" (*(volatile XATOMIC_T *)(ptr)) 318 :"Ir" (bitno)); 319 } 320 321 static __inline void 322 xen_atomic_clear_bit(volatile void *ptr, unsigned long bitno) 323 { 324 __asm volatile(__LOCK_PREFIX 325 #ifdef __x86_64__ 326 "btrq %1,%0" 327 #else 328 "btrl %1,%0" 329 #endif 330 :"=m" (*(volatile XATOMIC_T *)(ptr)) 331 :"Ir" (bitno)); 332 } 333 334 #undef XATOMIC_T 335 336 void wbinvd(void); 337 338 #endif /* !__ASSEMBLY__ */ 339 340 #endif /* _OS_H_ */ 341