Commit cd66cc2e authored by Kumar Gala's avatar Kumar Gala

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: default avatarKumar Gala <galak@kernel.crashing.org>
parent 1b291873
...@@ -374,7 +374,7 @@ extern const char *powerpc_base_platform; ...@@ -374,7 +374,7 @@ extern const char *powerpc_base_platform;
#define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ #define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ 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) #define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
/* 64-bit CPUs */ /* 64-bit CPUs */
......
...@@ -67,6 +67,10 @@ ...@@ -67,6 +67,10 @@
#define BOOKE_INTERRUPT_HV_SYSCALL 40 #define BOOKE_INTERRUPT_HV_SYSCALL 40
#define BOOKE_INTERRUPT_HV_PRIV 41 #define BOOKE_INTERRUPT_HV_PRIV 41
/* altivec */
#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42
#define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43
/* book3s */ /* book3s */
#define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100 #define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100
......
...@@ -53,6 +53,15 @@ _GLOBAL(__e500_dcache_setup) ...@@ -53,6 +53,15 @@ _GLOBAL(__e500_dcache_setup)
isync isync
blr 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 #ifdef CONFIG_PPC32
_GLOBAL(__setup_cpu_e200) _GLOBAL(__setup_cpu_e200)
/* enable dedicated debug exception handling resources (Debug APU) */ /* enable dedicated debug exception handling resources (Debug APU) */
...@@ -107,6 +116,13 @@ _GLOBAL(__setup_cpu_e5500) ...@@ -107,6 +116,13 @@ _GLOBAL(__setup_cpu_e5500)
#endif #endif
#ifdef CONFIG_PPC_BOOK3E_64 #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) _GLOBAL(__restore_cpu_e5500)
mflr r4 mflr r4
bl __e500_icache_setup bl __e500_icache_setup
......
...@@ -74,7 +74,9 @@ extern void __restore_cpu_a2(void); ...@@ -74,7 +74,9 @@ extern void __restore_cpu_a2(void);
#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC64 */
#if defined(CONFIG_E500) #if defined(CONFIG_E500)
extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec); 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_e5500(void);
extern void __restore_cpu_e6500(void);
#endif /* CONFIG_E500 */ #endif /* CONFIG_E500 */
/* This table only contains "desktop" CPUs, it need to be filled with embedded /* 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,7 +2067,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.pvr_value = 0x80400000, .pvr_value = 0x80400000,
.cpu_name = "e6500", .cpu_name = "e6500",
.cpu_features = CPU_FTRS_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_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS |
MMU_FTR_USE_TLBILX, MMU_FTR_USE_TLBILX,
.icache_bsize = 64, .icache_bsize = 64,
...@@ -2073,9 +2076,9 @@ static struct cpu_spec __initdata cpu_specs[] = { ...@@ -2073,9 +2076,9 @@ static struct cpu_spec __initdata cpu_specs[] = {
.num_pmcs = 4, .num_pmcs = 4,
.oprofile_cpu_type = "ppc/e6500", .oprofile_cpu_type = "ppc/e6500",
.oprofile_type = PPC_OPROFILE_FSL_EMB, .oprofile_type = PPC_OPROFILE_FSL_EMB,
.cpu_setup = __setup_cpu_e5500, .cpu_setup = __setup_cpu_e6500,
#ifndef CONFIG_PPC32 #ifndef CONFIG_PPC32
.cpu_restore = __restore_cpu_e5500, .cpu_restore = __restore_cpu_e6500,
#endif #endif
.machine_check = machine_check_e500mc, .machine_check = machine_check_e500mc,
.platform = "ppce6500", .platform = "ppce6500",
......
...@@ -299,6 +299,8 @@ interrupt_base_book3e: /* fake trap */ ...@@ -299,6 +299,8 @@ interrupt_base_book3e: /* fake trap */
EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */
EXCEPTION_STUB(0x1c0, data_tlb_miss) EXCEPTION_STUB(0x1c0, data_tlb_miss)
EXCEPTION_STUB(0x1e0, instruction_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(0x260, perfmon)
EXCEPTION_STUB(0x280, doorbell) EXCEPTION_STUB(0x280, doorbell)
EXCEPTION_STUB(0x2a0, doorbell_crit) EXCEPTION_STUB(0x2a0, doorbell_crit)
...@@ -395,6 +397,45 @@ interrupt_end_book3e: ...@@ -395,6 +397,45 @@ interrupt_end_book3e:
bl .kernel_fp_unavailable_exception bl .kernel_fp_unavailable_exception
b .ret_from_except 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 */ /* Decrementer Interrupt */
MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER,
decrementer, .timer_interrupt, ACK_DEC) decrementer, .timer_interrupt, ACK_DEC)
...@@ -807,6 +848,7 @@ fast_exception_return: ...@@ -807,6 +848,7 @@ fast_exception_return:
BAD_STACK_TRAMPOLINE(0x000) BAD_STACK_TRAMPOLINE(0x000)
BAD_STACK_TRAMPOLINE(0x100) BAD_STACK_TRAMPOLINE(0x100)
BAD_STACK_TRAMPOLINE(0x200) BAD_STACK_TRAMPOLINE(0x200)
BAD_STACK_TRAMPOLINE(0x220)
BAD_STACK_TRAMPOLINE(0x260) BAD_STACK_TRAMPOLINE(0x260)
BAD_STACK_TRAMPOLINE(0x280) BAD_STACK_TRAMPOLINE(0x280)
BAD_STACK_TRAMPOLINE(0x2a0) BAD_STACK_TRAMPOLINE(0x2a0)
...@@ -1350,6 +1392,11 @@ _GLOBAL(__setup_base_ivors) ...@@ -1350,6 +1392,11 @@ _GLOBAL(__setup_base_ivors)
blr blr
_GLOBAL(setup_altivec_ivors)
SET_IVOR(32, 0x200) /* AltiVec Unavailable */
SET_IVOR(33, 0x220) /* AltiVec Assist */
blr
_GLOBAL(setup_perfmon_ivor) _GLOBAL(setup_perfmon_ivor)
SET_IVOR(35, 0x260) /* Performance Monitor */ SET_IVOR(35, 0x260) /* Performance Monitor */
blr blr
......
...@@ -232,7 +232,7 @@ config PHYS_64BIT ...@@ -232,7 +232,7 @@ config PHYS_64BIT
config ALTIVEC config ALTIVEC
bool "AltiVec Support" bool "AltiVec Support"
depends on 6xx || POWER4 depends on 6xx || POWER4 || (PPC_E500MC && PPC64)
---help--- ---help---
This option enables kernel support for the Altivec extensions to the This option enables kernel support for the Altivec extensions to the
PowerPC processor. The kernel currently supports saving and restoring PowerPC processor. The kernel currently supports saving and restoring
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment