powerpc/85xx: Add AltiVec support for e6500
authorKumar Gala <galak@kernel.crashing.org>
Fri, 7 Sep 2012 20:57:17 +0000 (15:57 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Tue, 12 Mar 2013 20:59:26 +0000 (15:59 -0500)
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>
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/kvm_asm.h
arch/powerpc/kernel/cpu_setup_fsl_booke.S
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/platforms/Kconfig.cputype

index fb3245e928eabfe3152eaa49f2139fd84d906bef..f3264445d09fd73c8c8cea9c4938b1ec92905e5c 100644 (file)
@@ -374,7 +374,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
            CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
            CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
-           CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV)
+           CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP)
 #define CPU_FTRS_GENERIC_32    (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
 
 /* 64-bit CPUs */
index aabcdba8f6b0faedd974d0980041d3e88bc1167f..b9dd382cb349bd651f214eae662f13556f6c8b5a 100644 (file)
 #define BOOKE_INTERRUPT_HV_SYSCALL 40
 #define BOOKE_INTERRUPT_HV_PRIV 41
 
+/* altivec */
+#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42
+#define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43
+
 /* book3s */
 
 #define BOOK3S_INTERRUPT_SYSTEM_RESET  0x100
index dcd881937f7a9217c2c6b7843d218a1d6b777970..0b9af015bedcb8382350efe5066779930607044b 100644 (file)
@@ -53,6 +53,15 @@ _GLOBAL(__e500_dcache_setup)
        isync
        blr
 
+_GLOBAL(__setup_cpu_e6500)
+       mflr    r6
+#ifdef CONFIG_PPC64
+       bl      .setup_altivec_ivors
+#endif
+       bl      __setup_cpu_e5500
+       mtlr    r6
+       blr
+
 #ifdef CONFIG_PPC32
 _GLOBAL(__setup_cpu_e200)
        /* enable dedicated debug exception handling resources (Debug APU) */
@@ -107,6 +116,13 @@ _GLOBAL(__setup_cpu_e5500)
 #endif
 
 #ifdef CONFIG_PPC_BOOK3E_64
+_GLOBAL(__restore_cpu_e6500)
+       mflr    r5
+       bl      .setup_altivec_ivors
+       bl      __restore_cpu_e5500
+       mtlr    r5
+       blr
+
 _GLOBAL(__restore_cpu_e5500)
        mflr    r4
        bl      __e500_icache_setup
index 75a3d71b895d985e20307bdd90dda88e4449ed9c..cc39139233d7c89a1bfeb5c1ef7e8171c723271f 100644 (file)
@@ -74,7 +74,9 @@ extern void __restore_cpu_a2(void);
 #endif /* CONFIG_PPC64 */
 #if defined(CONFIG_E500)
 extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_e6500(unsigned long offset, struct cpu_spec* spec);
 extern void __restore_cpu_e5500(void);
+extern void __restore_cpu_e6500(void);
 #endif /* CONFIG_E500 */
 
 /* This table only contains "desktop" CPUs, it need to be filled with embedded
@@ -2065,7 +2067,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .pvr_value              = 0x80400000,
                .cpu_name               = "e6500",
                .cpu_features           = CPU_FTRS_E6500,
-               .cpu_user_features      = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
+               .cpu_user_features      = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP,
                .mmu_features           = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS |
                        MMU_FTR_USE_TLBILX,
                .icache_bsize           = 64,
@@ -2073,9 +2076,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .num_pmcs               = 4,
                .oprofile_cpu_type      = "ppc/e6500",
                .oprofile_type          = PPC_OPROFILE_FSL_EMB,
-               .cpu_setup              = __setup_cpu_e5500,
+               .cpu_setup              = __setup_cpu_e6500,
 #ifndef CONFIG_PPC32
-               .cpu_restore            = __restore_cpu_e5500,
+               .cpu_restore            = __restore_cpu_e6500,
 #endif
                .machine_check          = machine_check_e500mc,
                .platform               = "ppce6500",
index ae54553eacd940ab7f1919c5921c2ca82b443840..42a756eec9ff7ea6a240bbef197e6519b1abd008 100644 (file)
@@ -299,6 +299,8 @@ interrupt_base_book3e:                                      /* fake trap */
        EXCEPTION_STUB(0x1a0, watchdog)                 /* 0x09f0 */
        EXCEPTION_STUB(0x1c0, data_tlb_miss)
        EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
+       EXCEPTION_STUB(0x200, altivec_unavailable)      /* 0x0f20 */
+       EXCEPTION_STUB(0x220, altivec_assist)           /* 0x1700 */
        EXCEPTION_STUB(0x260, perfmon)
        EXCEPTION_STUB(0x280, doorbell)
        EXCEPTION_STUB(0x2a0, doorbell_crit)
@@ -395,6 +397,45 @@ interrupt_end_book3e:
        bl      .kernel_fp_unavailable_exception
        b       .ret_from_except
 
+/* Altivec Unavailable Interrupt */
+       START_EXCEPTION(altivec_unavailable);
+       NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL,
+                               PROLOG_ADDITION_NONE)
+       /* we can probably do a shorter exception entry for that one... */
+       EXCEPTION_COMMON(0x200, PACA_EXGEN, INTS_KEEP)
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+       ld      r12,_MSR(r1)
+       andi.   r0,r12,MSR_PR;
+       beq-    1f
+       bl      .load_up_altivec
+       b       fast_exception_return
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
+       INTS_DISABLE
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .altivec_unavailable_exception
+       b       .ret_from_except
+
+/* AltiVec Assist */
+       START_EXCEPTION(altivec_assist);
+       NORMAL_EXCEPTION_PROLOG(0x220, BOOKE_INTERRUPT_ALTIVEC_ASSIST,
+                               PROLOG_ADDITION_NONE)
+       EXCEPTION_COMMON(0x220, PACA_EXGEN, INTS_DISABLE)
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+       bl      .altivec_assist_exception
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#else
+       bl      .unknown_exception
+#endif
+       b       .ret_from_except
+
+
 /* Decrementer Interrupt */
        MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER,
                           decrementer, .timer_interrupt, ACK_DEC)
@@ -807,6 +848,7 @@ fast_exception_return:
 BAD_STACK_TRAMPOLINE(0x000)
 BAD_STACK_TRAMPOLINE(0x100)
 BAD_STACK_TRAMPOLINE(0x200)
+BAD_STACK_TRAMPOLINE(0x220)
 BAD_STACK_TRAMPOLINE(0x260)
 BAD_STACK_TRAMPOLINE(0x280)
 BAD_STACK_TRAMPOLINE(0x2a0)
@@ -1350,6 +1392,11 @@ _GLOBAL(__setup_base_ivors)
 
        blr
 
+_GLOBAL(setup_altivec_ivors)
+       SET_IVOR(32, 0x200) /* AltiVec Unavailable */
+       SET_IVOR(33, 0x220) /* AltiVec Assist */
+       blr
+
 _GLOBAL(setup_perfmon_ivor)
        SET_IVOR(35, 0x260) /* Performance Monitor */
        blr
index cea2f09c42418d101c78b445b18c9286a714b53b..6dfdb658c9f88dd17ec843e6508401695d1a74f8 100644 (file)
@@ -232,7 +232,7 @@ config PHYS_64BIT
 
 config ALTIVEC
        bool "AltiVec Support"
-       depends on 6xx || POWER4
+       depends on 6xx || POWER4 || (PPC_E500MC && PPC64)
        ---help---
          This option enables kernel support for the Altivec extensions to the
          PowerPC processor. The kernel currently supports saving and restoring