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 | 10 | |
ebac4655 JA |
11 | #define nop do { } while (0) |
12 | ||
db6defc7 | 13 | #ifdef __powerpc64__ |
44c47feb | 14 | #define read_barrier() __asm__ __volatile__ ("lwsync" : : : "memory") |
db6defc7 | 15 | #else |
44c47feb | 16 | #define read_barrier() __asm__ __volatile__ ("sync" : : : "memory") |
db6defc7 JA |
17 | #endif |
18 | ||
44c47feb JA |
19 | #define write_barrier() __asm__ __volatile__ ("sync" : : : "memory") |
20 | ||
92060d6c CR |
21 | #ifdef __powerpc64__ |
22 | #define PPC_CNTLZL "cntlzd" | |
23 | #else | |
24 | #define PPC_CNTLZL "cntlzw" | |
25 | #endif | |
26 | ||
8f7e39dd JA |
27 | static inline int __ilog2(unsigned long bitmask) |
28 | { | |
29 | int lz; | |
30 | ||
92060d6c CR |
31 | asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (bitmask)); |
32 | return BITS_PER_LONG - 1 - lz; | |
8f7e39dd JA |
33 | } |
34 | ||
35 | static inline int arch_ffz(unsigned long bitmask) | |
36 | { | |
37 | if ((bitmask = ~bitmask) == 0) | |
92060d6c | 38 | return BITS_PER_LONG; |
8f7e39dd JA |
39 | return __ilog2(bitmask & -bitmask); |
40 | } | |
5f39d8f7 | 41 | |
4247d1a9 JA |
42 | static 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 | ||
1c73ebea LZ |
55 | #ifdef __powerpc64__ |
56 | static 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 | |
5f39d8f7 CC |
70 | static inline unsigned long long get_cpu_clock(void) |
71 | { | |
2995607f JA |
72 | unsigned int tbl, tbu0, tbu1; |
73 | unsigned long long ret; | |
5f39d8f7 | 74 | |
2995607f | 75 | do { |
4247d1a9 JA |
76 | if (arch_flags & ARCH_FLAG_1) { |
77 | tbu0 = mfspr(SPRN_ATBU); | |
78 | tbl = mfspr(SPRN_ATBL); | |
79 | tbu1 = mfspr(SPRN_ATBU); | |
80 | } else { | |
f2dc46ad SN |
81 | tbu0 = mfspr(SPRN_TBRU); |
82 | tbl = mfspr(SPRN_TBRL); | |
83 | tbu1 = mfspr(SPRN_TBRU); | |
4247d1a9 | 84 | } |
2995607f | 85 | } while (tbu0 != tbu1); |
5f39d8f7 | 86 | |
2995607f JA |
87 | ret = (((unsigned long long)tbu0) << 32) | tbl; |
88 | return ret; | |
5f39d8f7 | 89 | } |
1c73ebea | 90 | #endif |
5f39d8f7 | 91 | |
1b4f8c7f | 92 | #if 0 |
4247d1a9 JA |
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(); | |
62443342 | 107 | else if (pid != -1) { |
4247d1a9 JA |
108 | int status; |
109 | ||
62443342 JA |
110 | pid = wait(&status); |
111 | if (pid == -1 || !WIFEXITED(status)) | |
4247d1a9 JA |
112 | arch_flags &= ~ARCH_FLAG_1; |
113 | else | |
114 | arch_flags |= ARCH_FLAG_1; | |
115 | } | |
116 | } | |
1b4f8c7f | 117 | #endif |
4247d1a9 | 118 | |
1b745f55 JA |
119 | #define ARCH_HAVE_INIT |
120 | extern int tsc_reliable; | |
4247d1a9 | 121 | |
1b745f55 JA |
122 | static inline int arch_init(char *envp[]) |
123 | { | |
ddc0cc31 | 124 | #if 0 |
1b745f55 | 125 | tsc_reliable = 1; |
4247d1a9 | 126 | atb_clocktest(); |
ddc0cc31 | 127 | #endif |
d20b2ca6 | 128 | return 0; |
1b745f55 JA |
129 | } |
130 | ||
8f7e39dd | 131 | #define ARCH_HAVE_FFZ |
d2d982d3 JA |
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 | */ | |
8f7e39dd | 139 | |
1c73ebea LZ |
140 | /* |
141 | * Let's have it defined for ppc64 | |
142 | */ | |
143 | ||
144 | #ifdef __powerpc64__ | |
145 | #define ARCH_HAVE_CPU_CLOCK | |
146 | #endif | |
147 | ||
ebac4655 | 148 | #endif |