2008-10-28 Joel Sherrill <joel.sherrill@oarcorp.com>

* Makefile.am, preinstall.am, rtems/score/cpu.h: Now performs context
	switches and many tests run.
	* context_init.c, context_switch.S, cpu.c, cpu_asm.c: New files.
This commit is contained in:
Joel Sherrill
2008-10-28 20:03:19 +00:00
parent d6223f869f
commit 0e5b446af7
8 changed files with 384 additions and 38 deletions

View File

@@ -1,3 +1,9 @@
2008-10-28 Joel Sherrill <joel.sherrill@oarcorp.com>
* Makefile.am, preinstall.am, rtems/score/cpu.h: Now performs context
switches and many tests run.
* context_init.c, context_switch.S, cpu.c, cpu_asm.c: New files.
2008-10-02 Joel Sherrill <joel.sherrill@oarcorp.com>
* .cvsignore, ChangeLog, Makefile.am, preinstall.am, rtems/asm.h,

View File

@@ -4,6 +4,8 @@
include $(top_srcdir)/automake/compile.am
include_HEADERS =
include_rtemsdir = $(includedir)/rtems
include_rtems_HEADERS = rtems/asm.h
@@ -12,8 +14,7 @@ include_rtems_score_HEADERS = rtems/score/cpu.h rtems/score/m32r.h \
rtems/score/cpu_asm.h rtems/score/types.h
noinst_LIBRARIES = libscorecpu.a
# for now just use the stubs
libscorecpu_a_SOURCES = ../no_cpu/cpu.c ../no_cpu/cpu_asm.c
libscorecpu_a_SOURCES = cpu.c cpu_asm.c context_switch.S context_init.c
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
include $(srcdir)/preinstall.am

View File

