aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2012-09-07 16:57:17 -0400
committerKumar Gala <galak@kernel.crashing.org>2013-03-12 16:59:26 -0400
commitcd66cc2ee52bca82f1b06e2fbc1ce63f33700190 (patch)
tree8c180e8049b4e91e27863c210d4b6a4d1a3784c6
parent1b29187315993cc34e9c73d4d8a0887a10cd8998 (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>
-rw-r--r--arch/powerpc/include/asm/cputable.h2
-rw-r--r--arch/powerpc/include/asm/kvm_asm.h4
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S16
-rw-r--r--arch/powerpc/kernel/cputable.c9
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S47
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype2
6 files changed, 75 insertions, 5 deletions
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index fb3245e928ea..f3264445d09f 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -374,7 +374,7 @@ extern const char *powerpc_base_platform;
374#define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 374#define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
375 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 375 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
376 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 376 CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
377 CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV) 377 CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP)
378#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) 378#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
379 379
380/* 64-bit CPUs */ 380/* 64-bit CPUs */
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index aabcdba8f6b0..b9dd382cb349 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -67,6 +67,10 @@
67#define BOOKE_INTERRUPT_HV_SYSCALL 40 67#define BOOKE_INTERRUPT_HV_SYSCALL 40
68#define BOOKE_INTERRUPT_HV_PRIV 41 68#define BOOKE_INTERRUPT_HV_PRIV 41
69 69
70/* altivec */
71#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42
72#define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43
73
70/* book3s */ 74/* book3s */
71 75
72#define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 76#define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100
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)
76extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); 76extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec);
77extern void __setup_cpu_e6500(unsigned long offset, struct cpu_spec* spec);
77extern void __restore_cpu_e5500(void); 78extern void __restore_cpu_e5500(void);
79extern 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
407BEGIN_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
4131:
414END_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
430BEGIN_FTR_SECTION
431 bl .altivec_assist_exception
432END_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:
807BAD_STACK_TRAMPOLINE(0x000) 848BAD_STACK_TRAMPOLINE(0x000)
808BAD_STACK_TRAMPOLINE(0x100) 849BAD_STACK_TRAMPOLINE(0x100)
809BAD_STACK_TRAMPOLINE(0x200) 850BAD_STACK_TRAMPOLINE(0x200)
851BAD_STACK_TRAMPOLINE(0x220)
810BAD_STACK_TRAMPOLINE(0x260) 852BAD_STACK_TRAMPOLINE(0x260)
811BAD_STACK_TRAMPOLINE(0x280) 853BAD_STACK_TRAMPOLINE(0x280)
812BAD_STACK_TRAMPOLINE(0x2a0) 854BAD_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
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index cea2f09c4241..6dfdb658c9f8 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -232,7 +232,7 @@ config PHYS_64BIT
232 232
233config ALTIVEC 233config ALTIVEC
234 bool "AltiVec Support" 234 bool "AltiVec Support"
235 depends on 6xx || POWER4 235 depends on 6xx || POWER4 || (PPC_E500MC && PPC64)
236 ---help--- 236 ---help---
237 This option enables kernel support for the Altivec extensions to the 237 This option enables kernel support for the Altivec extensions to the
238 PowerPC processor. The kernel currently supports saving and restoring 238 PowerPC processor. The kernel currently supports saving and restoring