1 /****************************************************************************** 2 * os.h 3 * 4 * random collection of macros and definition 5 */ 6 7 #ifndef _XEN_OS_H_ 8 #define _XEN_OS_H_ 9 #include <machine/param.h> 10 11 #ifdef PAE 12 #define CONFIG_X86_PAE 13 #endif 14 15 #if defined(XEN) && !defined(__XEN_INTERFACE_VERSION__) 16 /* 17 * Can update to a more recent version when we implement 18 * the hypercall page 19 */ 20 #define __XEN_INTERFACE_VERSION__ 0x00030204 21 #endif 22 23 #include <xen/interface/xen.h> 24 25 /* Force a proper event-channel callback from Xen. */ 26 void force_evtchn_callback(void); 27 28 #define likely(x) __builtin_expect((x),1) 29 #define unlikely(x) __builtin_expect((x),0) 30 31 #ifndef vtophys 32 #include <vm/vm.h> 33 #include <vm/vm_param.h> 34 #include <vm/pmap.h> 35 #endif 36 37 #ifdef SMP 38 #include <sys/time.h> /* XXX for pcpu.h */ 39 #include <sys/pcpu.h> /* XXX for PCPU_GET */ 40 extern int gdtset; 41 static inline int 42 smp_processor_id(void) 43 { 44 if (likely(gdtset)) 45 return PCPU_GET(cpuid); 46 return 0; 47 } 48 49 #else 50 #define smp_processor_id() 0 51 #endif 52 53 #ifndef NULL 54 #define NULL (void *)0 55 #endif 56 57 #ifndef PANIC_IF 58 #define PANIC_IF(exp) if (unlikely(exp)) {printk("panic - %s: %s:%d\n",#exp, __FILE__, __LINE__); panic("%s: %s:%d", #exp, __FILE__, __LINE__);} 59 #endif 60 61 extern shared_info_t *HYPERVISOR_shared_info; 62 63 /* Somewhere in the middle of the GCC 2.96 development cycle, we implemented 64 a mechanism by which the user can annotate likely branch directions and 65 expect the blocks to be reordered appropriately. Define __builtin_expect 66 to nothing for earlier compilers. */ 67 68 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ 69 static inline void rep_nop(void) 70 { 71 __asm__ __volatile__ ( "rep;nop" : : : "memory" ); 72 } 73 #define cpu_relax() rep_nop() 74 75 76 #if __GNUC__ == 2 && __GNUC_MINOR__ < 96 77 #define __builtin_expect(x, expected_value) (x) 78 #endif 79 80 #define per_cpu(var, cpu) (pcpu_find((cpu))->pc_ ## var) 81 82 /* crude memory allocator for memory allocation early in 83 * boot 84 */ 85 void *bootmem_alloc(unsigned int size); 86 void bootmem_free(void *ptr, unsigned int size); 87 88 89 /* Everything below this point is not included by assembler (.S) files. */ 90 #ifndef __ASSEMBLY__ 91 #include <sys/types.h> 92 93 void printk(const char *fmt, ...); 94 95 /* some function prototypes */ 96 void trap_init(void); 97 98 /* 99 * STI/CLI equivalents. These basically set and clear the virtual 100 * event_enable flag in teh shared_info structure. Note that when 101 * the enable bit is set, there may be pending events to be handled. 102 * We may therefore call into do_hypervisor_callback() directly. 103 */ 104 105 106 #define __cli() \ 107 do { \ 108 vcpu_info_t *_vcpu; \ 109 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ 110 _vcpu->evtchn_upcall_mask = 1; \ 111 barrier(); \ 112 } while (0) 113 114 #define __sti() \ 115 do { \ 116 vcpu_info_t *_vcpu; \ 117 barrier(); \ 118 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ 119 _vcpu->evtchn_upcall_mask = 0; \ 120 barrier(); /* unmask then check (avoid races) */ \ 121 if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ 122 force_evtchn_callback(); \ 123 } while (0) 124 125 #define __restore_flags(x) \ 126 do { \ 127 vcpu_info_t *_vcpu; \ 128 barrier(); \ 129 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ 130 if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \ 131 barrier(); /* unmask then check (avoid races) */ \ 132 if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ 133 force_evtchn_callback(); \ 134 } \ 135 } while (0) 136 137 /* 138 * Add critical_{enter, exit}? 139 * 140 */ 141 #define __save_and_cli(x) \ 142 do { \ 143 vcpu_info_t *_vcpu; \ 144 _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \ 145 (x) = _vcpu->evtchn_upcall_mask; \ 146 _vcpu->evtchn_upcall_mask = 1; \ 147 barrier(); \ 148 } while (0) 149 150 151 #define cli() __cli() 152 #define sti() __sti() 153 #define save_flags(x) __save_flags(x) 154 #define restore_flags(x) __restore_flags(x) 155 #define save_and_cli(x) __save_and_cli(x) 156 157 #define local_irq_save(x) __save_and_cli(x) 158 #define local_irq_restore(x) __restore_flags(x) 159 #define local_irq_disable() __cli() 160 #define local_irq_enable() __sti() 161 162 #define mtx_lock_irqsave(lock, x) {local_irq_save((x)); mtx_lock_spin((lock));} 163 #define mtx_unlock_irqrestore(lock, x) {mtx_unlock_spin((lock)); local_irq_restore((x)); } 164 #define spin_lock_irqsave mtx_lock_irqsave 165 #define spin_unlock_irqrestore mtx_unlock_irqrestore 166 167 168 #ifdef SMP 169 #define smp_mb() mb() 170 #define smp_rmb() rmb() 171 #define smp_wmb() wmb() 172 #define smp_read_barrier_depends() read_barrier_depends() 173 #define set_mb(var, value) do { xchg(&var, value); } while (0) 174 #else 175 #define smp_mb() barrier() 176 #define smp_rmb() barrier() 177 #define smp_wmb() barrier() 178 #define smp_read_barrier_depends() do { } while(0) 179 #define set_mb(var, value) do { var = value; barrier(); } while (0) 180 #endif 181 182 183 /* This is a barrier for the compiler only, NOT the processor! */ 184 #define barrier() __asm__ __volatile__("": : :"memory") 185 186 #define LOCK_PREFIX "" 187 #define LOCK "" 188 #define ADDR (*(volatile long *) addr) 189 /* 190 * Make sure gcc doesn't try to be clever and move things around 191 * on us. We need to use _exactly_ the address the user gave us, 192 * not some alias that contains the same information. 193 */ 194 typedef struct { volatile int counter; } atomic_t; 195 196 197 198 #define xen_xchg(ptr,v) \ 199 ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr)))) 200 struct __xchg_dummy { unsigned long a[100]; }; 201 #define __xg(x) ((volatile struct __xchg_dummy *)(x)) 202 static __inline unsigned long __xchg(unsigned long x, volatile void * ptr, 203 int size) 204 { 205 switch (size) { 206 case 1: 207 __asm__ __volatile__("xchgb %b0,%1" 208 :"=q" (x) 209 :"m" (*__xg(ptr)), "0" (x) 210 :"memory"); 211 break; 212 case 2: 213 __asm__ __volatile__("xchgw %w0,%1" 214 :"=r" (x) 215 :"m" (*__xg(ptr)), "0" (x) 216 :"memory"); 217 break; 218 case 4: 219 __asm__ __volatile__("xchgl %0,%1" 220 :"=r" (x) 221 :"m" (*__xg(ptr)), "0" (x) 222 :"memory"); 223 break; 224 } 225 return x; 226 } 227 228 /** 229 * test_and_clear_bit - Clear a bit and return its old value 230 * @nr: Bit to set 231 * @addr: Address to count from 232 * 233 * This operation is atomic and cannot be reordered. 234 * It also implies a memory barrier. 235 */ 236 static __inline int test_and_clear_bit(int nr, volatile void * addr) 237 { 238 int oldbit; 239 240 __asm__ __volatile__( LOCK_PREFIX 241 "btrl %2,%1\n\tsbbl %0,%0" 242 :"=r" (oldbit),"=m" (ADDR) 243 :"Ir" (nr) : "memory"); 244 return oldbit; 245 } 246 247 static __inline int constant_test_bit(int nr, const volatile void * addr) 248 { 249 return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; 250 } 251 252 static __inline int variable_test_bit(int nr, volatile void * addr) 253 { 254 int oldbit; 255 256 __asm__ __volatile__( 257 "btl %2,%1\n\tsbbl %0,%0" 258 :"=r" (oldbit) 259 :"m" (ADDR),"Ir" (nr)); 260 return oldbit; 261 } 262 263 #define test_bit(nr,addr) \ 264 (__builtin_constant_p(nr) ? \ 265 constant_test_bit((nr),(addr)) : \ 266 variable_test_bit((nr),(addr))) 267 268 269 /** 270 * set_bit - Atomically set a bit in memory 271 * @nr: the bit to set 272 * @addr: the address to start counting from 273 * 274 * This function is atomic and may not be reordered. See __set_bit() 275 * if you do not require the atomic guarantees. 276 * Note that @nr may be almost arbitrarily large; this function is not 277 * restricted to acting on a single-word quantity. 278 */ 279 static __inline__ void set_bit(int nr, volatile void * addr) 280 { 281 __asm__ __volatile__( LOCK_PREFIX 282 "btsl %1,%0" 283 :"=m" (ADDR) 284 :"Ir" (nr)); 285 } 286 287 /** 288 * clear_bit - Clears a bit in memory 289 * @nr: Bit to clear 290 * @addr: Address to start counting from 291 * 292 * clear_bit() is atomic and may not be reordered. However, it does 293 * not contain a memory barrier, so if it is used for locking purposes, 294 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() 295 * in order to ensure changes are visible on other processors. 296 */ 297 static __inline__ void clear_bit(int nr, volatile void * addr) 298 { 299 __asm__ __volatile__( LOCK_PREFIX 300 "btrl %1,%0" 301 :"=m" (ADDR) 302 :"Ir" (nr)); 303 } 304 305 /** 306 * atomic_inc - increment atomic variable 307 * @v: pointer of type atomic_t 308 * 309 * Atomically increments @v by 1. Note that the guaranteed 310 * useful range of an atomic_t is only 24 bits. 311 */ 312 static __inline__ void atomic_inc(atomic_t *v) 313 { 314 __asm__ __volatile__( 315 LOCK "incl %0" 316 :"=m" (v->counter) 317 :"m" (v->counter)); 318 } 319 320 321 #define rdtscll(val) \ 322 __asm__ __volatile__("rdtsc" : "=A" (val)) 323 324 325 326 /* 327 * Kernel pointers have redundant information, so we can use a 328 * scheme where we can return either an error code or a dentry 329 * pointer with the same return value. 330 * 331 * This should be a per-architecture thing, to allow different 332 * error and pointer decisions. 333 */ 334 #define IS_ERR_VALUE(x) unlikely((x) > (unsigned long)-1000L) 335 336 static inline void *ERR_PTR(long error) 337 { 338 return (void *) error; 339 } 340 341 static inline long PTR_ERR(const void *ptr) 342 { 343 return (long) ptr; 344 } 345 346 static inline long IS_ERR(const void *ptr) 347 { 348 return IS_ERR_VALUE((unsigned long)ptr); 349 } 350 351 #endif /* !__ASSEMBLY__ */ 352 353 #endif /* _OS_H_ */ 354