@@ -0,0 +1,52 @@
/*
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <stdint.h>
#include <rtems/system.h>
typedef struct {
uint32_t marker;
} Starting_Frame;
#define _get_r12( _r12 ) \
asm volatile( "mv r12, %0" : "=r" (_r12))
void _CPU_Context_Initialize(
Context_Control *the_context,
uint32_t *stack_base,
uint32_t size,
uint32_t new_level,
void *entry_point,
bool is_fp
)
{
void *stackEnd = stack_base;
Starting_Frame *frame;
uint32_t r12;
stackEnd += size;
frame = (Starting_Frame *)stackEnd;
frame--;
frame->marker = 0xa5a5a5a5;
_get_r12( r12 );
the_context->r8 = 0x88888888;
the_context->r9 = 0x99999999;
the_context->r10 = 0xaaaaaaaa;
the_context->r11 = 0xbbbbbbbb;
the_context->r12 = r12;
the_context->r13_fp = 0;
the_context->r14_lr = (uintptr_t) entry_point;
the_context->r15_sp = (uintptr_t) frame;
}

View File

@@ -0,0 +1,65 @@
/*
* Context switch for the Reneas M32C
*
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#define ARG_EXECUTING 8
#define ARG_HEIR 12
#define CONTEXT_R8 0x00
#define CONTEXT_R9 0x04
#define CONTEXT_R10 0x08
#define CONTEXT_R11 0x0C
#define CONTEXT_R12 0x10
#define CONTEXT_R13_FP 0x14
#define CONTEXT_R14_LR 0x18
#define CONTEXT_R15_SP 0x1C
#define CONTEXT_ACC_LOW 0x20
#define CONTEXT_ACC_HIGH 0x24
.file "context_switch.S"
.text
.global _CPU_Context_switch
.type _CPU_Context_switch, @function
_CPU_Context_switch:
st r8, @(CONTEXT_R8,r0)
st r9, @(CONTEXT_R9,r0)
st r10, @(CONTEXT_R10,r0)
st r11, @(CONTEXT_R11,r0)
st r12, @(CONTEXT_R12,r0)
st r13, @(CONTEXT_R13_FP,r0)
st r14, @(CONTEXT_R14_LR,r0)
st r15, @(CONTEXT_R15_SP,r0)
mvfaclo r2
st r2, @(CONTEXT_ACC_LOW,r0)
mvfachi r2
st r2, @(CONTEXT_ACC_HIGH,r0)
restore:
ld r8, @(CONTEXT_R8,r1)
ld r9, @(CONTEXT_R9,r1)
ld r10, @(CONTEXT_R10,r1)
ld r11, @(CONTEXT_R11,r1)
ld r12, @(CONTEXT_R12,r1)
ld r13, @(CONTEXT_R13_FP,r1)
ld r14, @(CONTEXT_R14_LR,r1)
ld r15, @(CONTEXT_R15_SP,r1)
ld r2, @(CONTEXT_ACC_LOW,r1)
mvtaclo r2
ld r2, @(CONTEXT_ACC_HIGH,r1)
mvtachi r2
jmp lr
.global _CPU_Context_Restart_self
.type _CPU_Context_Restart_self, @function
_CPU_Context_Restart_self:
mv r0, r1
bra restore

124
cpukit/score/cpu/m32r/cpu.c Normal file
View File

@@ -0,0 +1,124 @@
/*
* M32R CPU Dependent Source
*
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems/system.h>
#include <rtems/score/isr.h>
/* _CPU_Initialize
*
* This routine performs processor dependent initialization.
*
* INPUT PARAMETERS:
* thread_dispatch - address of disptaching routine
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_Initialize(
void (*thread_dispatch) /* ignored on this CPU */
)
{
}
/*
* This routine returns the current interrupt level.
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
uint32_t _CPU_ISR_Get_level( void )
{
return 0;
}
/*PAGE
*
* _CPU_ISR_install_raw_handler
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_ISR_install_raw_handler(
uint32_t vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
/*
* This is where we install the interrupt handler into the "raw" interrupt
* table used by the CPU to dispatch interrupt handlers.
*/
/* _set_var_vect(new_handler,vector); */
}
/*PAGE
*
* _CPU_ISR_install_vector
*
* This kernel routine installs the RTEMS handler for the
* specified vector.
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
*
* Output parameters: NONE
*
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_ISR_install_vector(
uint32_t vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
*old_handler = _ISR_Vector_table[ vector ];
/*
* If the interrupt vector table is a table of pointer to isr entry
* points, then we need to install the appropriate RTEMS interrupt
* handler for this vector number.
*/
_CPU_ISR_install_raw_handler( vector, new_handler, old_handler );
/*
* We put the actual user ISR address in '_ISR_vector_table'. This will
* be used by the _ISR_Handler so the user gets control.
*/
_ISR_Vector_table[ vector ] = new_handler;
}
/*PAGE
*
* _CPU_Install_interrupt_stack
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _CPU_Install_interrupt_stack( void )
{
}

View File

@@ -0,0 +1,93 @@
/* cpu_asm.c ===> cpu_asm.S or cpu_asm.s
*
* NOTE: This is supposed to be a .S or .s file NOT a C file.
*
* M32R does not yet have interrupt support. When this functionality
* is written, this file should become obsolete.
*
* COPYRIGHT (c) 1989-2008.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#include <rtems/system.h>
#include <rtems/score/cpu.h>
/* void __ISR_Handler()
*
* This routine provides the RTEMS interrupt management.
*
* NO_CPU Specific Information:
*
* XXX document implementation including references if appropriate
*/
void _ISR_Handler(void)
{
/*
* This discussion ignores a lot of the ugly details in a real
* implementation such as saving enough registers/state to be
* able to do something real. Keep in mind that the goal is
* to invoke a user's ISR handler which is written in C and
* uses a certain set of registers.
*
* Also note that the exact order is to a large extent flexible.
* Hardware will dictate a sequence for a certain subset of
* _ISR_Handler while requirements for setting
*/
/*
* At entry to "common" _ISR_Handler, the vector number must be
* available. On some CPUs the hardware puts either the vector
* number or the offset into the vector table for this ISR in a
* known place. If the hardware does not give us this information,
* then the assembly portion of RTEMS for this port will contain
* a set of distinct interrupt entry points which somehow place
* the vector number in a known place (which is safe if another
* interrupt nests this one) and branches to _ISR_Handler.
*
* save some or all context on stack
* may need to save some special interrupt information for exit
*
* #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
* if ( _ISR_Nest_level == 0 )
* switch to software interrupt stack
* #endif
*
* _ISR_Nest_level++;
*
* _Thread_Dispatch_disable_level++;
*
* (*_ISR_Vector_table[ vector ])( vector );
*
* _Thread_Dispatch_disable_level--;
*
* --_ISR_Nest_level;
*
* if ( _ISR_Nest_level )
* goto the label "exit interrupt (simple case)"
*
* if ( _Thread_Dispatch_disable_level )
* _ISR_Signals_to_thread_executing = FALSE;
* goto the label "exit interrupt (simple case)"
*
* if ( _Context_Switch_necessary || _ISR_Signals_to_thread_executing ) {
* _ISR_Signals_to_thread_executing = FALSE;
* call _Thread_Dispatch() or prepare to return to _ISR_Dispatch
* prepare to get out of interrupt
* return from interrupt (maybe to _ISR_Dispatch)
*
* LABEL "exit interrupt (simple case):
* #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
* if outermost interrupt
* restore stack
* #endif
* prepare to get out of interrupt
* return from interrupt
*/
}

