summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-08-11 10:44:04 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-08-22 16:27:03 +0200
commitc693a3a5061b67ad63faf7ae76be98ea7eb5cda8 (patch)
tree8a5313689f94b37c1604b15c61ddb0b0083e0c8a
parentbsp/qoriq: 64-bit MMU support (diff)
downloadrtems-c693a3a5061b67ad63faf7ae76be98ea7eb5cda8.tar.bz2
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.
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/start/start.S46
-rw-r--r--c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c8
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S3
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_fatal.S1
-rw-r--r--cpukit/score/cpu/powerpc/rtems/asm.h5
5 files changed, 62 insertions, 1 deletions
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