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