summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cpukit/ChangeLog8
-rw-r--r--cpukit/score/cpu/sparc/cpu.c4
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/cpu.h19
-rw-r--r--cpukit/score/include/rtems/score/context.h16
-rw-r--r--cpukit/score/src/threadhandler.c7
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 <joel.sherrill@OARcorp.com>
+
+ * 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 <daniel@gaisler.com> provided the
+ SPARC implementation and I made it more general.
+
2007-10-26 Glenn Humphrey <glenn.humphrey@OARcorp.com>
* 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
@@ -791,6 +791,25 @@ void _CPU_Context_Initialize(
);
/*
+ * 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
@@ -69,6 +69,22 @@ SCORE_EXTERN volatile boolean _Context_Switch_necessary;
_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
*
* This routine saves the current context into the @a _executing
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
@@ -76,6 +76,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
*/