1 /* $NetBSD: xen.h,v 1.7 2004/05/07 15:51:04 cl 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 31 #ifndef _LOCORE 32 33 struct xen_netinfo { 34 uint32_t xi_ifno; 35 char *xi_root; 36 uint32_t xi_ip[5]; 37 }; 38 39 union xen_cmdline_parseinfo { 40 char xcp_bootdev[16]; /* sizeof(dv_xname) */ 41 struct xen_netinfo xcp_netinfo; 42 char xcp_console[16]; 43 }; 44 45 #define XEN_PARSE_BOOTDEV 0 46 #define XEN_PARSE_NETINFO 1 47 #define XEN_PARSE_CONSOLE 2 48 49 void xen_parse_cmdline(int, union xen_cmdline_parseinfo *); 50 51 void xenconscn_attach(void); 52 53 void xenmachmem_init(void); 54 void xenprivcmd_init(void); 55 void xenvfr_init(void); 56 57 typedef uint16_t u16; 58 typedef uint32_t u32; 59 typedef uint64_t u64; 60 61 #ifdef XENDEBUG 62 void printk(const char *, ...); 63 void vprintk(const char *, va_list); 64 #endif 65 66 #endif 67 68 #define hypervisor_asm_ack(num) \ 69 movl HYPERVISOR_shared_info,%eax ;\ 70 lock ;\ 71 btsl $num,EVENTS_MASK(%eax) 72 73 #endif /* _XEN_H */ 74 75 /****************************************************************************** 76 * os.h 77 * 78 * random collection of macros and definition 79 */ 80 81 #ifndef _OS_H_ 82 #define _OS_H_ 83 84 /* 85 * These are the segment descriptors provided for us by the hypervisor. 86 * For now, these are hardwired -- guest OSes cannot update the GDT 87 * or LDT. 88 * 89 * It shouldn't be hard to support descriptor-table frobbing -- let me 90 * know if the BSD or XP ports require flexibility here. 91 */ 92 93 94 /* 95 * these are also defined in hypervisor-if.h but can't be pulled in as 96 * they are used in start of day assembly. Need to clean up the .h files 97 * a bit more... 98 */ 99 100 #ifndef FLAT_RING1_CS 101 #define FLAT_RING1_CS 0x0819 102 #define FLAT_RING1_DS 0x0821 103 #define FLAT_RING3_CS 0x082b 104 #define FLAT_RING3_DS 0x0833 105 #endif 106 107 #define __KERNEL_CS FLAT_RING1_CS 108 #define __KERNEL_DS FLAT_RING1_DS 109 110 /* Everything below this point is not included by assembler (.S) files. */ 111 #ifndef _LOCORE 112 113 #include <machine/hypervisor-ifs/hypervisor-if.h> 114 115 /* some function prototypes */ 116 void trap_init(void); 117 118 119 /* 120 * STI/CLI equivalents. These basically set and clear the virtual 121 * event_enable flag in teh shared_info structure. Note that when 122 * the enable bit is set, there may be pending events to be handled. 123 * We may therefore call into do_hypervisor_callback() directly. 124 */ 125 #define unlikely(x) __builtin_expect((x),0) 126 #define __save_flags(x) \ 127 do { \ 128 (x) = test_bit(EVENTS_MASTER_ENABLE_BIT, \ 129 &HYPERVISOR_shared_info->events_mask); \ 130 barrier(); \ 131 } while (0) 132 133 #define __restore_flags(x) \ 134 do { \ 135 shared_info_t *_shared = HYPERVISOR_shared_info; \ 136 if (x) set_bit(EVENTS_MASTER_ENABLE_BIT, &_shared->events_mask); \ 137 barrier(); \ 138 } while (0) 139 /* if ( unlikely(_shared->events) && (x) ) do_hypervisor_callback(NULL); \ */ 140 141 #define __cli() \ 142 do { \ 143 clear_bit(EVENTS_MASTER_ENABLE_BIT, &HYPERVISOR_shared_info->events_mask);\ 144 barrier(); \ 145 } while (0) 146 147 #define __sti() \ 148 do { \ 149 shared_info_t *_shared = HYPERVISOR_shared_info; \ 150 set_bit(EVENTS_MASTER_ENABLE_BIT, &_shared->events_mask); \ 151 barrier(); \ 152 } while (0) 153 /* if ( unlikely(_shared->events) ) do_hypervisor_callback(NULL); \ */ 154 #define cli() __cli() 155 #define sti() __sti() 156 #define save_flags(x) __save_flags(x) 157 #define restore_flags(x) __restore_flags(x) 158 #define save_and_cli(x) __save_and_cli(x) 159 #define save_and_sti(x) __save_and_sti(x) 160 161 162 163 /* This is a barrier for the compiler only, NOT the processor! */ 164 #define barrier() __asm__ __volatile__("": : :"memory") 165 166 #define __LOCK_PREFIX "" 167 #define __LOCK "" 168 #define __ADDR (*(volatile long *) addr) 169 /* 170 * Make sure gcc doesn't try to be clever and move things around 171 * on us. We need to use _exactly_ the address the user gave us, 172 * not some alias that contains the same information. 173 */ 174 typedef struct { volatile int counter; } atomic_t; 175 176 177 #define xchg(ptr,v) \ 178 ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr)))) 179 struct __xchg_dummy { unsigned long a[100]; }; 180 #define __xg(x) ((struct __xchg_dummy *)(x)) 181 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, 182 int size) 183 { 184 switch (size) { 185 case 1: 186 __asm__ __volatile__("xchgb %b0,%1" 187 :"=q" (x) 188 :"m" (*__xg(ptr)), "0" (x) 189 :"memory"); 190 break; 191 case 2: 192 __asm__ __volatile__("xchgw %w0,%1" 193 :"=r" (x) 194 :"m" (*__xg(ptr)), "0" (x) 195 :"memory"); 196 break; 197 case 4: 198 __asm__ __volatile__("xchgl %0,%1" 199 :"=r" (x) 200 :"m" (*__xg(ptr)), "0" (x) 201 :"memory"); 202 break; 203 } 204 return x; 205 } 206 207 /** 208 * test_and_clear_bit - Clear a bit and return its old value 209 * @nr: Bit to set 210 * @addr: Address to count from 211 * 212 * This operation is atomic and cannot be reordered. 213 * It also implies a memory barrier. 214 */ 215 static __inline__ int test_and_clear_bit(int nr, volatile void * addr) 216 { 217 int oldbit; 218 219 __asm__ __volatile__( __LOCK_PREFIX 220 "btrl %2,%1\n\tsbbl %0,%0" 221 :"=r" (oldbit),"=m" (__ADDR) 222 :"Ir" (nr) : "memory"); 223 return oldbit; 224 } 225 226 static __inline__ int constant_test_bit(int nr, const volatile void * addr) 227 { 228 return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; 229 } 230 231 static __inline__ int variable_test_bit(int nr, volatile void * addr) 232 { 233 int oldbit; 234 235 __asm__ __volatile__( 236 "btl %2,%1\n\tsbbl %0,%0" 237 :"=r" (oldbit) 238 :"m" (__ADDR),"Ir" (nr)); 239 return oldbit; 240 } 241 242 #define test_bit(nr,addr) \ 243 (__builtin_constant_p(nr) ? \ 244 constant_test_bit((nr),(addr)) : \ 245 variable_test_bit((nr),(addr))) 246 247 248 /** 249 * set_bit - Atomically set a bit in memory 250 * @nr: the bit to set 251 * @addr: the address to start counting from 252 * 253 * This function is atomic and may not be reordered. See __set_bit() 254 * if you do not require the atomic guarantees. 255 * Note that @nr may be almost arbitrarily large; this function is not 256 * restricted to acting on a single-word quantity. 257 */ 258 static __inline__ void set_bit(int nr, volatile void * addr) 259 { 260 __asm__ __volatile__( __LOCK_PREFIX 261 "btsl %1,%0" 262 :"=m" (__ADDR) 263 :"Ir" (nr)); 264 } 265 266 /** 267 * clear_bit - Clears a bit in memory 268 * @nr: Bit to clear 269 * @addr: Address to start counting from 270 * 271 * clear_bit() is atomic and may not be reordered. However, it does 272 * not contain a memory barrier, so if it is used for locking purposes, 273 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() 274 * in order to ensure changes are visible on other processors. 275 */ 276 static __inline__ void clear_bit(int nr, volatile void * addr) 277 { 278 __asm__ __volatile__( __LOCK_PREFIX 279 "btrl %1,%0" 280 :"=m" (__ADDR) 281 :"Ir" (nr)); 282 } 283 284 /** 285 * atomic_inc - increment atomic variable 286 * @v: pointer of type atomic_t 287 * 288 * Atomically increments @v by 1. Note that the guaranteed 289 * useful range of an atomic_t is only 24 bits. 290 */ 291 static __inline__ void atomic_inc(atomic_t *v) 292 { 293 __asm__ __volatile__( 294 __LOCK "incl %0" 295 :"=m" (v->counter) 296 :"m" (v->counter)); 297 } 298 299 300 #define rdtscll(val) \ 301 __asm__ __volatile__("rdtsc" : "=A" (val)) 302 303 304 #endif /* !__ASSEMBLY__ */ 305 306 #endif /* _OS_H_ */ 307