View File

@@ -13,6 +13,11 @@ all-am: $(PREINSTALL_FILES)
PREINSTALL_FILES =
CLEANFILES = $(PREINSTALL_FILES)
$(PROJECT_INCLUDE)/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)
@: > $(PROJECT_INCLUDE)/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
$(PROJECT_INCLUDE)/rtems/$(dirstamp):
@$(MKDIR_P) $(PROJECT_INCLUDE)/rtems
@: > $(PROJECT_INCLUDE)/rtems/$(dirstamp)

View File

@@ -188,7 +188,7 @@ extern "C" {
* If there is a FP coprocessor such as the i387 or mc68881, then
* the answer is TRUE.
*
* The macro name "NO_CPU_HAS_FPU" should be made CPU specific.
* The macro name "M32R_HAS_FPU" should be made CPU specific.
* It indicates whether or not this CPU model has FP support. For
* example, it would be possible to have an i386_nofp CPU model
* which set this to false to indicate that you have an i386 without
@@ -212,7 +212,7 @@ extern "C" {
*
* XXX document implementation including references if appropriate
*/
#if ( NO_CPU_HAS_FPU == 1 )
#if ( M32R_HAS_FPU == 1 )
#define CPU_HARDWARE_FP TRUE
#else
#define CPU_HARDWARE_FP FALSE
@@ -317,7 +317,7 @@ extern "C" {
*
* XXX document implementation including references if appropriate
*/
#define CPU_PROVIDES_IDLE_THREAD_BODY TRUE
#define CPU_PROVIDES_IDLE_THREAD_BODY FALSE
/**
* Does the stack grow up (toward higher addresses) or down
@@ -466,19 +466,26 @@ extern "C" {
* to another.
*/
typedef struct {
/** This field is a hint that a port will have a number of integer
* registers that need to be saved at a context switch.
*/
uint32_t some_integer_register;
/** This field is a hint that a port will have a number of system
* registers that need to be saved at a context switch.
*/
uint32_t some_system_register;
/** This field is a hint that a port will have a register that
* is the stack pointer.
*/
uint32_t stack_pointer;
/** r8 -- temporary register */
uint32_t r8;
/** r9 -- temporary register */
uint32_t r9;
/** r10 -- temporary register */
uint32_t r10;
/** r11 -- temporary register */
uint32_t r11;
/** r12 -- may be global pointer */
uint32_t r12;
/** r13 -- frame pointer */
uint32_t r13_fp;
/** r14 -- link register (aka return pointer */
uint32_t r14_lr;
/** r15 -- stack pointer */
uint32_t r15_sp;
/** dsp accumulator low order 32-bits */
uint32_t acc_low;
/** dsp accumulator high order 32-bits */
uint32_t acc_high;
} Context_Control;
/**
@@ -491,7 +498,7 @@ typedef struct {
* @return This method returns the stack pointer.
*/
#define _CPU_Context_Get_SP( _context ) \
(_context)->stack_pointer
(_context)->r15_sp
/**
* @ingroup CPUContext Management
@@ -645,7 +652,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(void);
*
* XXX document implementation including references if appropriate
*/
#define CPU_STACK_MINIMUM_SIZE (1024*4)
#define CPU_STACK_MINIMUM_SIZE (1024)
/**
* CPU's worst alignment requirement for data types on a byte boundary. This
@@ -848,10 +855,14 @@ uint32_t _CPU_ISR_Get_level( void );
*
* XXX document implementation including references if appropriate
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
_isr, _entry_point, _is_fp ) \
{ \
}
void _CPU_Context_Initialize(
Context_Control *the_context,
uint32_t *stack_base,
size_t size,
uint32_t new_level,
void *entry_point,
bool is_fp
);
/**
* This routine is responsible for somehow restarting the currently
@@ -868,8 +879,9 @@ uint32_t _CPU_ISR_Get_level( void );
*
* XXX document implementation including references if appropriate
*/
#define _CPU_Context_Restart_self( _the_context ) \
_CPU_Context_restore( (_the_context) );
void _CPU_Context_Restart_self(
Context_Control *the_context
);
/**
* @ingroup CPUContext
@@ -1142,18 +1154,6 @@ void _CPU_ISR_install_vector(
*/
void _CPU_Install_interrupt_stack( void );
/**
* This routine is the CPU dependent IDLE thread body.
*
* @note It need only be provided if @ref CPU_PROVIDES_IDLE_THREAD_BODY
* is TRUE.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
void *_CPU_Thread_Idle_body( uint32_t );
/**
* @ingroup CPUContext
* This routine switches from the run context to the heir context.