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>
This commit is contained in:
@@ -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 @@
|
|||||||
#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)
|
|||||||
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)
|
|||||||
#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);
|
|||||||
#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[] = {
|
|||||||
.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[] = {
|
|||||||
.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 */
|
|||||||
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:
|
|||||||
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:
|
|||||||
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)
|
|||||||
|
|
||||||
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
|
|||||||
|
|
||||||
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
|
||||||
|
Reference in New Issue
Block a user