From c693a3a5061b67ad63faf7ae76be98ea7eb5cda8 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 11 Aug 2017 10:44:04 +0200 Subject: powerpc: PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE In 64-bit mode, the linker must have the ability to restore the TOC pointer after an external function call. Update #3082. --- c/src/lib/libbsp/powerpc/qoriq/start/start.S | 46 ++++++++++++++++++++++ c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c | 8 +++- .../bspsupport/ppc_exc_async_normal.S | 3 ++ .../new-exceptions/bspsupport/ppc_exc_fatal.S | 1 + cpukit/score/cpu/powerpc/rtems/asm.h | 5 +++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/c/src/lib/libbsp/powerpc/qoriq/start/start.S b/c/src/lib/libbsp/powerpc/qoriq/start/start.S index c0bf1d5a48..dec1f95782 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/start/start.S +++ b/c/src/lib/libbsp/powerpc/qoriq/start/start.S @@ -67,6 +67,7 @@ _start: LA r3, bsp_section_fast_text_begin LA r4, bsp_section_fast_text_size bl rtems_cache_flush_multiple_data_lines + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Copy read-only data */ LA r3, bsp_section_rodata_begin @@ -77,11 +78,13 @@ _start: /* Copy FDT into read-only data */ mr r3, FDT_REGISTER bl bsp_fdt_copy + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Flush read-only data */ LA r3, bsp_section_rodata_begin LA r4, bsp_section_rodata_size bl rtems_cache_flush_multiple_data_lines + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Copy fast data */ LA r3, bsp_section_fast_data_begin @@ -116,11 +119,13 @@ _start: LA r3, bsp_section_sbss_begin LA r4, bsp_section_sbss_size bl bsp_start_zero + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Clear BSS */ LA r3, bsp_section_bss_begin LA r4, bsp_section_bss_size bl bsp_start_zero + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE #ifndef __powerpc64__ /* Set up EABI and SYSV environment */ @@ -131,11 +136,13 @@ _start: li r3, 0 bl boot_card + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE .Lcopy: PPC_REG_CMP r3, r4 beqlr b memcpy + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE .Linitearly: #ifdef __powerpc64__ @@ -196,6 +203,7 @@ _start: /* Invalidate all TS1 MMU entries */ li r3, 1 bl qoriq_tlb1_invalidate_all_by_ts + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Add TS1 entry for the first 4GiB of RAM */ li r3, SCRATCH_TLB @@ -206,6 +214,7 @@ _start: li r8, 0 li r9, 11 bl qoriq_tlb1_write + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* MSR initialization and use TS1 for address translation */ LWI INITIAL_MSR, QORIQ_INITIAL_MSR @@ -237,10 +246,12 @@ _start: li r4, FIRST_TLB li r5, SCRATCH_TLB bl qoriq_mmu_config + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE mtmsr INITIAL_MSR isync li r3, SCRATCH_TLB bl qoriq_tlb1_invalidate + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE mtlr SAVED_LINK_REGISTER blr @@ -314,6 +325,7 @@ _start_thread: #endif b qoriq_start_thread + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE #endif _start_secondary_processor: bl .Linitearly @@ -325,8 +337,15 @@ _start_secondary_processor: li r3, 0 bl .Linitmmu b bsp_start_on_secondary_processor + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE #endif /* RTEMS_SMP */ +#ifdef __powerpc64__ +#define START_NOP_FOR_LINKER_TOC_POINTER_RESTORE nop; nop; nop; nop +#else +#define START_NOP_FOR_LINKER_TOC_POINTER_RESTORE +#endif + /* Exception vector prologues area */ .section ".bsp_start_text", "ax" .align 4 @@ -336,143 +355,170 @@ bsp_exc_vector_base: PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 0 b ppc_exc_fatal_critical + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Machine check */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 1 b ppc_exc_fatal_machine_check + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Data storage */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 2 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Instruction storage */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 3 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* External input */ PPC_REG_STORE_UPDATE r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1) b ppc_exc_interrupt nop nop + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Alignment */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 5 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Program */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 6 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #ifdef __PPC_CPU_E6500__ /* Floating-point unavailable */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 7 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #endif /* System call */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 8 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #ifdef __PPC_CPU_E6500__ /* APU unavailable */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 9 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #endif /* Decrementer */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 10 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Fixed-interval timer interrupt */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 11 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Watchdog timer interrupt */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 12 b ppc_exc_fatal_critical + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Data TLB error */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 13 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Instruction TLB error */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 14 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Debug */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 15 b ppc_exc_fatal_debug + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* SPE APU unavailable or AltiVec unavailable */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 32 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* SPE floating-point data exception or AltiVec assist */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 33 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #ifndef __PPC_CPU_E6500__ /* SPE floating-point round exception */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 34 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #endif /* Performance monitor */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 35 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #ifdef __PPC_CPU_E6500__ /* Processor doorbell interrupt */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 36 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Processor doorbell critical interrupt */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 37 b ppc_exc_fatal_critical + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Guest processor doorbell */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 38 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Guest processor doorbell critical and machine check */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 39 b ppc_exc_fatal_critical + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Hypervisor system call */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 40 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Hypervisor privilege */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 41 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* LRAT error */ PPC_REG_STORE_UPDATE r1, -EXC_GENERIC_SIZE(r1) PPC_REG_STORE r3, GPR3_OFFSET(r1) li r3, 42 b ppc_exc_fatal_normal + START_NOP_FOR_LINKER_TOC_POINTER_RESTORE #endif /* Symbol provided for debugging and tracing */ diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c index 58f930ee22..6ad73c301a 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c @@ -113,10 +113,16 @@ static void initialize_frequency_parameters(void) #define MTIVPR(base) \ __asm__ volatile ("mtivpr %0" : : "r" (base)) +#ifdef __powerpc64__ +#define VECTOR_TABLE_ENTRY_SIZE 32 +#else +#define VECTOR_TABLE_ENTRY_SIZE 16 +#endif + #define MTIVOR(vec, offset) \ do { \ __asm__ volatile ("mtspr " RTEMS_XSTRING(vec) ", %0" : : "r" (offset)); \ - offset += 16; \ + offset += VECTOR_TABLE_ENTRY_SIZE; \ } while (0) void qoriq_initialize_exceptions(void *interrupt_stack_begin) diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S index d40e5cd48e..5b2a1b48e0 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S @@ -278,6 +278,7 @@ ppc_exc_interrupt: #else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ /* Call fixed high level handler */ bl bsp_interrupt_dispatch + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE #endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ #ifdef RTEMS_PROFILING @@ -287,6 +288,7 @@ ppc_exc_interrupt: lwz r4, PPC_EXC_INTERRUPT_ENTRY_INSTANT_OFFSET(FRAME_REGISTER) GET_TIME_BASE r5 bl _Profiling_Outer_most_interrupt_entry_and_exit + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE .Lprofiling_done: #endif /* RTEMS_PROFILING */ @@ -334,6 +336,7 @@ ppc_exc_interrupt: mfmsr r4 ori r4, r4, MSR_EE bl _Thread_Do_dispatch + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE /* Disable interrupts */ wrteei 0 diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_fatal.S b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_fatal.S index 0bfba57352..1cb97e350a 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_fatal.S +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_fatal.S @@ -226,3 +226,4 @@ ppc_exc_fatal_normal: li r3, 9 addi r4, r1, FRAME_LINK_SPACE b _Terminate + PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE diff --git a/cpukit/score/cpu/powerpc/rtems/asm.h b/cpukit/score/cpu/powerpc/rtems/asm.h index 192a00687d..2fddf56e6d 100644 --- a/cpukit/score/cpu/powerpc/rtems/asm.h +++ b/cpukit/score/cpu/powerpc/rtems/asm.h @@ -301,5 +301,10 @@ SYM (x):; \ #error "PPC_ASM_TYPE is not properly defined" #endif +#if defined(__powerpc64__) +#define PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE nop +#else +#define PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE +#endif #endif -- cgit v1.2.3