diff options
Diffstat (limited to 'arch/tile/include/asm/processor.h')
-rw-r--r-- | arch/tile/include/asm/processor.h | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h index 461322b473b5..230b830e94d4 100644 --- a/arch/tile/include/asm/processor.h +++ b/arch/tile/include/asm/processor.h | |||
@@ -148,9 +148,10 @@ struct thread_struct { | |||
148 | 148 | ||
149 | /* | 149 | /* |
150 | * Start with "sp" this many bytes below the top of the kernel stack. | 150 | * Start with "sp" this many bytes below the top of the kernel stack. |
151 | * This preserves the invariant that a called function may write to *sp. | 151 | * This allows us to be cache-aware when handling the initial save |
152 | * of the pt_regs value to the stack. | ||
152 | */ | 153 | */ |
153 | #define STACK_TOP_DELTA 8 | 154 | #define STACK_TOP_DELTA 64 |
154 | 155 | ||
155 | /* | 156 | /* |
156 | * When entering the kernel via a fault, start with the top of the | 157 | * When entering the kernel via a fault, start with the top of the |
@@ -234,15 +235,15 @@ extern int do_work_pending(struct pt_regs *regs, u32 flags); | |||
234 | unsigned long get_wchan(struct task_struct *p); | 235 | unsigned long get_wchan(struct task_struct *p); |
235 | 236 | ||
236 | /* Return initial ksp value for given task. */ | 237 | /* Return initial ksp value for given task. */ |
237 | #define task_ksp0(task) ((unsigned long)(task)->stack + THREAD_SIZE) | 238 | #define task_ksp0(task) \ |
239 | ((unsigned long)(task)->stack + THREAD_SIZE - STACK_TOP_DELTA) | ||
238 | 240 | ||
239 | /* Return some info about the user process TASK. */ | 241 | /* Return some info about the user process TASK. */ |
240 | #define KSTK_TOP(task) (task_ksp0(task) - STACK_TOP_DELTA) | ||
241 | #define task_pt_regs(task) \ | 242 | #define task_pt_regs(task) \ |
242 | ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1) | 243 | ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1) |
243 | #define current_pt_regs() \ | 244 | #define current_pt_regs() \ |
244 | ((struct pt_regs *)((stack_pointer | (THREAD_SIZE - 1)) - \ | 245 | ((struct pt_regs *)((stack_pointer | (THREAD_SIZE - 1)) - \ |
245 | (KSTK_PTREGS_GAP - 1)) - 1) | 246 | STACK_TOP_DELTA - (KSTK_PTREGS_GAP - 1)) - 1) |
246 | #define task_sp(task) (task_pt_regs(task)->sp) | 247 | #define task_sp(task) (task_pt_regs(task)->sp) |
247 | #define task_pc(task) (task_pt_regs(task)->pc) | 248 | #define task_pc(task) (task_pt_regs(task)->pc) |
248 | /* Aliases for pc and sp (used in fs/proc/array.c) */ | 249 | /* Aliases for pc and sp (used in fs/proc/array.c) */ |
@@ -355,20 +356,38 @@ extern int kdata_huge; | |||
355 | #define KERNEL_PL CONFIG_KERNEL_PL | 356 | #define KERNEL_PL CONFIG_KERNEL_PL |
356 | 357 | ||
357 | /* SYSTEM_SAVE_K_0 holds the current cpu number ORed with ksp0. */ | 358 | /* SYSTEM_SAVE_K_0 holds the current cpu number ORed with ksp0. */ |
358 | #define CPU_LOG_MASK_VALUE 12 | 359 | #ifdef __tilegx__ |
359 | #define CPU_MASK_VALUE ((1 << CPU_LOG_MASK_VALUE) - 1) | 360 | #define CPU_SHIFT 48 |
360 | #if CONFIG_NR_CPUS > CPU_MASK_VALUE | 361 | #if CHIP_VA_WIDTH() > CPU_SHIFT |
361 | # error Too many cpus! | 362 | # error Too many VA bits! |
362 | #endif | 363 | #endif |
364 | #define MAX_CPU_ID ((1 << (64 - CPU_SHIFT)) - 1) | ||
363 | #define raw_smp_processor_id() \ | 365 | #define raw_smp_processor_id() \ |
364 | ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & CPU_MASK_VALUE) | 366 | ((int)(__insn_mfspr(SPR_SYSTEM_SAVE_K_0) >> CPU_SHIFT)) |
365 | #define get_current_ksp0() \ | 367 | #define get_current_ksp0() \ |
366 | (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~CPU_MASK_VALUE) | 368 | ((unsigned long)(((long)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) << \ |
369 | (64 - CPU_SHIFT)) >> (64 - CPU_SHIFT))) | ||
370 | #define next_current_ksp0(task) ({ \ | ||
371 | unsigned long __ksp0 = task_ksp0(task) & ((1UL << CPU_SHIFT) - 1); \ | ||
372 | unsigned long __cpu = (long)raw_smp_processor_id() << CPU_SHIFT; \ | ||
373 | __ksp0 | __cpu; \ | ||
374 | }) | ||
375 | #else | ||
376 | #define LOG2_NR_CPU_IDS 6 | ||
377 | #define MAX_CPU_ID ((1 << LOG2_NR_CPU_IDS) - 1) | ||
378 | #define raw_smp_processor_id() \ | ||
379 | ((int)__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & MAX_CPU_ID) | ||
380 | #define get_current_ksp0() \ | ||
381 | (__insn_mfspr(SPR_SYSTEM_SAVE_K_0) & ~MAX_CPU_ID) | ||
367 | #define next_current_ksp0(task) ({ \ | 382 | #define next_current_ksp0(task) ({ \ |
368 | unsigned long __ksp0 = task_ksp0(task); \ | 383 | unsigned long __ksp0 = task_ksp0(task); \ |
369 | int __cpu = raw_smp_processor_id(); \ | 384 | int __cpu = raw_smp_processor_id(); \ |
370 | BUG_ON(__ksp0 & CPU_MASK_VALUE); \ | 385 | BUG_ON(__ksp0 & MAX_CPU_ID); \ |
371 | __ksp0 | __cpu; \ | 386 | __ksp0 | __cpu; \ |
372 | }) | 387 | }) |
388 | #endif | ||
389 | #if CONFIG_NR_CPUS > (MAX_CPU_ID + 1) | ||
390 | # error Too many cpus! | ||
391 | #endif | ||
373 | 392 | ||
374 | #endif /* _ASM_TILE_PROCESSOR_H */ | 393 | #endif /* _ASM_TILE_PROCESSOR_H */ |