1 #ifndef ARCH_PPC_H 2 #define ARCH_PPC_H 3 4 #include <unistd.h> 5 #include <stdlib.h> 6 #include <sys/types.h> 7 #include <sys/wait.h> 8 9 #define FIO_ARCH (arch_ppc) 10 11 #define nop do { } while (0) 12 13 #ifdef __powerpc64__ 14 #define read_barrier() __asm__ __volatile__ ("lwsync" : : : "memory") 15 #else 16 #define read_barrier() __asm__ __volatile__ ("sync" : : : "memory") 17 #endif 18 19 #define write_barrier() __asm__ __volatile__ ("sync" : : : "memory") 20 21 #ifdef __powerpc64__ 22 #define PPC_CNTLZL "cntlzd" 23 #else 24 #define PPC_CNTLZL "cntlzw" 25 #endif 26 __ilog2(unsigned long bitmask)27static inline int __ilog2(unsigned long bitmask) 28 { 29 int lz; 30 31 asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (bitmask)); 32 return BITS_PER_LONG - 1 - lz; 33 } 34 arch_ffz(unsigned long bitmask)35static inline int arch_ffz(unsigned long bitmask) 36 { 37 if ((bitmask = ~bitmask) == 0) 38 return BITS_PER_LONG; 39 return __ilog2(bitmask & -bitmask); 40 } 41 mfspr(unsigned int reg)42static inline unsigned int mfspr(unsigned int reg) 43 { 44 unsigned int val; 45 46 asm volatile("mfspr %0,%1": "=r" (val) : "K" (reg)); 47 return val; 48 } 49 50 #define SPRN_TBRL 0x10C /* Time Base Register Lower */ 51 #define SPRN_TBRU 0x10D /* Time Base Register Upper */ 52 #define SPRN_ATBL 0x20E /* Alternate Time Base Lower */ 53 #define SPRN_ATBU 0x20F /* Alternate Time Base Upper */ 54 55 #ifdef __powerpc64__ get_cpu_clock(void)56static inline unsigned long long get_cpu_clock(void) 57 { 58 unsigned long long rval; 59 60 asm volatile( 61 "90: mfspr %0, %1;\n" 62 " cmpwi %0,0;\n" 63 " beq- 90b;\n" 64 : "=r" (rval) 65 : "i" (SPRN_TBRL)); 66 67 return rval; 68 } 69 #else get_cpu_clock(void)70static inline unsigned long long get_cpu_clock(void) 71 { 72 unsigned int tbl, tbu0, tbu1; 73 unsigned long long ret; 74 75 do { 76 if (arch_flags & ARCH_FLAG_1) { 77 tbu0 = mfspr(SPRN_ATBU); 78 tbl = mfspr(SPRN_ATBL); 79 tbu1 = mfspr(SPRN_ATBU); 80 } else { 81 tbu0 = mfspr(SPRN_TBRU); 82 tbl = mfspr(SPRN_TBRL); 83 tbu1 = mfspr(SPRN_TBRU); 84 } 85 } while (tbu0 != tbu1); 86 87 ret = (((unsigned long long)tbu0) << 32) | tbl; 88 return ret; 89 } 90 #endif 91 92 #if 0 93 static void atb_child(void) 94 { 95 arch_flags |= ARCH_FLAG_1; 96 get_cpu_clock(); 97 _exit(0); 98 } 99 100 static void atb_clocktest(void) 101 { 102 pid_t pid; 103 104 pid = fork(); 105 if (!pid) 106 atb_child(); 107 else if (pid != -1) { 108 int status; 109 110 pid = wait(&status); 111 if (pid == -1 || !WIFEXITED(status)) 112 arch_flags &= ~ARCH_FLAG_1; 113 else 114 arch_flags |= ARCH_FLAG_1; 115 } 116 } 117 #endif 118 119 #define ARCH_HAVE_INIT 120 extern int tsc_reliable; 121 arch_init(char * envp[])122static inline int arch_init(char *envp[]) 123 { 124 #if 0 125 tsc_reliable = 1; 126 atb_clocktest(); 127 #endif 128 return 0; 129 } 130 131 #define ARCH_HAVE_FFZ 132 133 /* 134 * We don't have it on all platforms, lets comment this out until we 135 * can handle it more intelligently. 136 * 137 * #define ARCH_HAVE_CPU_CLOCK 138 */ 139 140 /* 141 * Let's have it defined for ppc64 142 */ 143 144 #ifdef __powerpc64__ 145 #define ARCH_HAVE_CPU_CLOCK 146 #endif 147 148 #endif 149