diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2012-09-07 16:57:17 -0400 |
---|---|---|
committer | Kumar Gala <galak@kernel.crashing.org> | 2013-03-12 16:59:26 -0400 |
commit | cd66cc2ee52bca82f1b06e2fbc1ce63f33700190 (patch) | |
tree | 8c180e8049b4e91e27863c210d4b6a4d1a3784c6 /arch/powerpc/kernel | |
parent | 1b29187315993cc34e9c73d4d8a0887a10cd8998 (diff) |
powerpc/85xx: Add AltiVec support for e6500
The e6500 core adds support for AltiVec on a Book-E class processor.
Connect up all the various exception handling code and build config
mechanisms to allow user spaces apps to utilize AltiVec.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_fsl_booke.S | 16 | ||||
-rw-r--r-- | arch/powerpc/kernel/cputable.c | 9 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64e.S | 47 |
3 files changed, 69 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index dcd881937f7a..0b9af015bedc 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S | |||
@@ -53,6 +53,15 @@ _GLOBAL(__e500_dcache_setup) | |||
53 | isync | 53 | isync |
54 | blr | 54 | blr |
55 | 55 | ||
56 | _GLOBAL(__setup_cpu_e6500) | ||
57 | mflr r6 | ||
58 | #ifdef CONFIG_PPC64 | ||
59 | bl .setup_altivec_ivors | ||
60 | #endif | ||
61 | bl __setup_cpu_e5500 | ||
62 | mtlr r6 | ||
63 | blr | ||
64 | |||
56 | #ifdef CONFIG_PPC32 | 65 | #ifdef CONFIG_PPC32 |
57 | _GLOBAL(__setup_cpu_e200) | 66 | _GLOBAL(__setup_cpu_e200) |
58 | /* enable dedicated debug exception handling resources (Debug APU) */ | 67 | /* enable dedicated debug exception handling resources (Debug APU) */ |
@@ -107,6 +116,13 @@ _GLOBAL(__setup_cpu_e5500) | |||
107 | #endif | 116 | #endif |
108 | 117 | ||
109 | #ifdef CONFIG_PPC_BOOK3E_64 | 118 | #ifdef CONFIG_PPC_BOOK3E_64 |
119 | _GLOBAL(__restore_cpu_e6500) | ||
120 | mflr r5 | ||
121 | bl .setup_altivec_ivors | ||
122 | bl __restore_cpu_e5500 | ||
123 | mtlr r5 | ||
124 | blr | ||
125 | |||
110 | _GLOBAL(__restore_cpu_e5500) | 126 | _GLOBAL(__restore_cpu_e5500) |
111 | mflr r4 | 127 | mflr r4 |
112 | bl __e500_icache_setup | 128 | bl __e500_icache_setup |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 75a3d71b895d..cc39139233d7 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -74,7 +74,9 @@ extern void __restore_cpu_a2(void); | |||
74 | #endif /* CONFIG_PPC64 */ | 74 | #endif /* CONFIG_PPC64 */ |
75 | #if defined(CONFIG_E500) | 75 | #if defined(CONFIG_E500) |
76 | extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); | 76 | extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); |
77 | extern void __setup_cpu_e6500(unsigned long offset, struct cpu_spec* spec); | ||
77 | extern void __restore_cpu_e5500(void); | 78 | extern void __restore_cpu_e5500(void); |
79 | extern void __restore_cpu_e6500(void); | ||
78 | #endif /* CONFIG_E500 */ | 80 | #endif /* CONFIG_E500 */ |
79 | 81 | ||
80 | /* This table only contains "desktop" CPUs, it need to be filled with embedded | 82 | /* This table only contains "desktop" CPUs, it need to be filled with embedded |
@@ -2065,7 +2067,8 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
2065 | .pvr_value = 0x80400000, | 2067 | .pvr_value = 0x80400000, |
2066 | .cpu_name = "e6500", | 2068 | .cpu_name = "e6500", |
2067 | .cpu_features = CPU_FTRS_E6500, | 2069 | .cpu_features = CPU_FTRS_E6500, |
2068 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 2070 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU | |
2071 | PPC_FEATURE_HAS_ALTIVEC_COMP, | ||
2069 | .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | | 2072 | .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | |
2070 | MMU_FTR_USE_TLBILX, | 2073 | MMU_FTR_USE_TLBILX, |
2071 | .icache_bsize = 64, | 2074 | .icache_bsize = 64, |
@@ -2073,9 +2076,9 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
2073 | .num_pmcs = 4, | 2076 | .num_pmcs = 4, |
2074 | .oprofile_cpu_type = "ppc/e6500", | 2077 | .oprofile_cpu_type = "ppc/e6500", |
2075 | .oprofile_type = PPC_OPROFILE_FSL_EMB, | 2078 | .oprofile_type = PPC_OPROFILE_FSL_EMB, |
2076 | .cpu_setup = __setup_cpu_e5500, | 2079 | .cpu_setup = __setup_cpu_e6500, |
2077 | #ifndef CONFIG_PPC32 | 2080 | #ifndef CONFIG_PPC32 |
2078 | .cpu_restore = __restore_cpu_e5500, | 2081 | .cpu_restore = __restore_cpu_e6500, |
2079 | #endif | 2082 | #endif |
2080 | .machine_check = machine_check_e500mc, | 2083 | .machine_check = machine_check_e500mc, |
2081 | .platform = "ppce6500", | 2084 | .platform = "ppce6500", |
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index ae54553eacd9..42a756eec9ff 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
@@ -299,6 +299,8 @@ interrupt_base_book3e: /* fake trap */ | |||
299 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ | 299 | EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ |
300 | EXCEPTION_STUB(0x1c0, data_tlb_miss) | 300 | EXCEPTION_STUB(0x1c0, data_tlb_miss) |
301 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) | 301 | EXCEPTION_STUB(0x1e0, instruction_tlb_miss) |
302 | EXCEPTION_STUB(0x200, altivec_unavailable) /* 0x0f20 */ | ||
303 | EXCEPTION_STUB(0x220, altivec_assist) /* 0x1700 */ | ||
302 | EXCEPTION_STUB(0x260, perfmon) | 304 | EXCEPTION_STUB(0x260, perfmon) |
303 | EXCEPTION_STUB(0x280, doorbell) | 305 | EXCEPTION_STUB(0x280, doorbell) |
304 | EXCEPTION_STUB(0x2a0, doorbell_crit) | 306 | EXCEPTION_STUB(0x2a0, doorbell_crit) |
@@ -395,6 +397,45 @@ interrupt_end_book3e: | |||
395 | bl .kernel_fp_unavailable_exception | 397 | bl .kernel_fp_unavailable_exception |
396 | b .ret_from_except | 398 | b .ret_from_except |
397 | 399 | ||
400 | /* Altivec Unavailable Interrupt */ | ||
401 | START_EXCEPTION(altivec_unavailable); | ||
402 | NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL, | ||
403 | PROLOG_ADDITION_NONE) | ||
404 | /* we can probably do a shorter exception entry for that one... */ | ||
405 | EXCEPTION_COMMON(0x200, PACA_EXGEN, INTS_KEEP) | ||
406 | #ifdef CONFIG_ALTIVEC | ||
407 | BEGIN_FTR_SECTION | ||
408 | ld r12,_MSR(r1) | ||
409 | andi. r0,r12,MSR_PR; | ||
410 | beq- 1f | ||
411 | bl .load_up_altivec | ||
412 | b fast_exception_return | ||
413 | 1: | ||
414 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | ||
415 | #endif | ||
416 | INTS_DISABLE | ||
417 | bl .save_nvgprs | ||
418 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
419 | bl .altivec_unavailable_exception | ||
420 | b .ret_from_except | ||
421 | |||
422 | /* AltiVec Assist */ | ||
423 | START_EXCEPTION(altivec_assist); | ||
424 | NORMAL_EXCEPTION_PROLOG(0x220, BOOKE_INTERRUPT_ALTIVEC_ASSIST, | ||
425 | PROLOG_ADDITION_NONE) | ||
426 | EXCEPTION_COMMON(0x220, PACA_EXGEN, INTS_DISABLE) | ||
427 | bl .save_nvgprs | ||
428 | addi r3,r1,STACK_FRAME_OVERHEAD | ||
429 | #ifdef CONFIG_ALTIVEC | ||
430 | BEGIN_FTR_SECTION | ||
431 | bl .altivec_assist_exception | ||
432 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | ||
433 | #else | ||
434 | bl .unknown_exception | ||
435 | #endif | ||
436 | b .ret_from_except | ||
437 | |||
438 | |||
398 | /* Decrementer Interrupt */ | 439 | /* Decrementer Interrupt */ |
399 | MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, | 440 | MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, |
400 | decrementer, .timer_interrupt, ACK_DEC) | 441 | decrementer, .timer_interrupt, ACK_DEC) |
@@ -807,6 +848,7 @@ fast_exception_return: | |||
807 | BAD_STACK_TRAMPOLINE(0x000) | 848 | BAD_STACK_TRAMPOLINE(0x000) |
808 | BAD_STACK_TRAMPOLINE(0x100) | 849 | BAD_STACK_TRAMPOLINE(0x100) |
809 | BAD_STACK_TRAMPOLINE(0x200) | 850 | BAD_STACK_TRAMPOLINE(0x200) |
851 | BAD_STACK_TRAMPOLINE(0x220) | ||
810 | BAD_STACK_TRAMPOLINE(0x260) | 852 | BAD_STACK_TRAMPOLINE(0x260) |
811 | BAD_STACK_TRAMPOLINE(0x280) | 853 | BAD_STACK_TRAMPOLINE(0x280) |
812 | BAD_STACK_TRAMPOLINE(0x2a0) | 854 | BAD_STACK_TRAMPOLINE(0x2a0) |
@@ -1350,6 +1392,11 @@ _GLOBAL(__setup_base_ivors) | |||
1350 | 1392 | ||
1351 | blr | 1393 | blr |
1352 | 1394 | ||
1395 | _GLOBAL(setup_altivec_ivors) | ||
1396 | SET_IVOR(32, 0x200) /* AltiVec Unavailable */ | ||
1397 | SET_IVOR(33, 0x220) /* AltiVec Assist */ | ||
1398 | blr | ||
1399 | |||
1353 | _GLOBAL(setup_perfmon_ivor) | 1400 | _GLOBAL(setup_perfmon_ivor) |
1354 | SET_IVOR(35, 0x260) /* Performance Monitor */ | 1401 | SET_IVOR(35, 0x260) /* Performance Monitor */ |
1355 | blr | 1402 | blr |