aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2007-09-13 02:44:20 -0400
committerKumar Gala <galak@kernel.crashing.org>2007-09-14 09:53:30 -0400
commit5e14d21e3f28a4181dacff0336040e30942f4921 (patch)
treeebaa8217d5af80e15116960641a0bf87a8b5d717
parentd8f1324a5063c833862328ceafabc53ac3cc4f71 (diff)
[POWERPC] Add cpu feature for SPE handling
Make it so that SPE support can be determined at runtime. This is similiar to how we handle AltiVec. This allows us to have SPE support built in and work on processors with and without SPE. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/cputable.c23
-rw-r--r--arch/powerpc/kernel/entry_32.S4
-rw-r--r--arch/powerpc/kernel/process.c15
-rw-r--r--arch/powerpc/kernel/ptrace.c6
-rw-r--r--include/asm-powerpc/cputable.h26
5 files changed, 46 insertions, 28 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 5873073c9045..8eb8087383eb 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -68,15 +68,6 @@ extern void __restore_cpu_ppc970(void);
68#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ 68#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
69 PPC_FEATURE_BOOKE) 69 PPC_FEATURE_BOOKE)
70 70
71/* We only set the spe features if the kernel was compiled with
72 * spe support
73 */
74#ifdef CONFIG_SPE
75#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE
76#else
77#define PPC_FEATURE_SPE_COMP 0
78#endif
79
80static struct cpu_spec cpu_specs[] = { 71static struct cpu_spec cpu_specs[] = {
81#ifdef CONFIG_PPC64 72#ifdef CONFIG_PPC64
82 { /* Power3 */ 73 { /* Power3 */
@@ -1261,8 +1252,8 @@ static struct cpu_spec cpu_specs[] = {
1261 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ 1252 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
1262 .cpu_features = CPU_FTRS_E200, 1253 .cpu_features = CPU_FTRS_E200,
1263 .cpu_user_features = COMMON_USER_BOOKE | 1254 .cpu_user_features = COMMON_USER_BOOKE |
1264 PPC_FEATURE_SPE_COMP | 1255 PPC_FEATURE_HAS_SPE_COMP |
1265 PPC_FEATURE_HAS_EFP_SINGLE | 1256 PPC_FEATURE_HAS_EFP_SINGLE_COMP |
1266 PPC_FEATURE_UNIFIED_CACHE, 1257 PPC_FEATURE_UNIFIED_CACHE,
1267 .dcache_bsize = 32, 1258 .dcache_bsize = 32,
1268 .platform = "ppc5554", 1259 .platform = "ppc5554",
@@ -1274,8 +1265,8 @@ static struct cpu_spec cpu_specs[] = {
1274 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ 1265 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
1275 .cpu_features = CPU_FTRS_E500, 1266 .cpu_features = CPU_FTRS_E500,
1276 .cpu_user_features = COMMON_USER_BOOKE | 1267 .cpu_user_features = COMMON_USER_BOOKE |
1277 PPC_FEATURE_SPE_COMP | 1268 PPC_FEATURE_HAS_SPE_COMP |
1278 PPC_FEATURE_HAS_EFP_SINGLE, 1269 PPC_FEATURE_HAS_EFP_SINGLE_COMP,
1279 .icache_bsize = 32, 1270 .icache_bsize = 32,
1280 .dcache_bsize = 32, 1271 .dcache_bsize = 32,
1281 .num_pmcs = 4, 1272 .num_pmcs = 4,
@@ -1290,9 +1281,9 @@ static struct cpu_spec cpu_specs[] = {
1290 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ 1281 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
1291 .cpu_features = CPU_FTRS_E500_2, 1282 .cpu_features = CPU_FTRS_E500_2,
1292 .cpu_user_features = COMMON_USER_BOOKE | 1283 .cpu_user_features = COMMON_USER_BOOKE |
1293 PPC_FEATURE_SPE_COMP | 1284 PPC_FEATURE_HAS_SPE_COMP |
1294 PPC_FEATURE_HAS_EFP_SINGLE | 1285 PPC_FEATURE_HAS_EFP_SINGLE_COMP |
1295 PPC_FEATURE_HAS_EFP_DOUBLE, 1286 PPC_FEATURE_HAS_EFP_DOUBLE_COMP,
1296 .icache_bsize = 32, 1287 .icache_bsize = 32,
1297 .dcache_bsize = 32, 1288 .dcache_bsize = 32,
1298 .num_pmcs = 4, 1289 .num_pmcs = 4,
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 4074c0b31453..21d889e63e87 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -504,9 +504,11 @@ BEGIN_FTR_SECTION
504END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 504END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
505#endif /* CONFIG_ALTIVEC */ 505#endif /* CONFIG_ALTIVEC */
506#ifdef CONFIG_SPE 506#ifdef CONFIG_SPE
507BEGIN_FTR_SECTION
507 oris r0,r0,MSR_SPE@h /* Disable SPE */ 508 oris r0,r0,MSR_SPE@h /* Disable SPE */
508 mfspr r12,SPRN_SPEFSCR /* save spefscr register value */ 509 mfspr r12,SPRN_SPEFSCR /* save spefscr register value */
509 stw r12,THREAD+THREAD_SPEFSCR(r2) 510 stw r12,THREAD+THREAD_SPEFSCR(r2)
511END_FTR_SECTION_IFSET(CPU_FTR_SPE)
510#endif /* CONFIG_SPE */ 512#endif /* CONFIG_SPE */
511 and. r0,r0,r11 /* FP or altivec or SPE enabled? */ 513 and. r0,r0,r11 /* FP or altivec or SPE enabled? */
512 beq+ 1f 514 beq+ 1f
@@ -542,8 +544,10 @@ BEGIN_FTR_SECTION
542END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 544END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
543#endif /* CONFIG_ALTIVEC */ 545#endif /* CONFIG_ALTIVEC */
544#ifdef CONFIG_SPE 546#ifdef CONFIG_SPE
547BEGIN_FTR_SECTION
545 lwz r0,THREAD+THREAD_SPEFSCR(r2) 548 lwz r0,THREAD+THREAD_SPEFSCR(r2)
546 mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */ 549 mtspr SPRN_SPEFSCR,r0 /* restore SPEFSCR reg */
550END_FTR_SECTION_IFSET(CPU_FTR_SPE)
547#endif /* CONFIG_SPE */ 551#endif /* CONFIG_SPE */
548 552
549 lwz r0,_CCR(r1) 553 lwz r0,_CCR(r1)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index e477c9d0498b..57c589c34147 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -669,9 +669,13 @@ int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
669 * mode (asyn, precise, disabled) for 'Classic' FP. */ 669 * mode (asyn, precise, disabled) for 'Classic' FP. */
670 if (val & PR_FP_EXC_SW_ENABLE) { 670 if (val & PR_FP_EXC_SW_ENABLE) {
671#ifdef CONFIG_SPE 671#ifdef CONFIG_SPE
672 tsk->thread.fpexc_mode = val & 672 if (cpu_has_feature(CPU_FTR_SPE)) {
673 (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT); 673 tsk->thread.fpexc_mode = val &
674 return 0; 674 (PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
675 return 0;
676 } else {
677 return -EINVAL;
678 }
675#else 679#else
676 return -EINVAL; 680 return -EINVAL;
677#endif 681#endif
@@ -697,7 +701,10 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
697 701
698 if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE) 702 if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
699#ifdef CONFIG_SPE 703#ifdef CONFIG_SPE
700 val = tsk->thread.fpexc_mode; 704 if (cpu_has_feature(CPU_FTR_SPE))
705 val = tsk->thread.fpexc_mode;
706 else
707 return -EINVAL;
701#else 708#else
702 return -EINVAL; 709 return -EINVAL;
703#endif 710#endif
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 8a177bd9eab4..fb8866e0e35d 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -576,8 +576,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
576#ifdef CONFIG_SPE 576#ifdef CONFIG_SPE
577 case PTRACE_GETEVRREGS: 577 case PTRACE_GETEVRREGS:
578 /* Get the child spe register state. */ 578 /* Get the child spe register state. */
579 if (child->thread.regs->msr & MSR_SPE) 579 flush_spe_to_thread(child);
580 giveup_spe(child);
581 ret = get_evrregs((unsigned long __user *)data, child); 580 ret = get_evrregs((unsigned long __user *)data, child);
582 break; 581 break;
583 582
@@ -585,8 +584,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
585 /* Set the child spe register state. */ 584 /* Set the child spe register state. */
586 /* this is to clear the MSR_SPE bit to force a reload 585 /* this is to clear the MSR_SPE bit to force a reload
587 * of register state from memory */ 586 * of register state from memory */
588 if (child->thread.regs->msr & MSR_SPE) 587 flush_spe_to_thread(child);
589 giveup_spe(child);
590 ret = set_evrregs(child, (unsigned long __user *)data); 588 ret = set_evrregs(child, (unsigned long __user *)data);
591 break; 589 break;
592#endif 590#endif
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 3dc8e2dfca84..f62cffd56c0c 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -136,6 +136,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
136#define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000) 136#define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000)
137#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x0000000000800000) 137#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x0000000000800000)
138#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000) 138#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000)
139#define CPU_FTR_SPE ASM_CONST(0x0000000002000000)
139 140
140/* 141/*
141 * Add the 64-bit processor unique features in the top half of the word; 142 * Add the 64-bit processor unique features in the top half of the word;
@@ -180,6 +181,21 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
180#define PPC_FEATURE_HAS_ALTIVEC_COMP 0 181#define PPC_FEATURE_HAS_ALTIVEC_COMP 0
181#endif 182#endif
182 183
184/* We only set the spe features if the kernel was compiled with spe
185 * support
186 */
187#ifdef CONFIG_SPE
188#define CPU_FTR_SPE_COMP CPU_FTR_SPE
189#define PPC_FEATURE_HAS_SPE_COMP PPC_FEATURE_HAS_SPE
190#define PPC_FEATURE_HAS_EFP_SINGLE_COMP PPC_FEATURE_HAS_EFP_SINGLE
191#define PPC_FEATURE_HAS_EFP_DOUBLE_COMP PPC_FEATURE_HAS_EFP_DOUBLE
192#else
193#define CPU_FTR_SPE_COMP 0
194#define PPC_FEATURE_HAS_SPE_COMP 0
195#define PPC_FEATURE_HAS_EFP_SINGLE_COMP 0
196#define PPC_FEATURE_HAS_EFP_DOUBLE_COMP 0
197#endif
198
183/* We need to mark all pages as being coherent if we're SMP or we 199/* We need to mark all pages as being coherent if we're SMP or we
184 * have a 74[45]x and an MPC107 host bridge. Also 83xx requires 200 * have a 74[45]x and an MPC107 host bridge. Also 83xx requires
185 * it for PCI "streaming/prefetch" to work properly. 201 * it for PCI "streaming/prefetch" to work properly.
@@ -310,10 +326,12 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
310#define CPU_FTRS_8XX (CPU_FTR_USE_TB) 326#define CPU_FTRS_8XX (CPU_FTR_USE_TB)
311#define CPU_FTRS_40X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN) 327#define CPU_FTRS_40X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN)
312#define CPU_FTRS_44X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN) 328#define CPU_FTRS_44X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN)
313#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 329#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
314 CPU_FTR_COHERENT_ICACHE | CPU_FTR_UNIFIED_ID_CACHE) 330 CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
315#define CPU_FTRS_E500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN) 331 CPU_FTR_UNIFIED_ID_CACHE)
316#define CPU_FTRS_E500_2 (CPU_FTR_USE_TB | \ 332#define CPU_FTRS_E500 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
333 CPU_FTR_NODSISRALIGN)
334#define CPU_FTRS_E500_2 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
317 CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN) 335 CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN)
318#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) 336#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
319 337