diff options
author | Ian Munsie <imunsie@au1.ibm.com> | 2013-02-07 10:46:58 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-02-07 22:05:50 -0500 |
commit | 2468dcf641e4f3e1b0153e3e11ca20740b2f4ce8 (patch) | |
tree | 02a1ca877b20fd0975befc2554957ee4b535a6a0 | |
parent | 14b6f00f8a4fdec5ccd45a0710284de301a61628 (diff) |
powerpc: Add support for context switching the TAR register
This patch adds support for enabling and context switching the Target
Address Register in Power8. The TAR is a new special purpose register
that can be used for computed branches with the bctar[l] (branch
conditional to TAR) instruction in the same manner as the count and link
registers.
Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Matt Evans <matt@ozlabs.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/include/asm/cputable.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 3 | ||||
-rw-r--r-- | arch/powerpc/include/asm/reg.h | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_power.S | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 20 |
6 files changed, 38 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 06f7fb93c547..5f1938fcce40 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h | |||
@@ -414,7 +414,7 @@ extern const char *powerpc_base_platform; | |||
414 | CPU_FTR_DSCR | CPU_FTR_SAO | \ | 414 | CPU_FTR_DSCR | CPU_FTR_SAO | \ |
415 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ | 415 | CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ |
416 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ | 416 | CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ |
417 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR) | 417 | CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | CPU_FTR_BCTAR) |
418 | #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ | 418 | #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ |
419 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ | 419 | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ |
420 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ | 420 | CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 7938658c168d..42ac53cebacd 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -257,6 +257,9 @@ struct thread_struct { | |||
257 | int dscr_inherit; | 257 | int dscr_inherit; |
258 | unsigned long ppr; /* used to save/restore SMT priority */ | 258 | unsigned long ppr; /* used to save/restore SMT priority */ |
259 | #endif | 259 | #endif |
260 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
261 | unsigned long tar; | ||
262 | #endif | ||
260 | }; | 263 | }; |
261 | 264 | ||
262 | #define ARCH_MIN_TASKALIGN 16 | 265 | #define ARCH_MIN_TASKALIGN 16 |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 1f59fbb7b054..e09ac51961d7 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -237,6 +237,9 @@ | |||
237 | #define SPRN_HRMOR 0x139 /* Real mode offset register */ | 237 | #define SPRN_HRMOR 0x139 /* Real mode offset register */ |
238 | #define SPRN_HSRR0 0x13A /* Hypervisor Save/Restore 0 */ | 238 | #define SPRN_HSRR0 0x13A /* Hypervisor Save/Restore 0 */ |
239 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ | 239 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ |
240 | #define SPRN_FSCR 0x099 /* Facility Status & Control Register */ | ||
241 | #define FSCR_TAR (1<<8) /* Enable Target Adress Register */ | ||
242 | #define SPRN_TAR 0x32f /* Target Address Register */ | ||
240 | #define SPRN_LPCR 0x13E /* LPAR Control Register */ | 243 | #define SPRN_LPCR 0x13E /* LPAR Control Register */ |
241 | #define LPCR_VPM0 (1ul << (63-0)) | 244 | #define LPCR_VPM0 (1ul << (63-0)) |
242 | #define LPCR_VPM1 (1ul << (63-1)) | 245 | #define LPCR_VPM1 (1ul << (63-1)) |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index e39ca556e87f..beddba432518 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -122,6 +122,10 @@ int main(void) | |||
122 | DEFINE(THREAD_KVM_VCPU, offsetof(struct thread_struct, kvm_vcpu)); | 122 | DEFINE(THREAD_KVM_VCPU, offsetof(struct thread_struct, kvm_vcpu)); |
123 | #endif | 123 | #endif |
124 | 124 | ||
125 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
126 | DEFINE(THREAD_TAR, offsetof(struct thread_struct, tar)); | ||
127 | #endif | ||
128 | |||
125 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | 129 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); |
126 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); | 130 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); |
127 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); | 131 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); |
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index 57cf14065aec..d29facbf9a28 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
@@ -56,6 +56,7 @@ _GLOBAL(__setup_cpu_power8) | |||
56 | mfspr r3,SPRN_LPCR | 56 | mfspr r3,SPRN_LPCR |
57 | oris r3, r3, LPCR_AIL_3@h | 57 | oris r3, r3, LPCR_AIL_3@h |
58 | bl __init_LPCR | 58 | bl __init_LPCR |
59 | bl __init_FSCR | ||
59 | bl __init_TLB | 60 | bl __init_TLB |
60 | mtlr r11 | 61 | mtlr r11 |
61 | blr | 62 | blr |
@@ -112,6 +113,12 @@ __init_LPCR: | |||
112 | isync | 113 | isync |
113 | blr | 114 | blr |
114 | 115 | ||
116 | __init_FSCR: | ||
117 | mfspr r3,SPRN_FSCR | ||
118 | ori r3,r3,FSCR_TAR | ||
119 | mtspr SPRN_FSCR,r3 | ||
120 | blr | ||
121 | |||
115 | __init_TLB: | 122 | __init_TLB: |
116 | /* Clear the TLB */ | 123 | /* Clear the TLB */ |
117 | li r6,128 | 124 | li r6,128 |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 44c733f4f829..9ae8451bbc83 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -448,6 +448,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR) | |||
448 | std r23,_CCR(r1) | 448 | std r23,_CCR(r1) |
449 | std r1,KSP(r3) /* Set old stack pointer */ | 449 | std r1,KSP(r3) /* Set old stack pointer */ |
450 | 450 | ||
451 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
452 | BEGIN_FTR_SECTION | ||
453 | /* | ||
454 | * Back up the TAR across context switches. Note that the TAR is not | ||
455 | * available for use in the kernel. (To provide this, the TAR should | ||
456 | * be backed up/restored on exception entry/exit instead, and be in | ||
457 | * pt_regs. FIXME, this should be in pt_regs anyway (for debug).) | ||
458 | */ | ||
459 | mfspr r0,SPRN_TAR | ||
460 | std r0,THREAD_TAR(r3) | ||
461 | END_FTR_SECTION_IFSET(CPU_FTR_BCTAR) | ||
462 | #endif | ||
463 | |||
451 | #ifdef CONFIG_SMP | 464 | #ifdef CONFIG_SMP |
452 | /* We need a sync somewhere here to make sure that if the | 465 | /* We need a sync somewhere here to make sure that if the |
453 | * previous task gets rescheduled on another CPU, it sees all | 466 | * previous task gets rescheduled on another CPU, it sees all |
@@ -530,6 +543,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) | |||
530 | mr r1,r8 /* start using new stack pointer */ | 543 | mr r1,r8 /* start using new stack pointer */ |
531 | std r7,PACAKSAVE(r13) | 544 | std r7,PACAKSAVE(r13) |
532 | 545 | ||
546 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
547 | BEGIN_FTR_SECTION | ||
548 | ld r0,THREAD_TAR(r4) | ||
549 | mtspr SPRN_TAR,r0 | ||
550 | END_FTR_SECTION_IFSET(CPU_FTR_BCTAR) | ||
551 | #endif | ||
552 | |||
533 | #ifdef CONFIG_ALTIVEC | 553 | #ifdef CONFIG_ALTIVEC |
534 | BEGIN_FTR_SECTION | 554 | BEGIN_FTR_SECTION |
535 | ld r0,THREAD_VRSAVE(r4) | 555 | ld r0,THREAD_VRSAVE(r4) |