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 | ||
deda87e3 MM |
27 | #define ARCH_HAVE_IOURING |
28 | ||
29 | #ifndef __NR_sys_io_uring_setup | |
30 | #define __NR_sys_io_uring_setup 425 | |
31 | #endif | |
32 | #ifndef __NR_sys_io_uring_enter | |
33 | #define __NR_sys_io_uring_enter 426 | |
34 | #endif | |
35 | #ifndef __NR_sys_io_uring_register | |
36 | #define __NR_sys_io_uring_register 427 | |
37 | #endif | |
38 | ||
8f7e39dd JA |
39 | static inline int __ilog2(unsigned long bitmask) |
40 | { | |
41 | int lz; | |
42 | ||
92060d6c CR |
43 | asm (PPC_CNTLZL " %0,%1" : "=r" (lz) : "r" (bitmask)); |
44 | return BITS_PER_LONG - 1 - lz; | |
8f7e39dd JA |
45 | } |
46 | ||
47 | static inline int arch_ffz(unsigned long bitmask) | |
48 | { | |
49 | if ((bitmask = ~bitmask) == 0) | |
92060d6c | 50 | return BITS_PER_LONG; |
8f7e39dd JA |
51 | return __ilog2(bitmask & -bitmask); |
52 | } | |
5f39d8f7 | 53 | |
4247d1a9 JA |
54 | static inline unsigned int mfspr(unsigned int reg) |
55 | { | |
56 | unsigned int val; | |
57 | ||
58 | asm volatile("mfspr %0,%1": "=r" (val) : "K" (reg)); | |
59 | return val; | |
60 | } | |
61 | ||
62 | #define SPRN_TBRL 0x10C /* Time Base Register Lower */ | |
63 | #define SPRN_TBRU 0x10D /* Time Base Register Upper */ | |
64 | #define SPRN_ATBL 0x20E /* Alternate Time Base Lower */ | |
65 | #define SPRN_ATBU 0x20F /* Alternate Time Base Upper */ | |
66 | ||
1c73ebea LZ |
67 | #ifdef __powerpc64__ |
68 | static inline unsigned long long get_cpu_clock(void) | |
69 | { | |
70 | unsigned long long rval; | |
71 | ||
72 | asm volatile( | |
73 | "90: mfspr %0, %1;\n" | |
74 | " cmpwi %0,0;\n" | |
75 | " beq- 90b;\n" | |
76 | : "=r" (rval) | |
e8bf784a OH |
77 | : "i" (SPRN_TBRL) |
78 | : "cr0"); | |
1c73ebea LZ |
79 | |
80 | return rval; | |
81 | } | |
82 | #else | |
5f39d8f7 CC |
83 | static inline unsigned long long get_cpu_clock(void) |
84 | { | |
2995607f JA |
85 | unsigned int tbl, tbu0, tbu1; |
86 | unsigned long long ret; | |
5f39d8f7 | 87 | |
2995607f | 88 | do { |
4247d1a9 JA |
89 | if (arch_flags & ARCH_FLAG_1) { |
90 | tbu0 = mfspr(SPRN_ATBU); | |
91 | tbl = mfspr(SPRN_ATBL); | |
92 | tbu1 = mfspr(SPRN_ATBU); | |
93 | } else { | |
f2dc46ad SN |
94 | tbu0 = mfspr(SPRN_TBRU); |
95 | tbl = mfspr(SPRN_TBRL); | |
96 | tbu1 = mfspr(SPRN_TBRU); | |
4247d1a9 | 97 | } |
2995607f | 98 | } while (tbu0 != tbu1); |
5f39d8f7 | 99 | |
2995607f JA |
100 | ret = (((unsigned long long)tbu0) << 32) | tbl; |
101 | return ret; | |
5f39d8f7 | 102 | } |
1c73ebea | 103 | #endif |
5f39d8f7 | 104 | |
1b4f8c7f | 105 | #if 0 |
4247d1a9 JA |
106 | static void atb_child(void) |
107 | { | |
108 | arch_flags |= ARCH_FLAG_1; | |
109 | get_cpu_clock(); | |
110 | _exit(0); | |
111 | } | |
112 | ||
113 | static void atb_clocktest(void) | |
114 | { | |
115 | pid_t pid; | |
116 | ||
117 | pid = fork(); | |
118 | if (!pid) | |
119 | atb_child(); | |
62443342 | 120 | else if (pid != -1) { |
4247d1a9 JA |
121 | int status; |
122 | ||
62443342 JA |
123 | pid = wait(&status); |
124 | if (pid == -1 || !WIFEXITED(status)) | |
4247d1a9 JA |
125 | arch_flags &= ~ARCH_FLAG_1; |
126 | else | |
127 | arch_flags |= ARCH_FLAG_1; | |
128 | } | |
129 | } | |
1b4f8c7f | 130 | #endif |
4247d1a9 | 131 | |
1b745f55 | 132 | #define ARCH_HAVE_INIT |
24575392 | 133 | extern bool tsc_reliable; |
4247d1a9 | 134 | |
1b745f55 JA |
135 | static inline int arch_init(char *envp[]) |
136 | { | |
ddc0cc31 | 137 | #if 0 |
24575392 | 138 | tsc_reliable = true; |
4247d1a9 | 139 | atb_clocktest(); |
ddc0cc31 | 140 | #endif |
d20b2ca6 | 141 | return 0; |
1b745f55 JA |
142 | } |
143 | ||
8f7e39dd | 144 | #define ARCH_HAVE_FFZ |
d2d982d3 JA |
145 | |
146 | /* | |
147 | * We don't have it on all platforms, lets comment this out until we | |
148 | * can handle it more intelligently. | |
149 | * | |
150 | * #define ARCH_HAVE_CPU_CLOCK | |
151 | */ | |
8f7e39dd | 152 | |
1c73ebea LZ |
153 | /* |
154 | * Let's have it defined for ppc64 | |
155 | */ | |
156 | ||
157 | #ifdef __powerpc64__ | |
158 | #define ARCH_HAVE_CPU_CLOCK | |
159 | #endif | |
160 | ||
ebac4655 | 161 | #endif |