1 /****************************************************************************** 2 * amd64/xen/xen-os.h 3 * 4 * Random collection of macros and definition 5 * 6 * Copyright (c) 2003, 2004 Keir Fraser (on behalf of the Xen team) 7 * All rights reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a copy 10 * of this software and associated documentation files (the "Software"), to 11 * deal in the Software without restriction, including without limitation the 12 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 13 * sell copies of the Software, and to permit persons to whom the Software is 14 * furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included in 17 * all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 * DEALINGS IN THE SOFTWARE. 26 * 27 * $FreeBSD$ 28 */ 29 30 #ifndef _MACHINE_XEN_XEN_OS_H_ 31 #define _MACHINE_XEN_XEN_OS_H_ 32 33 #ifdef PAE 34 #define CONFIG_X86_PAE 35 #endif 36 37 /* Everything below this point is not included by assembler (.S) files. */ 38 #ifndef __ASSEMBLY__ 39 40 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ 41 static inline void rep_nop(void) 42 { 43 __asm__ __volatile__ ( "rep;nop" : : : "memory" ); 44 } 45 #define cpu_relax() rep_nop() 46 47 /* This is a barrier for the compiler only, NOT the processor! */ 48 #define barrier() __asm__ __volatile__("": : :"memory") 49 50 #define LOCK_PREFIX "" 51 #define LOCK "" 52 #define ADDR (*(volatile long *) addr) 53 54 /** 55 * test_and_clear_bit - Clear a bit and return its old value 56 * @nr: Bit to set 57 * @addr: Address to count from 58 * 59 * This operation is atomic and cannot be reordered. 60 * It also implies a memory barrier. 61 */ 62 static __inline int test_and_clear_bit(int nr, volatile void * addr) 63 { 64 int oldbit; 65 66 __asm__ __volatile__( LOCK_PREFIX 67 "btrl %2,%1\n\tsbbl %0,%0" 68 :"=r" (oldbit),"=m" (ADDR) 69 :"Ir" (nr) : "memory"); 70 return oldbit; 71 } 72 73 static __inline int constant_test_bit(int nr, const volatile void * addr) 74 { 75 return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; 76 } 77 78 static __inline int variable_test_bit(int nr, volatile void * addr) 79 { 80 int oldbit; 81 82 __asm__ __volatile__( 83 "btl %2,%1\n\tsbbl %0,%0" 84 :"=r" (oldbit) 85 :"m" (ADDR),"Ir" (nr)); 86 return oldbit; 87 } 88 89 #define test_bit(nr,addr) \ 90 (__builtin_constant_p(nr) ? \ 91 constant_test_bit((nr),(addr)) : \ 92 variable_test_bit((nr),(addr))) 93 94 /** 95 * set_bit - Atomically set a bit in memory 96 * @nr: the bit to set 97 * @addr: the address to start counting from 98 * 99 * This function is atomic and may not be reordered. See __set_bit() 100 * if you do not require the atomic guarantees. 101 * Note that @nr may be almost arbitrarily large; this function is not 102 * restricted to acting on a single-word quantity. 103 */ 104 static __inline__ void set_bit(int nr, volatile void * addr) 105 { 106 __asm__ __volatile__( LOCK_PREFIX 107 "btsl %1,%0" 108 :"=m" (ADDR) 109 :"Ir" (nr)); 110 } 111 112 /** 113 * clear_bit - Clears a bit in memory 114 * @nr: Bit to clear 115 * @addr: Address to start counting from 116 * 117 * clear_bit() is atomic and may not be reordered. However, it does 118 * not contain a memory barrier, so if it is used for locking purposes, 119 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() 120 * in order to ensure changes are visible on other processors. 121 */ 122 static __inline__ void clear_bit(int nr, volatile void * addr) 123 { 124 __asm__ __volatile__( LOCK_PREFIX 125 "btrl %1,%0" 126 :"=m" (ADDR) 127 :"Ir" (nr)); 128 } 129 130 #endif /* !__ASSEMBLY__ */ 131 132 #endif /* _MACHINE_XEN_XEN_OS_H_ */ 133