Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+75 -5
+1 -1
arch/powerpc/include/asm/cputable.h
··· 374 374 #define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ 375 375 CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ 376 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 378 #define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) 379 379 380 380 /* 64-bit CPUs */
+4
arch/powerpc/include/asm/kvm_asm.h
··· 67 67 #define BOOKE_INTERRUPT_HV_SYSCALL 40 68 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 74 /* book3s */ 71 75 72 76 #define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100
+16
arch/powerpc/kernel/cpu_setup_fsl_booke.S
··· 53 53 isync 54 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 65 #ifdef CONFIG_PPC32 57 66 _GLOBAL(__setup_cpu_e200) 58 67 /* enable dedicated debug exception handling resources (Debug APU) */ ··· 116 107 #endif 117 108 118 109 #ifdef CONFIG_PPC_BOOK3E_64 110 + _GLOBAL(__restore_cpu_e6500) 111 + mflr r5 112 + bl .setup_altivec_ivors 113 + bl __restore_cpu_e5500 114 + mtlr r5 115 + blr 116 + 119 117 _GLOBAL(__restore_cpu_e5500) 120 118 mflr r4 121 119 bl __e500_icache_setup
+6 -3
arch/powerpc/kernel/cputable.c
··· 74 74 #endif /* CONFIG_PPC64 */ 75 75 #if defined(CONFIG_E500) 76 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 78 extern void __restore_cpu_e5500(void); 79 + extern void __restore_cpu_e6500(void); 78 80 #endif /* CONFIG_E500 */ 79 81 80 82 /* This table only contains "desktop" CPUs, it need to be filled with embedded ··· 2067 2065 .pvr_value = 0x80400000, 2068 2066 .cpu_name = "e6500", 2069 2067 .cpu_features = CPU_FTRS_E6500, 2070 - .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 2068 + .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU | 2069 + PPC_FEATURE_HAS_ALTIVEC_COMP, 2071 2070 .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS | 2072 2071 MMU_FTR_USE_TLBILX, 2073 2072 .icache_bsize = 64, ··· 2076 2073 .num_pmcs = 4, 2077 2074 .oprofile_cpu_type = "ppc/e6500", 2078 2075 .oprofile_type = PPC_OPROFILE_FSL_EMB, 2079 - .cpu_setup = __setup_cpu_e5500, 2076 + .cpu_setup = __setup_cpu_e6500, 2080 2077 #ifndef CONFIG_PPC32 2081 - .cpu_restore = __restore_cpu_e5500, 2078 + .cpu_restore = __restore_cpu_e6500, 2082 2079 #endif 2083 2080 .machine_check = machine_check_e500mc, 2084 2081 .platform = "ppce6500",
+47
arch/powerpc/kernel/exceptions-64e.S
··· 299 299 EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ 300 300 EXCEPTION_STUB(0x1c0, data_tlb_miss) 301 301 EXCEPTION_STUB(0x1e0, instruction_tlb_miss) 302 + EXCEPTION_STUB(0x200, altivec_unavailable) /* 0x0f20 */ 303 + EXCEPTION_STUB(0x220, altivec_assist) /* 0x1700 */ 302 304 EXCEPTION_STUB(0x260, perfmon) 303 305 EXCEPTION_STUB(0x280, doorbell) 304 306 EXCEPTION_STUB(0x2a0, doorbell_crit) ··· 396 394 addi r3,r1,STACK_FRAME_OVERHEAD 397 395 bl .kernel_fp_unavailable_exception 398 396 b .ret_from_except 397 + 398 + /* Altivec Unavailable Interrupt */ 399 + START_EXCEPTION(altivec_unavailable); 400 + NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL, 401 + PROLOG_ADDITION_NONE) 402 + /* we can probably do a shorter exception entry for that one... */ 403 + EXCEPTION_COMMON(0x200, PACA_EXGEN, INTS_KEEP) 404 + #ifdef CONFIG_ALTIVEC 405 + BEGIN_FTR_SECTION 406 + ld r12,_MSR(r1) 407 + andi. r0,r12,MSR_PR; 408 + beq- 1f 409 + bl .load_up_altivec 410 + b fast_exception_return 411 + 1: 412 + END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 413 + #endif 414 + INTS_DISABLE 415 + bl .save_nvgprs 416 + addi r3,r1,STACK_FRAME_OVERHEAD 417 + bl .altivec_unavailable_exception 418 + b .ret_from_except 419 + 420 + /* AltiVec Assist */ 421 + START_EXCEPTION(altivec_assist); 422 + NORMAL_EXCEPTION_PROLOG(0x220, BOOKE_INTERRUPT_ALTIVEC_ASSIST, 423 + PROLOG_ADDITION_NONE) 424 + EXCEPTION_COMMON(0x220, PACA_EXGEN, INTS_DISABLE) 425 + bl .save_nvgprs 426 + addi r3,r1,STACK_FRAME_OVERHEAD 427 + #ifdef CONFIG_ALTIVEC 428 + BEGIN_FTR_SECTION 429 + bl .altivec_assist_exception 430 + END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 431 + #else 432 + bl .unknown_exception 433 + #endif 434 + b .ret_from_except 435 + 399 436 400 437 /* Decrementer Interrupt */ 401 438 MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, ··· 848 807 BAD_STACK_TRAMPOLINE(0x000) 849 808 BAD_STACK_TRAMPOLINE(0x100) 850 809 BAD_STACK_TRAMPOLINE(0x200) 810 + BAD_STACK_TRAMPOLINE(0x220) 851 811 BAD_STACK_TRAMPOLINE(0x260) 852 812 BAD_STACK_TRAMPOLINE(0x280) 853 813 BAD_STACK_TRAMPOLINE(0x2a0) ··· 1390 1348 1391 1349 sync 1392 1350 1351 + blr 1352 + 1353 + _GLOBAL(setup_altivec_ivors) 1354 + SET_IVOR(32, 0x200) /* AltiVec Unavailable */ 1355 + SET_IVOR(33, 0x220) /* AltiVec Assist */ 1393 1356 blr 1394 1357 1395 1358 _GLOBAL(setup_perfmon_ivor)
+1 -1
arch/powerpc/platforms/Kconfig.cputype
··· 232 232 233 233 config ALTIVEC 234 234 bool "AltiVec Support" 235 - depends on 6xx || POWER4 235 + depends on 6xx || POWER4 || (PPC_E500MC && PPC64) 236 236 ---help--- 237 237 This option enables kernel support for the Altivec extensions to the 238 238 PowerPC processor. The kernel currently supports saving and restoring