From 48816d7d7a60a8bc07ef3fe397ad20657761d284 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 2 Nov 2007 13:35:02 +0000 Subject: [PATCH] 2007-11-02 Joel Sherrill * score/cpu/sparc/cpu.c, score/cpu/sparc/rtems/score/cpu.h, score/include/rtems/score/context.h, score/src/threadhandler.c: Fix stack so gdb backtrace does not print corrupted frame message after _Thread_Handler. Daniel Hellstrom provided the SPARC implementation and I made it more general. --- cpukit/ChangeLog | 8 ++++++++ cpukit/score/cpu/sparc/cpu.c | 4 ++-- cpukit/score/cpu/sparc/rtems/score/cpu.h | 19 +++++++++++++++++++ cpukit/score/include/rtems/score/context.h | 16 ++++++++++++++++ cpukit/score/src/threadhandler.c | 7 +++++++ 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index f79c4f8d38..eca3f04495 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,11 @@ +2007-11-02 Joel Sherrill + + * score/cpu/sparc/cpu.c, score/cpu/sparc/rtems/score/cpu.h, + score/include/rtems/score/context.h, score/src/threadhandler.c: Fix + stack so gdb backtrace does not print corrupted frame message after + _Thread_Handler. Daniel Hellstrom provided the + SPARC implementation and I made it more general. + 2007-10-26 Glenn Humphrey * libmisc/cpuuse/cpuusagereport.c, rtems/src/ratemonreportstatistics.c: diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c index e18acad6cc..b90b42da6c 100644 --- a/cpukit/score/cpu/sparc/cpu.c +++ b/cpukit/score/cpu/sparc/cpu.c @@ -1,7 +1,7 @@ /* * SPARC Dependent Source * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 1989-2007. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -301,7 +301,7 @@ void _CPU_Context_Initialize( the_context->o7 = ((uint32_t ) entry_point) - 8; the_context->o6_sp = stack_high - CPU_MINIMUM_STACK_FRAME_SIZE; - the_context->i6_fp = stack_high; + the_context->i6_fp = 0; /* * Build the PSR for the task. Most everything can be 0 and the diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h index dfe9978c7f..8396d2c31f 100644 --- a/cpukit/score/cpu/sparc/rtems/score/cpu.h +++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h @@ -790,6 +790,25 @@ void _CPU_Context_Initialize( boolean is_fp ); +/* + * This macro is invoked from _Thread_Handler to do whatever CPU + * specific magic is required that must be done in the context of + * the thread when it starts. + * + * On the SPARC, this is setting the frame pointer so GDB is happy. + * Make GDB stop unwinding at _Thread_Handler, previous register window + * Frame pointer is 0 and calling address must be a function with starting + * with a SAVE instruction. If return address is leaf-function (no SAVE) + * GDB will not look at prev reg window fp. + * + * _Thread_Handler is known to start with SAVE. + */ + +#define _CPU_Context_Initialization_at_thread_begin() \ + do { \ + asm volatile ("set _Thread_Handler,%%i7\n"::); \ + } while (0) + /* * This routine is responsible for somehow restarting the currently * executing task. diff --git a/cpukit/score/include/rtems/score/context.h b/cpukit/score/include/rtems/score/context.h index 87c61957ba..46ecff3686 100644 --- a/cpukit/score/include/rtems/score/context.h +++ b/cpukit/score/include/rtems/score/context.h @@ -68,6 +68,22 @@ SCORE_EXTERN volatile boolean _Context_Switch_necessary; #define _Context_Initialize(_the_context, _stack, _size, _isr, _entry, _is_fp) \ _CPU_Context_Initialize( _the_context, _stack, _size, _isr, _entry, _is_fp ) +/** + * This macro is invoked from _Thread_Handler to do whatever CPU + * specific magic is required that must be done in the context of + * the thread when it starts. + * + * If the CPU architecture does not require any magic, then this + * macro is empty. + */ + +#if defined(_CPU_Context_Initialization_at_thread_begin) + #define _Context_Initialization_at_thread_begin() \ + _CPU_Context_Initialization_at_thread_begin() +#else + #define _Context_Initialization_at_thread_begin() +#endif + /** * @brief Perform Context Switch * diff --git a/cpukit/score/src/threadhandler.c b/cpukit/score/src/threadhandler.c index 7c94121009..523f623d02 100644 --- a/cpukit/score/src/threadhandler.c +++ b/cpukit/score/src/threadhandler.c @@ -75,6 +75,13 @@ void _Thread_Handler( void ) executing = _Thread_Executing; + /* + * Some CPUs need to tinker with the call frame or registers when the + * thread actually begins to execute for the first time. This is a + * hook point where the port gets a shot at doing whatever it requires. + */ + _Context_Initialization_at_thread_begin(); + /* * have to put level into a register for those cpu's that use * inline asm here