diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2007-09-13 02:44:20 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2007-09-14 09:53:30 -0400 |
commit | 5e14d21e3f28a4181dacff0336040e30942f4921 (patch) | |
tree | ebaa8217d5af80e15116960641a0bf87a8b5d717 /arch | |
parent | d8f1324a5063c833862328ceafabc53ac3cc4f71 (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/cputable.c | 23 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_32.S | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 15 | ||||
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 6 |
4 files changed, 24 insertions, 24 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 | |||
80 | static struct cpu_spec cpu_specs[] = { | 71 | static 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 | |||
504 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 504 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
505 | #endif /* CONFIG_ALTIVEC */ | 505 | #endif /* CONFIG_ALTIVEC */ |
506 | #ifdef CONFIG_SPE | 506 | #ifdef CONFIG_SPE |
507 | BEGIN_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) |
511 | END_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 | |||
542 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 544 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
543 | #endif /* CONFIG_ALTIVEC */ | 545 | #endif /* CONFIG_ALTIVEC */ |
544 | #ifdef CONFIG_SPE | 546 | #ifdef CONFIG_SPE |
547 | BEGIN_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 */ |
550 | END_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 |