1 /* $NetBSD: xen.h,v 1.30 2008/10/21 15:46:32 cegger 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_setipending(int, int); 66 void xenevt_notify(void); 67 68 void idle_block(void); 69 70 #if defined(XENDEBUG) || 1 /* XXX */ 71 void printk(const char *, ...); 72 void vprintk(const char *, _BSD_VA_LIST_); 73 #endif 74 75 #endif 76 77 #endif /* _XEN_H */ 78 79 /****************************************************************************** 80 * os.h 81 * 82 * random collection of macros and definition 83 */ 84 85 #ifndef _OS_H_ 86 #define _OS_H_ 87 88 /* 89 * These are the segment descriptors provided for us by the hypervisor. 90 * For now, these are hardwired -- guest OSes cannot update the GDT 91 * or LDT. 92 * 93 * It shouldn't be hard to support descriptor-table frobbing -- let me 94 * know if the BSD or XP ports require flexibility here. 95 */ 96 97 98 /* 99 * these are also defined in xen-public/xen.h but can't be pulled in as 100 * they are used in start of day assembly. Need to clean up the .h files 101 * a bit more... 102 */ 103 104 #ifdef XEN3 105 #ifndef FLAT_RING1_CS 106 #define FLAT_RING1_CS 0xe019 /* GDT index 259 */ 107 #define FLAT_RING1_DS 0xe021 /* GDT index 260 */ 108 #define FLAT_RING1_SS 0xe021 /* GDT index 260 */ 109 #define FLAT_RING3_CS 0xe02b /* GDT index 261 */ 110 #define FLAT_RING3_DS 0xe033 /* GDT index 262 */ 111 #define FLAT_RING3_SS 0xe033 /* GDT index 262 */ 112 #endif 113 #else /* XEN3 */ 114 #ifndef FLAT_RING1_CS 115 #define FLAT_RING1_CS 0x0819 116 #define FLAT_RING1_DS 0x0821 117 #define FLAT_RING3_CS 0x082b 118 #define FLAT_RING3_DS 0x0833 119 #endif 120 #endif /* XEN3 */ 121 122 #define __KERNEL_CS FLAT_RING1_CS 123 #define __KERNEL_DS FLAT_RING1_DS 124 125 /* Everything below this point is not included by assembler (.S) files. */ 126 #ifndef _LOCORE 127 128 /* some function prototypes */ 129 void trap_init(void); 130 void xpq_flush_cache(void); 131 132 #define xendomain_is_dom0() (xen_start_info.flags & SIF_INITDOMAIN) 133 #define xendomain_is_privileged() (xen_start_info.flags & SIF_PRIVILEGED) 134 135 /* 136 * STI/CLI equivalents. These basically set and clear the virtual 137 * event_enable flag in the shared_info structure. Note that when 138 * the enable bit is set, there may be pending events to be handled. 139 * We may therefore call into do_hypervisor_callback() directly. 140 */ 141 142 #define __save_flags(x) \ 143 do { \ 144 (x) = curcpu()->ci_vcpu->evtchn_upcall_mask; \ 145 } while (0) 146 147 #define __restore_flags(x) \ 148 do { \ 149 volatile struct vcpu_info *_vci = curcpu()->ci_vcpu; \ 150 __insn_barrier(); \ 151 if ((_vci->evtchn_upcall_mask = (x)) == 0) { \ 152 x86_lfence(); \ 153 if (__predict_false(_vci->evtchn_upcall_pending)) \ 154 hypervisor_force_callback(); \ 155 } \ 156 } while (0) 157 158 #define __cli() \ 159 do { \ 160 curcpu()->ci_vcpu->evtchn_upcall_mask = 1; \ 161 x86_lfence(); \ 162 } while (0) 163 164 #define __sti() \ 165 do { \ 166 volatile struct vcpu_info *_vci = curcpu()->ci_vcpu; \ 167 __insn_barrier(); \ 168 _vci->evtchn_upcall_mask = 0; \ 169 x86_lfence(); /* unmask then check (avoid races) */ \ 170 if (__predict_false(_vci->evtchn_upcall_pending)) \ 171 hypervisor_force_callback(); \ 172 } while (0) 173 174 #define cli() __cli() 175 #define sti() __sti() 176 #define save_flags(x) __save_flags(x) 177 #define restore_flags(x) __restore_flags(x) 178 #define save_and_cli(x) do { \ 179 __save_flags(x); \ 180 __cli(); \ 181 } while (/* CONSTCOND */ 0) 182 #define save_and_sti(x) __save_and_sti(x) 183 184 /* 185 * always assume we're on multiprocessor. We don't know how many CPU the 186 * underlying hardware has. 187 */ 188 #define __LOCK_PREFIX "lock; " 189 190 #ifdef XEN3 191 #define XATOMIC_T u_long 192 #ifdef __x86_64__ 193 #define LONG_SHIFT 6 194 #define LONG_MASK 63 195 #else /* __x86_64__ */ 196 #define LONG_SHIFT 5 197 #define LONG_MASK 31 198 #endif /* __x86_64__ */ 199 #else /* XEN3 */ 200 #define XATOMIC_T uint32_t 201 #define LONG_SHIFT 5 202 #define LONG_MASK 31 203 #endif /* XEN3 */ 204 205 #define xen_ffs __builtin_ffsl 206 207 static __inline XATOMIC_T 208 xen_atomic_xchg(volatile XATOMIC_T *ptr, unsigned long val) 209 { 210 unsigned long result; 211 212 __asm volatile(__LOCK_PREFIX 213 #ifdef __x86_64__ 214 "xchgq %0,%1" 215 #else 216 "xchgl %0,%1" 217 #endif 218 :"=r" (result) 219 :"m" (*ptr), "0" (val) 220 :"memory"); 221 222 return result; 223 } 224 225 static inline uint16_t 226 xen_atomic_cmpxchg16(volatile uint16_t *ptr, uint16_t val, uint16_t newval) 227 { 228 unsigned long result; 229 230 __asm volatile(__LOCK_PREFIX 231 "cmpxchgw %w1,%2" 232 :"=a" (result) 233 :"q"(newval), "m" (*ptr), "0" (val) 234 :"memory"); 235 236 return result; 237 } 238 239 static __inline void 240 xen_atomic_setbits_l (volatile XATOMIC_T *ptr, unsigned long bits) { 241 #ifdef __x86_64__ 242 __asm volatile("lock ; orq %1,%0" : "=m" (*ptr) : "ir" (bits)); 243 #else 244 __asm volatile("lock ; orl %1,%0" : "=m" (*ptr) : "ir" (bits)); 245 #endif 246 } 247 248 static __inline void 249 xen_atomic_clearbits_l (volatile XATOMIC_T *ptr, unsigned long bits) { 250 #ifdef __x86_64__ 251 __asm volatile("lock ; andq %1,%0" : "=m" (*ptr) : "ir" (~bits)); 252 #else 253 __asm volatile("lock ; andl %1,%0" : "=m" (*ptr) : "ir" (~bits)); 254 #endif 255 } 256 257 static __inline XATOMIC_T 258 xen_atomic_test_and_clear_bit(volatile void *ptr, unsigned long bitno) 259 { 260 int result; 261 262 __asm volatile(__LOCK_PREFIX 263 #ifdef __x86_64__ 264 "btrq %2,%1 ;" 265 "sbbq %0,%0" 266 #else 267 "btrl %2,%1 ;" 268 "sbbl %0,%0" 269 #endif 270 :"=r" (result), "=m" (*(volatile XATOMIC_T *)(ptr)) 271 :"Ir" (bitno) : "memory"); 272 return result; 273 } 274 275 static __inline XATOMIC_T 276 xen_atomic_test_and_set_bit(volatile void *ptr, unsigned long bitno) 277 { 278 long result; 279 280 __asm volatile(__LOCK_PREFIX 281 #ifdef __x86_64__ 282 "btsq %2,%1 ;" 283 "sbbq %0,%0" 284 #else 285 "btsl %2,%1 ;" 286 "sbbl %0,%0" 287 #endif 288 :"=r" (result), "=m" (*(volatile XATOMIC_T *)(ptr)) 289 :"Ir" (bitno) : "memory"); 290 return result; 291 } 292 293 static __inline int 294 xen_constant_test_bit(const volatile void *ptr, unsigned long bitno) 295 { 296 return ((1UL << (bitno & LONG_MASK)) & 297 (((const volatile XATOMIC_T *) ptr)[bitno >> LONG_SHIFT])) != 0; 298 } 299 300 static __inline XATOMIC_T 301 xen_variable_test_bit(const volatile void *ptr, unsigned long bitno) 302 { 303 long result; 304 305 __asm volatile( 306 #ifdef __x86_64__ 307 "btq %2,%1 ;" 308 "sbbq %0,%0" 309 #else 310 "btl %2,%1 ;" 311 "sbbl %0,%0" 312 #endif 313 :"=r" (result) 314 :"m" (*(const volatile XATOMIC_T *)(ptr)), "Ir" (bitno)); 315 return result; 316 } 317 318 #define xen_atomic_test_bit(ptr, bitno) \ 319 (__builtin_constant_p(bitno) ? \ 320 xen_constant_test_bit((ptr),(bitno)) : \ 321 xen_variable_test_bit((ptr),(bitno))) 322 323 static __inline void 324 xen_atomic_set_bit(volatile void *ptr, unsigned long bitno) 325 { 326 __asm volatile(__LOCK_PREFIX 327 #ifdef __x86_64__ 328 "btsq %1,%0" 329 #else 330 "btsl %1,%0" 331 #endif 332 :"=m" (*(volatile XATOMIC_T *)(ptr)) 333 :"Ir" (bitno)); 334 } 335 336 static __inline void 337 xen_atomic_clear_bit(volatile void *ptr, unsigned long bitno) 338 { 339 __asm volatile(__LOCK_PREFIX 340 #ifdef __x86_64__ 341 "btrq %1,%0" 342 #else 343 "btrl %1,%0" 344 #endif 345 :"=m" (*(volatile XATOMIC_T *)(ptr)) 346 :"Ir" (bitno)); 347 } 348 349 #undef XATOMIC_T 350 351 void wbinvd(void); 352 353 #endif /* !__ASSEMBLY__ */ 354 355 #endif /* _OS_H_ */ 356