[rtems commit] powerpc: PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE

Sebastian Huber sebh at rtems.org
Tue Aug 22 14:56:08 UTC 2017


Module:    rtems
Branch:    master
Commit:    c693a3a5061b67ad63faf7ae76be98ea7eb5cda8
Changeset: http://git.rtems.org/rtems/commit/?id=c693a3a5061b67ad63faf7ae76be98ea7eb5cda8

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Aug 11 10:44:04 2017 +0200

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 c0bf1d5..dec1f95 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 58f930e..6ad73c3 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 d40e5cd..5b2a1b4 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 0bfba57..1cb97e3 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 192a006..2fddf56 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




More information about the vc mailing list