diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 22:34:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 22:34:12 -0400 |
commit | 08351fc6a75731226e1112fc7254542bd3a2912e (patch) | |
tree | 8b25bd168e0663c766f0332c8be082aa7d6ed265 /arch/tile/include | |
parent | 0df0914d414a504b975f3cc66ace0c16ef55b7f3 (diff) | |
parent | 0dccb0489f9a5a13a33e828ab965aa49685d12f8 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: (27 commits)
arch/tile: support newer binutils assembler shift semantics
arch/tile: fix deadlock bugs in rwlock implementation
drivers/edac: provide support for tile architecture
tile on-chip network driver: sync up with latest fixes
arch/tile: support 4KB page size as well as 64KB
arch/tile: add some more VMSPLIT options and use consistent naming
arch/tile: fix some comments and whitespace
arch/tile: export some additional module symbols
arch/tile: enhance existing finv_buffer_remote() routine
arch/tile: fix two bugs in the backtracer code
arch/tile: use extended assembly to inline __mb_incoherent()
arch/tile: use a cleaner technique to enable interrupt for cpu_idle()
arch/tile: sync up with <arch/sim.h> and <arch/sim_def.h> changes
arch/tile: fix reversed test of strict_strtol() return value
arch/tile: avoid a simulator warning during bootup
arch/tile: export <asm/hardwall.h> to userspace
arch/tile: warn and retry if an IPI is not accepted by the target cpu
arch/tile: stop disabling INTCTRL_1 interrupts during hypervisor downcalls
arch/tile: fix __ndelay etc to work better
arch/tile: bug fix: exec'ed task thought it was still single-stepping
...
Fix up trivial conflict in arch/tile/kernel/vmlinux.lds.S (percpu
alignment vs section naming convention fix)
Diffstat (limited to 'arch/tile/include')
24 files changed, 265 insertions, 195 deletions
diff --git a/arch/tile/include/arch/interrupts_32.h b/arch/tile/include/arch/interrupts_32.h index 9d0bfa7e59be..96b5710505b6 100644 --- a/arch/tile/include/arch/interrupts_32.h +++ b/arch/tile/include/arch/interrupts_32.h | |||
@@ -16,10 +16,11 @@ | |||
16 | #define __ARCH_INTERRUPTS_H__ | 16 | #define __ARCH_INTERRUPTS_H__ |
17 | 17 | ||
18 | /** Mask for an interrupt. */ | 18 | /** Mask for an interrupt. */ |
19 | #ifdef __ASSEMBLER__ | ||
20 | /* Note: must handle breaking interrupts into high and low words manually. */ | 19 | /* Note: must handle breaking interrupts into high and low words manually. */ |
21 | #define INT_MASK(intno) (1 << (intno)) | 20 | #define INT_MASK_LO(intno) (1 << (intno)) |
22 | #else | 21 | #define INT_MASK_HI(intno) (1 << ((intno) - 32)) |
22 | |||
23 | #ifndef __ASSEMBLER__ | ||
23 | #define INT_MASK(intno) (1ULL << (intno)) | 24 | #define INT_MASK(intno) (1ULL << (intno)) |
24 | #endif | 25 | #endif |
25 | 26 | ||
@@ -89,6 +90,7 @@ | |||
89 | 90 | ||
90 | #define NUM_INTERRUPTS 49 | 91 | #define NUM_INTERRUPTS 49 |
91 | 92 | ||
93 | #ifndef __ASSEMBLER__ | ||
92 | #define QUEUED_INTERRUPTS ( \ | 94 | #define QUEUED_INTERRUPTS ( \ |
93 | INT_MASK(INT_MEM_ERROR) | \ | 95 | INT_MASK(INT_MEM_ERROR) | \ |
94 | INT_MASK(INT_DMATLB_MISS) | \ | 96 | INT_MASK(INT_DMATLB_MISS) | \ |
@@ -301,4 +303,5 @@ | |||
301 | INT_MASK(INT_DOUBLE_FAULT) | \ | 303 | INT_MASK(INT_DOUBLE_FAULT) | \ |
302 | INT_MASK(INT_AUX_PERF_COUNT) | \ | 304 | INT_MASK(INT_AUX_PERF_COUNT) | \ |
303 | 0) | 305 | 0) |
306 | #endif /* !__ASSEMBLER__ */ | ||
304 | #endif /* !__ARCH_INTERRUPTS_H__ */ | 307 | #endif /* !__ARCH_INTERRUPTS_H__ */ |
diff --git a/arch/tile/include/arch/sim.h b/arch/tile/include/arch/sim.h index 74b7c1624d34..e54b7b0527f3 100644 --- a/arch/tile/include/arch/sim.h +++ b/arch/tile/include/arch/sim.h | |||
@@ -152,16 +152,33 @@ sim_dump(unsigned int mask) | |||
152 | /** | 152 | /** |
153 | * Print a string to the simulator stdout. | 153 | * Print a string to the simulator stdout. |
154 | * | 154 | * |
155 | * @param str The string to be written; a newline is automatically added. | 155 | * @param str The string to be written. |
156 | */ | ||
157 | static __inline void | ||
158 | sim_print(const char* str) | ||
159 | { | ||
160 | for ( ; *str != '\0'; str++) | ||
161 | { | ||
162 | __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC | | ||
163 | (*str << _SIM_CONTROL_OPERATOR_BITS)); | ||
164 | } | ||
165 | __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC | | ||
166 | (SIM_PUTC_FLUSH_BINARY << _SIM_CONTROL_OPERATOR_BITS)); | ||
167 | } | ||
168 | |||
169 | |||
170 | /** | ||
171 | * Print a string to the simulator stdout. | ||
172 | * | ||
173 | * @param str The string to be written (a newline is automatically added). | ||
156 | */ | 174 | */ |
157 | static __inline void | 175 | static __inline void |
158 | sim_print_string(const char* str) | 176 | sim_print_string(const char* str) |
159 | { | 177 | { |
160 | int i; | 178 | for ( ; *str != '\0'; str++) |
161 | for (i = 0; str[i] != 0; i++) | ||
162 | { | 179 | { |
163 | __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC | | 180 | __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC | |
164 | (str[i] << _SIM_CONTROL_OPERATOR_BITS)); | 181 | (*str << _SIM_CONTROL_OPERATOR_BITS)); |
165 | } | 182 | } |
166 | __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC | | 183 | __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_PUTC | |
167 | (SIM_PUTC_FLUSH_STRING << _SIM_CONTROL_OPERATOR_BITS)); | 184 | (SIM_PUTC_FLUSH_STRING << _SIM_CONTROL_OPERATOR_BITS)); |
@@ -203,7 +220,7 @@ sim_command(const char* str) | |||
203 | * we are passing to the simulator are actually valid in the registers | 220 | * we are passing to the simulator are actually valid in the registers |
204 | * (i.e. returned from memory) prior to the SIM_CONTROL spr. | 221 | * (i.e. returned from memory) prior to the SIM_CONTROL spr. |
205 | */ | 222 | */ |
206 | static __inline int _sim_syscall0(int val) | 223 | static __inline long _sim_syscall0(int val) |
207 | { | 224 | { |
208 | long result; | 225 | long result; |
209 | __asm__ __volatile__ ("mtspr SIM_CONTROL, r0" | 226 | __asm__ __volatile__ ("mtspr SIM_CONTROL, r0" |
@@ -211,7 +228,7 @@ static __inline int _sim_syscall0(int val) | |||
211 | return result; | 228 | return result; |
212 | } | 229 | } |
213 | 230 | ||
214 | static __inline int _sim_syscall1(int val, long arg1) | 231 | static __inline long _sim_syscall1(int val, long arg1) |
215 | { | 232 | { |
216 | long result; | 233 | long result; |
217 | __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }" | 234 | __asm__ __volatile__ ("{ and zero, r1, r1; mtspr SIM_CONTROL, r0 }" |
@@ -219,7 +236,7 @@ static __inline int _sim_syscall1(int val, long arg1) | |||
219 | return result; | 236 | return result; |
220 | } | 237 | } |
221 | 238 | ||
222 | static __inline int _sim_syscall2(int val, long arg1, long arg2) | 239 | static __inline long _sim_syscall2(int val, long arg1, long arg2) |
223 | { | 240 | { |
224 | long result; | 241 | long result; |
225 | __asm__ __volatile__ ("{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }" | 242 | __asm__ __volatile__ ("{ and zero, r1, r2; mtspr SIM_CONTROL, r0 }" |
@@ -233,7 +250,7 @@ static __inline int _sim_syscall2(int val, long arg1, long arg2) | |||
233 | the register values for arguments 3 and up may still be in flight | 250 | the register values for arguments 3 and up may still be in flight |
234 | to the core from a stack frame reload. */ | 251 | to the core from a stack frame reload. */ |
235 | 252 | ||
236 | static __inline int _sim_syscall3(int val, long arg1, long arg2, long arg3) | 253 | static __inline long _sim_syscall3(int val, long arg1, long arg2, long arg3) |
237 | { | 254 | { |
238 | long result; | 255 | long result; |
239 | __asm__ __volatile__ ("{ and zero, r3, r3 };" | 256 | __asm__ __volatile__ ("{ and zero, r3, r3 };" |
@@ -244,7 +261,7 @@ static __inline int _sim_syscall3(int val, long arg1, long arg2, long arg3) | |||
244 | return result; | 261 | return result; |
245 | } | 262 | } |
246 | 263 | ||
247 | static __inline int _sim_syscall4(int val, long arg1, long arg2, long arg3, | 264 | static __inline long _sim_syscall4(int val, long arg1, long arg2, long arg3, |
248 | long arg4) | 265 | long arg4) |
249 | { | 266 | { |
250 | long result; | 267 | long result; |
@@ -256,7 +273,7 @@ static __inline int _sim_syscall4(int val, long arg1, long arg2, long arg3, | |||
256 | return result; | 273 | return result; |
257 | } | 274 | } |
258 | 275 | ||
259 | static __inline int _sim_syscall5(int val, long arg1, long arg2, long arg3, | 276 | static __inline long _sim_syscall5(int val, long arg1, long arg2, long arg3, |
260 | long arg4, long arg5) | 277 | long arg4, long arg5) |
261 | { | 278 | { |
262 | long result; | 279 | long result; |
@@ -268,7 +285,6 @@ static __inline int _sim_syscall5(int val, long arg1, long arg2, long arg3, | |||
268 | return result; | 285 | return result; |
269 | } | 286 | } |
270 | 287 | ||
271 | |||
272 | /** | 288 | /** |
273 | * Make a special syscall to the simulator itself, if running under | 289 | * Make a special syscall to the simulator itself, if running under |
274 | * simulation. This is used as the implementation of other functions | 290 | * simulation. This is used as the implementation of other functions |
@@ -281,7 +297,8 @@ static __inline int _sim_syscall5(int val, long arg1, long arg2, long arg3, | |||
281 | */ | 297 | */ |
282 | #define _sim_syscall(syscall_num, nr, args...) \ | 298 | #define _sim_syscall(syscall_num, nr, args...) \ |
283 | _sim_syscall##nr( \ | 299 | _sim_syscall##nr( \ |
284 | ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS) | SIM_CONTROL_SYSCALL, args) | 300 | ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS) | SIM_CONTROL_SYSCALL, \ |
301 | ##args) | ||
285 | 302 | ||
286 | 303 | ||
287 | /* Values for the "access_mask" parameters below. */ | 304 | /* Values for the "access_mask" parameters below. */ |
@@ -365,6 +382,13 @@ sim_validate_lines_evicted(unsigned long long pa, unsigned long length) | |||
365 | } | 382 | } |
366 | 383 | ||
367 | 384 | ||
385 | /* Return the current CPU speed in cycles per second. */ | ||
386 | static __inline long | ||
387 | sim_query_cpu_speed(void) | ||
388 | { | ||
389 | return _sim_syscall(SIM_SYSCALL_QUERY_CPU_SPEED, 0); | ||
390 | } | ||
391 | |||
368 | #endif /* !__DOXYGEN__ */ | 392 | #endif /* !__DOXYGEN__ */ |
369 | 393 | ||
370 | 394 | ||
diff --git a/arch/tile/include/arch/sim_def.h b/arch/tile/include/arch/sim_def.h index 7a17082c3773..4b44a2b6a09a 100644 --- a/arch/tile/include/arch/sim_def.h +++ b/arch/tile/include/arch/sim_def.h | |||
@@ -243,6 +243,9 @@ | |||
243 | */ | 243 | */ |
244 | #define SIM_SYSCALL_VALIDATE_LINES_EVICTED 5 | 244 | #define SIM_SYSCALL_VALIDATE_LINES_EVICTED 5 |
245 | 245 | ||
246 | /** Syscall number for sim_query_cpu_speed(). */ | ||
247 | #define SIM_SYSCALL_QUERY_CPU_SPEED 6 | ||
248 | |||
246 | 249 | ||
247 | /* | 250 | /* |
248 | * Bit masks which can be shifted by 8, combined with | 251 | * Bit masks which can be shifted by 8, combined with |
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index 3b8f55b82dee..849ab2fa1f5c 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild | |||
@@ -1,3 +1,4 @@ | |||
1 | include include/asm-generic/Kbuild.asm | 1 | include include/asm-generic/Kbuild.asm |
2 | 2 | ||
3 | header-y += ucontext.h | 3 | header-y += ucontext.h |
4 | header-y += hardwall.h | ||
diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h index b8c49f98a44c..75a16028a952 100644 --- a/arch/tile/include/asm/atomic.h +++ b/arch/tile/include/asm/atomic.h | |||
@@ -32,7 +32,7 @@ | |||
32 | */ | 32 | */ |
33 | static inline int atomic_read(const atomic_t *v) | 33 | static inline int atomic_read(const atomic_t *v) |
34 | { | 34 | { |
35 | return v->counter; | 35 | return ACCESS_ONCE(v->counter); |
36 | } | 36 | } |
37 | 37 | ||
38 | /** | 38 | /** |
diff --git a/arch/tile/include/asm/bitops_32.h b/arch/tile/include/asm/bitops_32.h index 7a93c001ac19..2638be51a164 100644 --- a/arch/tile/include/asm/bitops_32.h +++ b/arch/tile/include/asm/bitops_32.h | |||
@@ -122,7 +122,7 @@ static inline int test_and_change_bit(unsigned nr, | |||
122 | return (_atomic_xor(addr, mask) & mask) != 0; | 122 | return (_atomic_xor(addr, mask) & mask) != 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | /* See discussion at smp_mb__before_atomic_dec() in <asm/atomic.h>. */ | 125 | /* See discussion at smp_mb__before_atomic_dec() in <asm/atomic_32.h>. */ |
126 | #define smp_mb__before_clear_bit() smp_mb() | 126 | #define smp_mb__before_clear_bit() smp_mb() |
127 | #define smp_mb__after_clear_bit() do {} while (0) | 127 | #define smp_mb__after_clear_bit() do {} while (0) |
128 | 128 | ||
diff --git a/arch/tile/include/asm/cache.h b/arch/tile/include/asm/cache.h index 08a2815b5e4e..392e5333dd8b 100644 --- a/arch/tile/include/asm/cache.h +++ b/arch/tile/include/asm/cache.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #define INTERNODE_CACHE_BYTES L2_CACHE_BYTES | 40 | #define INTERNODE_CACHE_BYTES L2_CACHE_BYTES |
41 | 41 | ||
42 | /* Group together read-mostly things to avoid cache false sharing */ | 42 | /* Group together read-mostly things to avoid cache false sharing */ |
43 | #define __read_mostly __attribute__((__section__(".data.read_mostly"))) | 43 | #define __read_mostly __attribute__((__section__(".data..read_mostly"))) |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * Attribute for data that is kept read/write coherent until the end of | 46 | * Attribute for data that is kept read/write coherent until the end of |
diff --git a/arch/tile/include/asm/cacheflush.h b/arch/tile/include/asm/cacheflush.h index 14a3f8556ace..12fb0fb330ee 100644 --- a/arch/tile/include/asm/cacheflush.h +++ b/arch/tile/include/asm/cacheflush.h | |||
@@ -138,55 +138,12 @@ static inline void finv_buffer(void *buffer, size_t size) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * Flush & invalidate a VA range that is homed remotely on a single core, | 141 | * Flush and invalidate a VA range that is homed remotely, waiting |
142 | * waiting until the memory controller holds the flushed values. | 142 | * until the memory controller holds the flushed values. If "hfh" is |
143 | * true, we will do a more expensive flush involving additional loads | ||
144 | * to make sure we have touched all the possible home cpus of a buffer | ||
145 | * that is homed with "hash for home". | ||
143 | */ | 146 | */ |
144 | static inline void finv_buffer_remote(void *buffer, size_t size) | 147 | void finv_buffer_remote(void *buffer, size_t size, int hfh); |
145 | { | ||
146 | char *p; | ||
147 | int i; | ||
148 | |||
149 | /* | ||
150 | * Flush and invalidate the buffer out of the local L1/L2 | ||
151 | * and request the home cache to flush and invalidate as well. | ||
152 | */ | ||
153 | __finv_buffer(buffer, size); | ||
154 | |||
155 | /* | ||
156 | * Wait for the home cache to acknowledge that it has processed | ||
157 | * all the flush-and-invalidate requests. This does not mean | ||
158 | * that the flushed data has reached the memory controller yet, | ||
159 | * but it does mean the home cache is processing the flushes. | ||
160 | */ | ||
161 | __insn_mf(); | ||
162 | |||
163 | /* | ||
164 | * Issue a load to the last cache line, which can't complete | ||
165 | * until all the previously-issued flushes to the same memory | ||
166 | * controller have also completed. If we weren't striping | ||
167 | * memory, that one load would be sufficient, but since we may | ||
168 | * be, we also need to back up to the last load issued to | ||
169 | * another memory controller, which would be the point where | ||
170 | * we crossed an 8KB boundary (the granularity of striping | ||
171 | * across memory controllers). Keep backing up and doing this | ||
172 | * until we are before the beginning of the buffer, or have | ||
173 | * hit all the controllers. | ||
174 | */ | ||
175 | for (i = 0, p = (char *)buffer + size - 1; | ||
176 | i < (1 << CHIP_LOG_NUM_MSHIMS()) && p >= (char *)buffer; | ||
177 | ++i) { | ||
178 | const unsigned long STRIPE_WIDTH = 8192; | ||
179 | |||
180 | /* Force a load instruction to issue. */ | ||
181 | *(volatile char *)p; | ||
182 | |||
183 | /* Jump to end of previous stripe. */ | ||
184 | p -= STRIPE_WIDTH; | ||
185 | p = (char *)((unsigned long)p | (STRIPE_WIDTH - 1)); | ||
186 | } | ||
187 | |||
188 | /* Wait for the loads (and thus flushes) to have completed. */ | ||
189 | __insn_mf(); | ||
190 | } | ||
191 | 148 | ||
192 | #endif /* _ASM_TILE_CACHEFLUSH_H */ | 149 | #endif /* _ASM_TILE_CACHEFLUSH_H */ |
diff --git a/arch/tile/include/asm/edac.h b/arch/tile/include/asm/edac.h new file mode 100644 index 000000000000..87fc83eeaffd --- /dev/null +++ b/arch/tile/include/asm/edac.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _ASM_TILE_EDAC_H | ||
16 | #define _ASM_TILE_EDAC_H | ||
17 | |||
18 | /* ECC atomic, DMA, SMP and interrupt safe scrub function */ | ||
19 | |||
20 | static inline void atomic_scrub(void *va, u32 size) | ||
21 | { | ||
22 | /* | ||
23 | * These is nothing to be done here because CE is | ||
24 | * corrected by the mshim. | ||
25 | */ | ||
26 | return; | ||
27 | } | ||
28 | |||
29 | #endif /* _ASM_TILE_EDAC_H */ | ||
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h index 0521c277bbde..d396d1805163 100644 --- a/arch/tile/include/asm/hugetlb.h +++ b/arch/tile/include/asm/hugetlb.h | |||
@@ -54,7 +54,7 @@ static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb, | |||
54 | static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 54 | static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
55 | pte_t *ptep, pte_t pte) | 55 | pte_t *ptep, pte_t pte) |
56 | { | 56 | { |
57 | set_pte_order(ptep, pte, HUGETLB_PAGE_ORDER); | 57 | set_pte(ptep, pte); |
58 | } | 58 | } |
59 | 59 | ||
60 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | 60 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, |
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h index 641e4ff3d805..5db0ce54284d 100644 --- a/arch/tile/include/asm/irqflags.h +++ b/arch/tile/include/asm/irqflags.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <arch/interrupts.h> | 18 | #include <arch/interrupts.h> |
19 | #include <arch/chip.h> | 19 | #include <arch/chip.h> |
20 | 20 | ||
21 | #if !defined(__tilegx__) && defined(__ASSEMBLY__) | ||
22 | |||
21 | /* | 23 | /* |
22 | * The set of interrupts we want to allow when interrupts are nominally | 24 | * The set of interrupts we want to allow when interrupts are nominally |
23 | * disabled. The remainder are effectively "NMI" interrupts from | 25 | * disabled. The remainder are effectively "NMI" interrupts from |
@@ -25,6 +27,16 @@ | |||
25 | * interrupts (aka "non-queued") are not blocked by the mask in any case. | 27 | * interrupts (aka "non-queued") are not blocked by the mask in any case. |
26 | */ | 28 | */ |
27 | #if CHIP_HAS_AUX_PERF_COUNTERS() | 29 | #if CHIP_HAS_AUX_PERF_COUNTERS() |
30 | #define LINUX_MASKABLE_INTERRUPTS_HI \ | ||
31 | (~(INT_MASK_HI(INT_PERF_COUNT) | INT_MASK_HI(INT_AUX_PERF_COUNT))) | ||
32 | #else | ||
33 | #define LINUX_MASKABLE_INTERRUPTS_HI \ | ||
34 | (~(INT_MASK_HI(INT_PERF_COUNT))) | ||
35 | #endif | ||
36 | |||
37 | #else | ||
38 | |||
39 | #if CHIP_HAS_AUX_PERF_COUNTERS() | ||
28 | #define LINUX_MASKABLE_INTERRUPTS \ | 40 | #define LINUX_MASKABLE_INTERRUPTS \ |
29 | (~(INT_MASK(INT_PERF_COUNT) | INT_MASK(INT_AUX_PERF_COUNT))) | 41 | (~(INT_MASK(INT_PERF_COUNT) | INT_MASK(INT_AUX_PERF_COUNT))) |
30 | #else | 42 | #else |
@@ -32,6 +44,8 @@ | |||
32 | (~(INT_MASK(INT_PERF_COUNT))) | 44 | (~(INT_MASK(INT_PERF_COUNT))) |
33 | #endif | 45 | #endif |
34 | 46 | ||
47 | #endif | ||
48 | |||
35 | #ifndef __ASSEMBLY__ | 49 | #ifndef __ASSEMBLY__ |
36 | 50 | ||
37 | /* NOTE: we can't include <linux/percpu.h> due to #include dependencies. */ | 51 | /* NOTE: we can't include <linux/percpu.h> due to #include dependencies. */ |
@@ -224,11 +238,11 @@ DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask); | |||
224 | #define IRQ_DISABLE(tmp0, tmp1) \ | 238 | #define IRQ_DISABLE(tmp0, tmp1) \ |
225 | { \ | 239 | { \ |
226 | movei tmp0, -1; \ | 240 | movei tmp0, -1; \ |
227 | moveli tmp1, lo16(LINUX_MASKABLE_INTERRUPTS) \ | 241 | moveli tmp1, lo16(LINUX_MASKABLE_INTERRUPTS_HI) \ |
228 | }; \ | 242 | }; \ |
229 | { \ | 243 | { \ |
230 | mtspr SPR_INTERRUPT_MASK_SET_K_0, tmp0; \ | 244 | mtspr SPR_INTERRUPT_MASK_SET_K_0, tmp0; \ |
231 | auli tmp1, tmp1, ha16(LINUX_MASKABLE_INTERRUPTS) \ | 245 | auli tmp1, tmp1, ha16(LINUX_MASKABLE_INTERRUPTS_HI) \ |
232 | }; \ | 246 | }; \ |
233 | mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp1 | 247 | mtspr SPR_INTERRUPT_MASK_SET_K_1, tmp1 |
234 | 248 | ||
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h index 7979a45430d3..3eb53525bf9d 100644 --- a/arch/tile/include/asm/page.h +++ b/arch/tile/include/asm/page.h | |||
@@ -16,10 +16,11 @@ | |||
16 | #define _ASM_TILE_PAGE_H | 16 | #define _ASM_TILE_PAGE_H |
17 | 17 | ||
18 | #include <linux/const.h> | 18 | #include <linux/const.h> |
19 | #include <hv/pagesize.h> | ||
19 | 20 | ||
20 | /* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */ | 21 | /* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */ |
21 | #define PAGE_SHIFT 16 | 22 | #define PAGE_SHIFT HV_LOG2_PAGE_SIZE_SMALL |
22 | #define HPAGE_SHIFT 24 | 23 | #define HPAGE_SHIFT HV_LOG2_PAGE_SIZE_LARGE |
23 | 24 | ||
24 | #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) | 25 | #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) |
25 | #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) | 26 | #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) |
@@ -29,25 +30,18 @@ | |||
29 | 30 | ||
30 | #ifdef __KERNEL__ | 31 | #ifdef __KERNEL__ |
31 | 32 | ||
32 | #include <hv/hypervisor.h> | ||
33 | #include <arch/chip.h> | ||
34 | |||
35 | /* | 33 | /* |
36 | * The {,H}PAGE_SHIFT values must match the HV_LOG2_PAGE_SIZE_xxx | 34 | * If the Kconfig doesn't specify, set a maximum zone order that |
37 | * definitions in <hv/hypervisor.h>. We validate this at build time | 35 | * is enough so that we can create huge pages from small pages given |
38 | * here, and again at runtime during early boot. We provide a | 36 | * the respective sizes of the two page types. See <linux/mmzone.h>. |
39 | * separate definition since userspace doesn't have <hv/hypervisor.h>. | ||
40 | * | ||
41 | * Be careful to distinguish PAGE_SHIFT from HV_PTE_INDEX_PFN, since | ||
42 | * they are the same on i386 but not TILE. | ||
43 | */ | 37 | */ |
44 | #if HV_LOG2_PAGE_SIZE_SMALL != PAGE_SHIFT | 38 | #ifndef CONFIG_FORCE_MAX_ZONEORDER |
45 | # error Small page size mismatch in Linux | 39 | #define CONFIG_FORCE_MAX_ZONEORDER (HPAGE_SHIFT - PAGE_SHIFT + 1) |
46 | #endif | ||
47 | #if HV_LOG2_PAGE_SIZE_LARGE != HPAGE_SHIFT | ||
48 | # error Huge page size mismatch in Linux | ||
49 | #endif | 40 | #endif |
50 | 41 | ||
42 | #include <hv/hypervisor.h> | ||
43 | #include <arch/chip.h> | ||
44 | |||
51 | #ifndef __ASSEMBLY__ | 45 | #ifndef __ASSEMBLY__ |
52 | 46 | ||
53 | #include <linux/types.h> | 47 | #include <linux/types.h> |
@@ -81,12 +75,6 @@ static inline void copy_user_page(void *to, void *from, unsigned long vaddr, | |||
81 | * Hypervisor page tables are made of the same basic structure. | 75 | * Hypervisor page tables are made of the same basic structure. |
82 | */ | 76 | */ |
83 | 77 | ||
84 | typedef __u64 pteval_t; | ||
85 | typedef __u64 pmdval_t; | ||
86 | typedef __u64 pudval_t; | ||
87 | typedef __u64 pgdval_t; | ||
88 | typedef __u64 pgprotval_t; | ||
89 | |||
90 | typedef HV_PTE pte_t; | 78 | typedef HV_PTE pte_t; |
91 | typedef HV_PTE pgd_t; | 79 | typedef HV_PTE pgd_t; |
92 | typedef HV_PTE pgprot_t; | 80 | typedef HV_PTE pgprot_t; |
diff --git a/arch/tile/include/asm/pgalloc.h b/arch/tile/include/asm/pgalloc.h index cf52791a5501..e919c0bdc22d 100644 --- a/arch/tile/include/asm/pgalloc.h +++ b/arch/tile/include/asm/pgalloc.h | |||
@@ -41,9 +41,9 @@ | |||
41 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) | 41 | static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) |
42 | { | 42 | { |
43 | #ifdef CONFIG_64BIT | 43 | #ifdef CONFIG_64BIT |
44 | set_pte_order(pmdp, pmd, L2_USER_PGTABLE_ORDER); | 44 | set_pte(pmdp, pmd); |
45 | #else | 45 | #else |
46 | set_pte_order(&pmdp->pud.pgd, pmd.pud.pgd, L2_USER_PGTABLE_ORDER); | 46 | set_pte(&pmdp->pud.pgd, pmd.pud.pgd); |
47 | #endif | 47 | #endif |
48 | } | 48 | } |
49 | 49 | ||
@@ -100,6 +100,9 @@ pte_t *get_prealloc_pte(unsigned long pfn); | |||
100 | /* During init, we can shatter kernel huge pages if needed. */ | 100 | /* During init, we can shatter kernel huge pages if needed. */ |
101 | void shatter_pmd(pmd_t *pmd); | 101 | void shatter_pmd(pmd_t *pmd); |
102 | 102 | ||
103 | /* After init, a more complex technique is required. */ | ||
104 | void shatter_huge_page(unsigned long addr); | ||
105 | |||
103 | #ifdef __tilegx__ | 106 | #ifdef __tilegx__ |
104 | /* We share a single page allocator for both L1 and L2 page tables. */ | 107 | /* We share a single page allocator for both L1 and L2 page tables. */ |
105 | #if HV_L1_SIZE != HV_L2_SIZE | 108 | #if HV_L1_SIZE != HV_L2_SIZE |
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h index a6604e9485da..1a20b7ef8ea2 100644 --- a/arch/tile/include/asm/pgtable.h +++ b/arch/tile/include/asm/pgtable.h | |||
@@ -233,15 +233,23 @@ static inline void __pte_clear(pte_t *ptep) | |||
233 | #define pgd_ERROR(e) \ | 233 | #define pgd_ERROR(e) \ |
234 | pr_err("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e)) | 234 | pr_err("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e)) |
235 | 235 | ||
236 | /* Return PA and protection info for a given kernel VA. */ | ||
237 | int va_to_cpa_and_pte(void *va, phys_addr_t *cpa, pte_t *pte); | ||
238 | |||
239 | /* | ||
240 | * __set_pte() ensures we write the 64-bit PTE with 32-bit words in | ||
241 | * the right order on 32-bit platforms and also allows us to write | ||
242 | * hooks to check valid PTEs, etc., if we want. | ||
243 | */ | ||
244 | void __set_pte(pte_t *ptep, pte_t pte); | ||
245 | |||
236 | /* | 246 | /* |
237 | * set_pte_order() sets the given PTE and also sanity-checks the | 247 | * set_pte() sets the given PTE and also sanity-checks the |
238 | * requested PTE against the page homecaching. Unspecified parts | 248 | * requested PTE against the page homecaching. Unspecified parts |
239 | * of the PTE are filled in when it is written to memory, i.e. all | 249 | * of the PTE are filled in when it is written to memory, i.e. all |
240 | * caching attributes if "!forcecache", or the home cpu if "anyhome". | 250 | * caching attributes if "!forcecache", or the home cpu if "anyhome". |
241 | */ | 251 | */ |
242 | extern void set_pte_order(pte_t *ptep, pte_t pte, int order); | 252 | extern void set_pte(pte_t *ptep, pte_t pte); |
243 | |||
244 | #define set_pte(ptep, pteval) set_pte_order(ptep, pteval, 0) | ||
245 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) | 253 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) |
246 | #define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval) | 254 | #define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval) |
247 | 255 | ||
@@ -293,21 +301,6 @@ extern void check_mm_caching(struct mm_struct *prev, struct mm_struct *next); | |||
293 | #define __swp_entry_to_pte(swp) ((pte_t) { (((long long) ((swp).val)) << 32) }) | 301 | #define __swp_entry_to_pte(swp) ((pte_t) { (((long long) ((swp).val)) << 32) }) |
294 | 302 | ||
295 | /* | 303 | /* |
296 | * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); | ||
297 | * | ||
298 | * dst - pointer to pgd range anwhere on a pgd page | ||
299 | * src - "" | ||
300 | * count - the number of pgds to copy. | ||
301 | * | ||
302 | * dst and src can be on the same page, but the range must not overlap, | ||
303 | * and must not cross a page boundary. | ||
304 | */ | ||
305 | static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) | ||
306 | { | ||
307 | memcpy(dst, src, count * sizeof(pgd_t)); | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * Conversion functions: convert a page and protection to a page entry, | 304 | * Conversion functions: convert a page and protection to a page entry, |
312 | * and a page entry and page directory to the page they refer to. | 305 | * and a page entry and page directory to the page they refer to. |
313 | */ | 306 | */ |
diff --git a/arch/tile/include/asm/pgtable_32.h b/arch/tile/include/asm/pgtable_32.h index 53ec34884744..9f98529761fd 100644 --- a/arch/tile/include/asm/pgtable_32.h +++ b/arch/tile/include/asm/pgtable_32.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define PGDIR_SIZE HV_PAGE_SIZE_LARGE | 24 | #define PGDIR_SIZE HV_PAGE_SIZE_LARGE |
25 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | 25 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
26 | #define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) | 26 | #define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) |
27 | #define SIZEOF_PGD (PTRS_PER_PGD * sizeof(pgd_t)) | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * The level-2 index is defined by the difference between the huge | 30 | * The level-2 index is defined by the difference between the huge |
@@ -33,6 +34,7 @@ | |||
33 | * this nomenclature is somewhat confusing. | 34 | * this nomenclature is somewhat confusing. |
34 | */ | 35 | */ |
35 | #define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)) | 36 | #define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)) |
37 | #define SIZEOF_PTE (PTRS_PER_PTE * sizeof(pte_t)) | ||
36 | 38 | ||
37 | #ifndef __ASSEMBLY__ | 39 | #ifndef __ASSEMBLY__ |
38 | 40 | ||
@@ -94,7 +96,6 @@ static inline int pgd_addr_invalid(unsigned long addr) | |||
94 | */ | 96 | */ |
95 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | 97 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG |
96 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT | 98 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT |
97 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR | ||
98 | 99 | ||
99 | extern int ptep_test_and_clear_young(struct vm_area_struct *, | 100 | extern int ptep_test_and_clear_young(struct vm_area_struct *, |
100 | unsigned long addr, pte_t *); | 101 | unsigned long addr, pte_t *); |
@@ -110,6 +111,11 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, | |||
110 | return pte; | 111 | return pte; |
111 | } | 112 | } |
112 | 113 | ||
114 | static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval) | ||
115 | { | ||
116 | set_pte(&pmdp->pud.pgd, pmdval.pud.pgd); | ||
117 | } | ||
118 | |||
113 | /* Create a pmd from a PTFN. */ | 119 | /* Create a pmd from a PTFN. */ |
114 | static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot) | 120 | static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot) |
115 | { | 121 | { |
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h index a9e7c8760334..e6889474038a 100644 --- a/arch/tile/include/asm/processor.h +++ b/arch/tile/include/asm/processor.h | |||
@@ -269,7 +269,6 @@ extern char chip_model[64]; | |||
269 | /* Data on which physical memory controller corresponds to which NUMA node. */ | 269 | /* Data on which physical memory controller corresponds to which NUMA node. */ |
270 | extern int node_controller[]; | 270 | extern int node_controller[]; |
271 | 271 | ||
272 | |||
273 | /* Do we dump information to the console when a user application crashes? */ | 272 | /* Do we dump information to the console when a user application crashes? */ |
274 | extern int show_crashinfo; | 273 | extern int show_crashinfo; |
275 | 274 | ||
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h index ac6d343129d3..6be2246e015c 100644 --- a/arch/tile/include/asm/ptrace.h +++ b/arch/tile/include/asm/ptrace.h | |||
@@ -141,6 +141,9 @@ struct single_step_state { | |||
141 | /* Single-step the instruction at regs->pc */ | 141 | /* Single-step the instruction at regs->pc */ |
142 | extern void single_step_once(struct pt_regs *regs); | 142 | extern void single_step_once(struct pt_regs *regs); |
143 | 143 | ||
144 | /* Clean up after execve(). */ | ||
145 | extern void single_step_execve(void); | ||
146 | |||
144 | struct task_struct; | 147 | struct task_struct; |
145 | 148 | ||
146 | extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, | 149 | extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, |
diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h index 88efdde8dd2b..a8f2c6e31a87 100644 --- a/arch/tile/include/asm/spinlock_32.h +++ b/arch/tile/include/asm/spinlock_32.h | |||
@@ -78,13 +78,6 @@ void arch_spin_unlock_wait(arch_spinlock_t *lock); | |||
78 | #define _RD_COUNT_SHIFT 24 | 78 | #define _RD_COUNT_SHIFT 24 |
79 | #define _RD_COUNT_WIDTH 8 | 79 | #define _RD_COUNT_WIDTH 8 |
80 | 80 | ||
81 | /* Internal functions; do not use. */ | ||
82 | void arch_read_lock_slow(arch_rwlock_t *, u32); | ||
83 | int arch_read_trylock_slow(arch_rwlock_t *); | ||
84 | void arch_read_unlock_slow(arch_rwlock_t *); | ||
85 | void arch_write_lock_slow(arch_rwlock_t *, u32); | ||
86 | void arch_write_unlock_slow(arch_rwlock_t *, u32); | ||
87 | |||
88 | /** | 81 | /** |
89 | * arch_read_can_lock() - would read_trylock() succeed? | 82 | * arch_read_can_lock() - would read_trylock() succeed? |
90 | */ | 83 | */ |
@@ -104,94 +97,32 @@ static inline int arch_write_can_lock(arch_rwlock_t *rwlock) | |||
104 | /** | 97 | /** |
105 | * arch_read_lock() - acquire a read lock. | 98 | * arch_read_lock() - acquire a read lock. |
106 | */ | 99 | */ |
107 | static inline void arch_read_lock(arch_rwlock_t *rwlock) | 100 | void arch_read_lock(arch_rwlock_t *rwlock); |
108 | { | ||
109 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
110 | if (unlikely(val << _RD_COUNT_WIDTH)) { | ||
111 | arch_read_lock_slow(rwlock, val); | ||
112 | return; | ||
113 | } | ||
114 | rwlock->lock = val + (1 << _RD_COUNT_SHIFT); | ||
115 | } | ||
116 | 101 | ||
117 | /** | 102 | /** |
118 | * arch_read_lock() - acquire a write lock. | 103 | * arch_write_lock() - acquire a write lock. |
119 | */ | 104 | */ |
120 | static inline void arch_write_lock(arch_rwlock_t *rwlock) | 105 | void arch_write_lock(arch_rwlock_t *rwlock); |
121 | { | ||
122 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
123 | if (unlikely(val != 0)) { | ||
124 | arch_write_lock_slow(rwlock, val); | ||
125 | return; | ||
126 | } | ||
127 | rwlock->lock = 1 << _WR_NEXT_SHIFT; | ||
128 | } | ||
129 | 106 | ||
130 | /** | 107 | /** |
131 | * arch_read_trylock() - try to acquire a read lock. | 108 | * arch_read_trylock() - try to acquire a read lock. |
132 | */ | 109 | */ |
133 | static inline int arch_read_trylock(arch_rwlock_t *rwlock) | 110 | int arch_read_trylock(arch_rwlock_t *rwlock); |
134 | { | ||
135 | int locked; | ||
136 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
137 | if (unlikely(val & 1)) | ||
138 | return arch_read_trylock_slow(rwlock); | ||
139 | locked = (val << _RD_COUNT_WIDTH) == 0; | ||
140 | rwlock->lock = val + (locked << _RD_COUNT_SHIFT); | ||
141 | return locked; | ||
142 | } | ||
143 | 111 | ||
144 | /** | 112 | /** |
145 | * arch_write_trylock() - try to acquire a write lock. | 113 | * arch_write_trylock() - try to acquire a write lock. |
146 | */ | 114 | */ |
147 | static inline int arch_write_trylock(arch_rwlock_t *rwlock) | 115 | int arch_write_trylock(arch_rwlock_t *rwlock); |
148 | { | ||
149 | u32 val = __insn_tns((int *)&rwlock->lock); | ||
150 | |||
151 | /* | ||
152 | * If a tns is in progress, or there's a waiting or active locker, | ||
153 | * or active readers, we can't take the lock, so give up. | ||
154 | */ | ||
155 | if (unlikely(val != 0)) { | ||
156 | if (!(val & 1)) | ||
157 | rwlock->lock = val; | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* Set the "next" field to mark it locked. */ | ||
162 | rwlock->lock = 1 << _WR_NEXT_SHIFT; | ||
163 | return 1; | ||
164 | } | ||
165 | 116 | ||
166 | /** | 117 | /** |
167 | * arch_read_unlock() - release a read lock. | 118 | * arch_read_unlock() - release a read lock. |
168 | */ | 119 | */ |
169 | static inline void arch_read_unlock(arch_rwlock_t *rwlock) | 120 | void arch_read_unlock(arch_rwlock_t *rwlock); |
170 | { | ||
171 | u32 val; | ||
172 | mb(); /* guarantee anything modified under the lock is visible */ | ||
173 | val = __insn_tns((int *)&rwlock->lock); | ||
174 | if (unlikely(val & 1)) { | ||
175 | arch_read_unlock_slow(rwlock); | ||
176 | return; | ||
177 | } | ||
178 | rwlock->lock = val - (1 << _RD_COUNT_SHIFT); | ||
179 | } | ||
180 | 121 | ||
181 | /** | 122 | /** |
182 | * arch_write_unlock() - release a write lock. | 123 | * arch_write_unlock() - release a write lock. |
183 | */ | 124 | */ |
184 | static inline void arch_write_unlock(arch_rwlock_t *rwlock) | 125 | void arch_write_unlock(arch_rwlock_t *rwlock); |
185 | { | ||
186 | u32 val; | ||
187 | mb(); /* guarantee anything modified under the lock is visible */ | ||
188 | val = __insn_tns((int *)&rwlock->lock); | ||
189 | if (unlikely(val != (1 << _WR_NEXT_SHIFT))) { | ||
190 | arch_write_unlock_slow(rwlock, val); | ||
191 | return; | ||
192 | } | ||
193 | rwlock->lock = 0; | ||
194 | } | ||
195 | 126 | ||
196 | #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) | 127 | #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) |
197 | #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) | 128 | #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) |
diff --git a/arch/tile/include/asm/stack.h b/arch/tile/include/asm/stack.h index f908473c322d..4d97a2db932e 100644 --- a/arch/tile/include/asm/stack.h +++ b/arch/tile/include/asm/stack.h | |||
@@ -18,13 +18,14 @@ | |||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <asm/backtrace.h> | 20 | #include <asm/backtrace.h> |
21 | #include <asm/page.h> | ||
21 | #include <hv/hypervisor.h> | 22 | #include <hv/hypervisor.h> |
22 | 23 | ||
23 | /* Everything we need to keep track of a backtrace iteration */ | 24 | /* Everything we need to keep track of a backtrace iteration */ |
24 | struct KBacktraceIterator { | 25 | struct KBacktraceIterator { |
25 | BacktraceIterator it; | 26 | BacktraceIterator it; |
26 | struct task_struct *task; /* task we are backtracing */ | 27 | struct task_struct *task; /* task we are backtracing */ |
27 | HV_PTE *pgtable; /* page table for user space access */ | 28 | pte_t *pgtable; /* page table for user space access */ |
28 | int end; /* iteration complete. */ | 29 | int end; /* iteration complete. */ |
29 | int new_context; /* new context is starting */ | 30 | int new_context; /* new context is starting */ |
30 | int profile; /* profiling, so stop on async intrpt */ | 31 | int profile; /* profiling, so stop on async intrpt */ |
diff --git a/arch/tile/include/asm/system.h b/arch/tile/include/asm/system.h index 5388850deeb2..23d1842f4839 100644 --- a/arch/tile/include/asm/system.h +++ b/arch/tile/include/asm/system.h | |||
@@ -90,7 +90,24 @@ | |||
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | #if !CHIP_HAS_MF_WAITS_FOR_VICTIMS() | 92 | #if !CHIP_HAS_MF_WAITS_FOR_VICTIMS() |
93 | int __mb_incoherent(void); /* Helper routine for mb_incoherent(). */ | 93 | #include <hv/syscall_public.h> |
94 | /* | ||
95 | * Issue an uncacheable load to each memory controller, then | ||
96 | * wait until those loads have completed. | ||
97 | */ | ||
98 | static inline void __mb_incoherent(void) | ||
99 | { | ||
100 | long clobber_r10; | ||
101 | asm volatile("swint2" | ||
102 | : "=R10" (clobber_r10) | ||
103 | : "R10" (HV_SYS_fence_incoherent) | ||
104 | : "r0", "r1", "r2", "r3", "r4", | ||
105 | "r5", "r6", "r7", "r8", "r9", | ||
106 | "r11", "r12", "r13", "r14", | ||
107 | "r15", "r16", "r17", "r18", "r19", | ||
108 | "r20", "r21", "r22", "r23", "r24", | ||
109 | "r25", "r26", "r27", "r28", "r29"); | ||
110 | } | ||
94 | #endif | 111 | #endif |
95 | 112 | ||
96 | /* Fence to guarantee visibility of stores to incoherent memory. */ | 113 | /* Fence to guarantee visibility of stores to incoherent memory. */ |
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index 3872f2b345d2..9e8e9c4dfa2a 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h | |||
@@ -68,6 +68,7 @@ struct thread_info { | |||
68 | #else | 68 | #else |
69 | #define THREAD_SIZE_ORDER (0) | 69 | #define THREAD_SIZE_ORDER (0) |
70 | #endif | 70 | #endif |
71 | #define THREAD_SIZE_PAGES (1 << THREAD_SIZE_ORDER) | ||
71 | 72 | ||
72 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) | 73 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
73 | #define LOG2_THREAD_SIZE (PAGE_SHIFT + THREAD_SIZE_ORDER) | 74 | #define LOG2_THREAD_SIZE (PAGE_SHIFT + THREAD_SIZE_ORDER) |
diff --git a/arch/tile/include/asm/timex.h b/arch/tile/include/asm/timex.h index 3baf5fc4c0a1..29921f0b86da 100644 --- a/arch/tile/include/asm/timex.h +++ b/arch/tile/include/asm/timex.h | |||
@@ -38,6 +38,9 @@ static inline cycles_t get_cycles(void) | |||
38 | 38 | ||
39 | cycles_t get_clock_rate(void); | 39 | cycles_t get_clock_rate(void); |
40 | 40 | ||
41 | /* Convert nanoseconds to core clock cycles. */ | ||
42 | cycles_t ns2cycles(unsigned long nsecs); | ||
43 | |||
41 | /* Called at cpu initialization to set some low-level constants. */ | 44 | /* Called at cpu initialization to set some low-level constants. */ |
42 | void setup_clock(void); | 45 | void setup_clock(void); |
43 | 46 | ||
diff --git a/arch/tile/include/hv/drv_mshim_intf.h b/arch/tile/include/hv/drv_mshim_intf.h new file mode 100644 index 000000000000..c6ef3bdc55cf --- /dev/null +++ b/arch/tile/include/hv/drv_mshim_intf.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | /** | ||
16 | * @file drv_mshim_intf.h | ||
17 | * Interface definitions for the Linux EDAC memory controller driver. | ||
18 | */ | ||
19 | |||
20 | #ifndef _SYS_HV_INCLUDE_DRV_MSHIM_INTF_H | ||
21 | #define _SYS_HV_INCLUDE_DRV_MSHIM_INTF_H | ||
22 | |||
23 | /** Number of memory controllers in the public API. */ | ||
24 | #define TILE_MAX_MSHIMS 4 | ||
25 | |||
26 | /** Memory info under each memory controller. */ | ||
27 | struct mshim_mem_info | ||
28 | { | ||
29 | uint64_t mem_size; /**< Total memory size in bytes. */ | ||
30 | uint8_t mem_type; /**< Memory type, DDR2 or DDR3. */ | ||
31 | uint8_t mem_ecc; /**< Memory supports ECC. */ | ||
32 | }; | ||
33 | |||
34 | /** | ||
35 | * DIMM error structure. | ||
36 | * For now, only correctable errors are counted and the mshim doesn't record | ||
37 | * the error PA. HV takes panic upon uncorrectable errors. | ||
38 | */ | ||
39 | struct mshim_mem_error | ||
40 | { | ||
41 | uint32_t sbe_count; /**< Number of single-bit errors. */ | ||
42 | }; | ||
43 | |||
44 | /** Read this offset to get the memory info per mshim. */ | ||
45 | #define MSHIM_MEM_INFO_OFF 0x100 | ||
46 | |||
47 | /** Read this offset to check DIMM error. */ | ||
48 | #define MSHIM_MEM_ERROR_OFF 0x200 | ||
49 | |||
50 | #endif /* _SYS_HV_INCLUDE_DRV_MSHIM_INTF_H */ | ||
diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h index f672544cd4f9..1b8bf03d62a0 100644 --- a/arch/tile/include/hv/hypervisor.h +++ b/arch/tile/include/hv/hypervisor.h | |||
@@ -338,9 +338,10 @@ typedef int HV_Errno; | |||
338 | #define HV_ENOTREADY -812 /**< Device not ready */ | 338 | #define HV_ENOTREADY -812 /**< Device not ready */ |
339 | #define HV_EIO -813 /**< I/O error */ | 339 | #define HV_EIO -813 /**< I/O error */ |
340 | #define HV_ENOMEM -814 /**< Out of memory */ | 340 | #define HV_ENOMEM -814 /**< Out of memory */ |
341 | #define HV_EAGAIN -815 /**< Try again */ | ||
341 | 342 | ||
342 | #define HV_ERR_MAX -801 /**< Largest HV error code */ | 343 | #define HV_ERR_MAX -801 /**< Largest HV error code */ |
343 | #define HV_ERR_MIN -814 /**< Smallest HV error code */ | 344 | #define HV_ERR_MIN -815 /**< Smallest HV error code */ |
344 | 345 | ||
345 | #ifndef __ASSEMBLER__ | 346 | #ifndef __ASSEMBLER__ |
346 | 347 | ||
@@ -867,6 +868,43 @@ typedef struct | |||
867 | */ | 868 | */ |
868 | HV_PhysAddrRange hv_inquire_physical(int idx); | 869 | HV_PhysAddrRange hv_inquire_physical(int idx); |
869 | 870 | ||
871 | /** Possible DIMM types. */ | ||
872 | typedef enum | ||
873 | { | ||
874 | NO_DIMM = 0, /**< No DIMM */ | ||
875 | DDR2 = 1, /**< DDR2 */ | ||
876 | DDR3 = 2 /**< DDR3 */ | ||
877 | } HV_DIMM_Type; | ||
878 | |||
879 | #ifdef __tilegx__ | ||
880 | |||
881 | /** Log2 of minimum DIMM bytes supported by the memory controller. */ | ||
882 | #define HV_MSH_MIN_DIMM_SIZE_SHIFT 29 | ||
883 | |||
884 | /** Max number of DIMMs contained by one memory controller. */ | ||
885 | #define HV_MSH_MAX_DIMMS 8 | ||
886 | |||
887 | #else | ||
888 | |||
889 | /** Log2 of minimum DIMM bytes supported by the memory controller. */ | ||
890 | #define HV_MSH_MIN_DIMM_SIZE_SHIFT 26 | ||
891 | |||
892 | /** Max number of DIMMs contained by one memory controller. */ | ||
893 | #define HV_MSH_MAX_DIMMS 2 | ||
894 | |||
895 | #endif | ||
896 | |||
897 | /** Number of bits to right-shift to get the DIMM type. */ | ||
898 | #define HV_DIMM_TYPE_SHIFT 0 | ||
899 | |||
900 | /** Bits to mask to get the DIMM type. */ | ||
901 | #define HV_DIMM_TYPE_MASK 0xf | ||
902 | |||
903 | /** Number of bits to right-shift to get the DIMM size. */ | ||
904 | #define HV_DIMM_SIZE_SHIFT 4 | ||
905 | |||
906 | /** Bits to mask to get the DIMM size. */ | ||
907 | #define HV_DIMM_SIZE_MASK 0xf | ||
870 | 908 | ||
871 | /** Memory controller information. */ | 909 | /** Memory controller information. */ |
872 | typedef struct | 910 | typedef struct |
@@ -964,6 +1002,11 @@ HV_ASIDRange hv_inquire_asid(int idx); | |||
964 | 1002 | ||
965 | /** Waits for at least the specified number of nanoseconds then returns. | 1003 | /** Waits for at least the specified number of nanoseconds then returns. |
966 | * | 1004 | * |
1005 | * NOTE: this deprecated function currently assumes a 750 MHz clock, | ||
1006 | * and is thus not generally suitable for use. New code should call | ||
1007 | * hv_sysconf(HV_SYSCONF_CPU_SPEED), compute a cycle count to wait for, | ||
1008 | * and delay by looping while checking the cycle counter SPR. | ||
1009 | * | ||
967 | * @param nanosecs The number of nanoseconds to sleep. | 1010 | * @param nanosecs The number of nanoseconds to sleep. |
968 | */ | 1011 | */ |
969 | void hv_nanosleep(int nanosecs); | 1012 | void hv_nanosleep(int nanosecs); |
@@ -1038,6 +1081,7 @@ int hv_console_write(HV_VirtAddr bytes, int len); | |||
1038 | * downcall: | 1081 | * downcall: |
1039 | * | 1082 | * |
1040 | * INT_MESSAGE_RCV_DWNCL (hypervisor message available) | 1083 | * INT_MESSAGE_RCV_DWNCL (hypervisor message available) |
1084 | * INT_DEV_INTR_DWNCL (device interrupt) | ||
1041 | * INT_DMATLB_MISS_DWNCL (DMA TLB miss) | 1085 | * INT_DMATLB_MISS_DWNCL (DMA TLB miss) |
1042 | * INT_SNITLB_MISS_DWNCL (SNI TLB miss) | 1086 | * INT_SNITLB_MISS_DWNCL (SNI TLB miss) |
1043 | * INT_DMATLB_ACCESS_DWNCL (DMA TLB access violation) | 1087 | * INT_DMATLB_ACCESS_DWNCL (DMA TLB access violation) |