mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 23:23:13 +00:00
Refreshing effort from Avenger.
This commit is contained in:
@@ -11,21 +11,27 @@ There are various issues regarding this port:
|
|||||||
This port is written by Andrew Bray <andy@i-cubed.co.uk>, and
|
This port is written by Andrew Bray <andy@i-cubed.co.uk>, and
|
||||||
is copyright 1995 i-cubed ltd.
|
is copyright 1995 i-cubed ltd.
|
||||||
|
|
||||||
|
This port was later updated by Joel Sherrill <joel@OARcorp.com>
|
||||||
|
to test the support for the PPC603, PPC603e, and PPC604. This
|
||||||
|
was tested on the PowerPC simulator PSIM and a VMEbus single board
|
||||||
|
computer.
|
||||||
|
|
||||||
2) CPU support.
|
2) CPU support.
|
||||||
|
|
||||||
This release fully supports the IBM PPC403GA and PPC403GB processors.
|
This release fully supports the PPC403GA, PPC403GB, PPC603, PPC603e,
|
||||||
|
and PPC604 processors. A good faith attempt has been made to include
|
||||||
|
support other models based upon available documentation.
|
||||||
|
|
||||||
It has only been tested on the PPC403GA (using software floating
|
This port was originally written and tested on the PPC403GA (using
|
||||||
point).
|
software floating point). Current ports are tested on 60x CPUs
|
||||||
|
using the PowerPC simulator PSIM.
|
||||||
|
|
||||||
With the gratefully acknowledged assistance of IBM and Blue Micro,
|
Andrew Bray received assistance during the initial porting effort
|
||||||
this release contains code to support the following processors
|
from IBM and Blue Micro and we would like to gratefully acknowledge
|
||||||
PPC601, PPC603, PPC603e, PPC604, and PPC602.
|
that help.
|
||||||
|
|
||||||
The support for these processors is incomplete, especially that for
|
The support for the PPC602 processor is incomplete as only sketchy
|
||||||
the PPC602 for which only sketchy data is currently available.
|
data is currently available. Perhaps this model has been dropped.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -58,14 +64,15 @@ d) GCC 2.7.0. This compiler is partway along the road to supporting the EABI,
|
|||||||
but is currently halfway in between.
|
but is currently halfway in between.
|
||||||
|
|
||||||
This port was built and tested using the PowerOpen ABI, with the following
|
This port was built and tested using the PowerOpen ABI, with the following
|
||||||
caveat: we used an ELF assembler and linker. So some attention may be required
|
caveat: we used an ELF assembler and linker. So some attention may be
|
||||||
on the assembler files to get them through a traditional (XCOFF) PowerOpen
|
required on the assembler files to get them through a traditional (XCOFF)
|
||||||
assembler.
|
PowerOpen assembler.
|
||||||
|
|
||||||
This port contains support for the other ABIs, but this may prove to be incomplete
|
This port contains support for the other ABIs, but this may prove to be
|
||||||
as it is untested.
|
incomplete as it is untested.
|
||||||
|
|
||||||
In the long term, the RTEMS PowerPC port should move to the EABI as its primary
|
The RTEMS PowerPC port supports EABI as the primary ABI. The powerpc-rtems
|
||||||
or only port. This should wait on a true EABI version of GCC.
|
GNU toolset configuration is EABI and .
|
||||||
|
|
||||||
Andrew Bray 4/December/1995
|
Andrew Bray, 4 December 1995
|
||||||
|
Joel Sherrill, 16 July 1997
|
||||||
|
|||||||
@@ -18,12 +18,12 @@
|
|||||||
*
|
*
|
||||||
* Derived from c/src/exec/cpu/no_cpu/cpu.c:
|
* Derived from c/src/exec/cpu/no_cpu/cpu.c:
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 1989-1998.
|
* COPYRIGHT (c) 1989-1997.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
* Copyright assigned to U.S. Government, 1994.
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be found in
|
||||||
* found in the file LICENSE in this distribution or at
|
* the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
@@ -37,24 +37,6 @@
|
|||||||
/*
|
/*
|
||||||
* These are for testing purposes.
|
* These are for testing purposes.
|
||||||
*/
|
*/
|
||||||
#undef Testing
|
|
||||||
|
|
||||||
#ifdef Testing
|
|
||||||
static unsigned32 msr;
|
|
||||||
#ifdef ppc403
|
|
||||||
static unsigned32 evpr;
|
|
||||||
static unsigned32 exier;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ppc_interrupt_level_to_msr
|
|
||||||
*
|
|
||||||
* This routine converts a two bit interrupt level to an MSR bit map.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const unsigned32 _CPU_msrs[4] =
|
|
||||||
{ PPC_MSR_0, PPC_MSR_1, PPC_MSR_2, PPC_MSR_3 };
|
|
||||||
|
|
||||||
/* _CPU_Initialize
|
/* _CPU_Initialize
|
||||||
*
|
*
|
||||||
@@ -75,9 +57,9 @@ void _CPU_Initialize(
|
|||||||
proc_ptr handler = (proc_ptr)ppc_spurious;
|
proc_ptr handler = (proc_ptr)ppc_spurious;
|
||||||
int i;
|
int i;
|
||||||
#if (PPC_ABI != PPC_ABI_POWEROPEN)
|
#if (PPC_ABI != PPC_ABI_POWEROPEN)
|
||||||
register unsigned32 r2;
|
register unsigned32 r2 = 0;
|
||||||
#if (PPC_ABI != PPC_ABI_GCC27)
|
#if (PPC_ABI != PPC_ABI_GCC27)
|
||||||
register unsigned32 r13;
|
register unsigned32 r13 = 0;
|
||||||
|
|
||||||
asm ("mr %0,13" : "=r" ((r13)) : "0" ((r13)));
|
asm ("mr %0,13" : "=r" ((r13)) : "0" ((r13)));
|
||||||
_CPU_IRQ_info.Default_r13 = r13;
|
_CPU_IRQ_info.Default_r13 = r13;
|
||||||
@@ -96,26 +78,19 @@ void _CPU_Initialize(
|
|||||||
_CPU_IRQ_info.Switch_necessary = &_Context_Switch_necessary;
|
_CPU_IRQ_info.Switch_necessary = &_Context_Switch_necessary;
|
||||||
_CPU_IRQ_info.Signal = &_ISR_Signals_to_thread_executing;
|
_CPU_IRQ_info.Signal = &_ISR_Signals_to_thread_executing;
|
||||||
|
|
||||||
|
#if (PPC_USE_SPRG)
|
||||||
i = (int)&_CPU_IRQ_info;
|
i = (int)&_CPU_IRQ_info;
|
||||||
asm volatile("mtspr 0x113, %0" : "=r" (i) : "0" (i)); /* SPRG 3 */
|
asm volatile("mtspr 0x113, %0" : "=r" (i) : "0" (i)); /* SPRG 3 */
|
||||||
|
|
||||||
i = PPC_MSR_INITIAL & ~PPC_MSR_DISABLE_MASK;
|
|
||||||
asm volatile("mtspr 0x112, %0" : "=r" (i) : "0" (i)); /* SPRG 2 */
|
|
||||||
|
|
||||||
#ifdef Testing
|
|
||||||
{
|
|
||||||
unsigned32 tmp;
|
|
||||||
|
|
||||||
asm volatile ("mfmsr %0" : "=&r" (tmp));
|
|
||||||
msr = tmp;
|
|
||||||
#ifdef ppc403
|
|
||||||
asm volatile ("mfspr %0, 0x3d6" : "=&r" (tmp)); /* EVPR */
|
|
||||||
evpr = tmp;
|
|
||||||
asm volatile ("mfdcr %0, 0x42" : "=&r" (tmp)); /* EXIER */
|
|
||||||
exier = tmp;
|
|
||||||
asm volatile ("mtspr 0x3d6, %0" :: "r" (0)); /* EVPR */
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
/*
|
||||||
|
* Store Msr Value in the IRQ info structure.
|
||||||
|
*/
|
||||||
|
_CPU_MSR_Value(_CPU_IRQ_info.msr_initial);
|
||||||
|
|
||||||
|
#if (PPC_USE_SPRG)
|
||||||
|
i = _CPU_IRQ_info.msr_initial;
|
||||||
|
asm volatile("mtspr 0x112, %0" : "=r" (i) : "0" (i)); /* SPRG 2 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( cpu_table->spurious_handler )
|
if ( cpu_table->spurious_handler )
|
||||||
@@ -129,38 +104,180 @@ void _CPU_Initialize(
|
|||||||
|
|
||||||
/*PAGE
|
/*PAGE
|
||||||
*
|
*
|
||||||
* _CPU_ISR_Get_level
|
* _CPU_ISR_Calculate_level
|
||||||
*
|
|
||||||
* COMMENTS FROM Andrew Bray <andy@i-cubed.co.uk>:
|
|
||||||
*
|
*
|
||||||
* The PowerPC puts its interrupt enable status in the MSR register
|
* The PowerPC puts its interrupt enable status in the MSR register
|
||||||
* which also contains things like endianness control. To be more
|
* which also contains things like endianness control. To be more
|
||||||
* awkward, the layout varies from processor to processor. This
|
* awkward, the layout varies from processor to processor. This
|
||||||
* is why I adopted a table approach in my interrupt handling.
|
* is why it was necessary to adopt a scheme which allowed the user
|
||||||
* Thus the inverse process is slow, because it requires a table
|
* to specify specifically which interrupt sources were enabled.
|
||||||
* search.
|
|
||||||
*
|
|
||||||
* This could fail, and return 4 (an invalid level) if the MSR has been
|
|
||||||
* set to a value not in the table. This is also quite an expensive
|
|
||||||
* operation - I do hope its not too common.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
unsigned32 _CPU_ISR_Calculate_level(
|
||||||
|
unsigned32 new_level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register unsigned32 new_msr = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the critical interrupt enable bit
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (PPC_HAS_RFCI)
|
||||||
|
if ( !(new_level & PPC_INTERRUPT_LEVEL_CE) )
|
||||||
|
new_msr |= PPC_MSR_CE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( !(new_level & PPC_INTERRUPT_LEVEL_ME) )
|
||||||
|
new_msr |= PPC_MSR_ME;
|
||||||
|
|
||||||
|
if ( !(new_level & PPC_INTERRUPT_LEVEL_EE) )
|
||||||
|
new_msr |= PPC_MSR_EE;
|
||||||
|
|
||||||
|
return new_msr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _CPU_ISR_Set_level
|
||||||
|
*
|
||||||
|
* This routine sets the requested level in the MSR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _CPU_ISR_Set_level(
|
||||||
|
unsigned32 new_level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register unsigned32 tmp = 0;
|
||||||
|
register unsigned32 new_msr;
|
||||||
|
|
||||||
|
new_msr = _CPU_ISR_Calculate_level( new_level );
|
||||||
|
|
||||||
|
asm volatile (
|
||||||
|
"mfmsr %0; andc %0,%0,%1; and %2, %2, %1; or %0, %0, %2; mtmsr %0" :
|
||||||
|
"=&r" ((tmp)) :
|
||||||
|
"r" ((PPC_MSR_DISABLE_MASK)), "r" ((new_msr)), "0" ((tmp))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _CPU_ISR_Get_level
|
||||||
|
*
|
||||||
|
* This routine gets the current interrupt level from the MSR and
|
||||||
|
* converts it to an RTEMS interrupt level.
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned32 _CPU_ISR_Get_level( void )
|
unsigned32 _CPU_ISR_Get_level( void )
|
||||||
{
|
{
|
||||||
unsigned32 level, msr;
|
unsigned32 level = 0;
|
||||||
|
unsigned32 msr;
|
||||||
|
|
||||||
asm volatile("mfmsr %0" : "=r" ((msr)));
|
asm volatile("mfmsr %0" : "=r" ((msr)));
|
||||||
|
|
||||||
msr &= PPC_MSR_DISABLE_MASK;
|
msr &= PPC_MSR_DISABLE_MASK;
|
||||||
|
|
||||||
for (level = 0; level < 4; level++)
|
/*
|
||||||
if ((_CPU_msrs[level] & PPC_MSR_DISABLE_MASK) == msr)
|
* Set the critical interrupt enable bit
|
||||||
break;
|
*/
|
||||||
|
|
||||||
|
#if (PPC_HAS_RFCI)
|
||||||
|
if ( !(msr & PPC_MSR_CE) )
|
||||||
|
level |= PPC_INTERRUPT_LEVEL_CE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( !(msr & PPC_MSR_ME) )
|
||||||
|
level |= PPC_INTERRUPT_LEVEL_ME;
|
||||||
|
|
||||||
|
if ( !(msr & PPC_MSR_EE) )
|
||||||
|
level |= PPC_INTERRUPT_LEVEL_EE;
|
||||||
|
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _CPU_Context_Initialize
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (PPC_ABI == PPC_ABI_POWEROPEN)
|
||||||
|
#define CPU_MINIMUM_STACK_FRAME_SIZE 56
|
||||||
|
#else /* PPC_ABI_SVR4 or PPC_ABI_EABI */
|
||||||
|
#define CPU_MINIMUM_STACK_FRAME_SIZE 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _CPU_Context_Initialize(
|
||||||
|
Context_Control *the_context,
|
||||||
|
unsigned32 *stack_base,
|
||||||
|
unsigned32 size,
|
||||||
|
unsigned32 new_level,
|
||||||
|
void *entry_point,
|
||||||
|
boolean is_fp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
unsigned32 msr_value;
|
||||||
|
unsigned32 sp;
|
||||||
|
|
||||||
|
sp = (unsigned32)stack_base + size - CPU_MINIMUM_STACK_FRAME_SIZE;
|
||||||
|
*((unsigned32 *)sp) = 0;
|
||||||
|
the_context->gpr1 = sp;
|
||||||
|
|
||||||
|
the_context->msr = _CPU_ISR_Calculate_level( new_level );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The FP bit of the MSR should only be enabled if this is a floating
|
||||||
|
* point task. Unfortunately, the vfprintf_r routine in newlib
|
||||||
|
* ends up pushing a floating point register regardless of whether or
|
||||||
|
* not a floating point number is being printed. Serious restructuring
|
||||||
|
* of vfprintf.c will be required to avoid this behavior. At this
|
||||||
|
* time (7 July 1997), this restructuring is not being done.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*if ( is_fp ) */
|
||||||
|
the_context->msr |= PPC_MSR_FP;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the task's MSR value:
|
||||||
|
*
|
||||||
|
* + Set the exception prefix bit to point to the exception table
|
||||||
|
* + Force the RI bit
|
||||||
|
* + Use the DR and IR bits
|
||||||
|
*/
|
||||||
|
_CPU_MSR_Value( msr_value );
|
||||||
|
the_context->msr |= (msr_value & PPC_MSR_EP);
|
||||||
|
the_context->msr |= PPC_MSR_RI;
|
||||||
|
the_context->msr |= msr_value & (PPC_MSR_DR|PPC_MSR_IR);
|
||||||
|
|
||||||
|
#if (PPC_ABI == PPC_ABI_POWEROPEN)
|
||||||
|
{ unsigned32 *desc = (unsigned32 *)entry_point;
|
||||||
|
|
||||||
|
the_context->pc = desc[0];
|
||||||
|
the_context->gpr2 = desc[1];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PPC_ABI == PPC_ABI_SVR4)
|
||||||
|
{ unsigned r13 = 0;
|
||||||
|
asm volatile ("mr %0, 13" : "=r" ((r13)));
|
||||||
|
|
||||||
|
the_context->pc = (unsigned32)entry_point;
|
||||||
|
the_context->gpr13 = r13;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PPC_ABI == PPC_ABI_EABI)
|
||||||
|
{ unsigned32 r2 = 0;
|
||||||
|
unsigned r13 = 0;
|
||||||
|
asm volatile ("mr %0,2; mr %1,13" : "=r" ((r2)), "=r" ((r13)));
|
||||||
|
|
||||||
|
the_context->pc = (unsigned32)entry_point;
|
||||||
|
the_context->gpr2 = r2;
|
||||||
|
the_context->gpr13 = r13;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* _CPU_ISR_install_vector
|
/* _CPU_ISR_install_vector
|
||||||
*
|
*
|
||||||
* This kernel routine installs the RTEMS handler for the
|
* This kernel routine installs the RTEMS handler for the
|
||||||
@@ -181,6 +298,7 @@ void _CPU_ISR_install_vector(
|
|||||||
proc_ptr *old_handler
|
proc_ptr *old_handler
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
proc_ptr ignored;
|
||||||
*old_handler = _ISR_Vector_table[ vector ];
|
*old_handler = _ISR_Vector_table[ vector ];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -189,6 +307,12 @@ void _CPU_ISR_install_vector(
|
|||||||
* handler for this vector number.
|
* handler for this vector number.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Install the wrapper so this ISR can be invoked properly.
|
||||||
|
*/
|
||||||
|
if (_CPU_Table.exceptions_in_RAM)
|
||||||
|
_CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We put the actual user ISR address in '_ISR_vector_table'. This will
|
* We put the actual user ISR address in '_ISR_vector_table'. This will
|
||||||
* be used by the _ISR_Handler so the user gets control.
|
* be used by the _ISR_Handler so the user gets control.
|
||||||
@@ -226,39 +350,273 @@ static void ppc_spurious(int v, CPU_Interrupt_frame *i)
|
|||||||
{
|
{
|
||||||
register int r = 0;
|
register int r = 0;
|
||||||
|
|
||||||
asm volatile("mtdcr 0x42, %0" : "=r" ((r)) : "0" ((r))); /* EXIER */
|
asm volatile("mtdcr 0x42, %0" :
|
||||||
|
"=&r" ((r)) : "0" ((r))); /* EXIER */
|
||||||
}
|
}
|
||||||
else if (v == PPC_IRQ_PIT)
|
else if (v == PPC_IRQ_PIT)
|
||||||
{
|
{
|
||||||
register int r = 0x08000000;
|
register int r = 0x08000000;
|
||||||
|
|
||||||
asm volatile("mtspr 0x3d8, %0" : "=r" ((r)) : "0" ((r))); /* TSR */
|
asm volatile("mtspr 0x3d8, %0" :
|
||||||
|
"=&r" ((r)) : "0" ((r))); /* TSR */
|
||||||
}
|
}
|
||||||
else if (v == PPC_IRQ_FIT)
|
else if (v == PPC_IRQ_FIT)
|
||||||
{
|
{
|
||||||
register int r = 0x04000000;
|
register int r = 0x04000000;
|
||||||
|
|
||||||
asm volatile("mtspr 0x3d8, %0" : "=r" ((r)) : "0" ((r))); /* TSR */
|
asm volatile("mtspr 0x3d8, %0" :
|
||||||
|
"=&r" ((r)) : "0" ((r))); /* TSR */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void _CPU_Fatal_error(unsigned32 _error)
|
void _CPU_Fatal_error(unsigned32 _error)
|
||||||
{
|
{
|
||||||
#ifdef Testing
|
|
||||||
unsigned32 tmp;
|
|
||||||
|
|
||||||
tmp = msr;
|
|
||||||
asm volatile ("mtmsr %0" :: "r" (tmp));
|
|
||||||
#ifdef ppc403
|
|
||||||
tmp = evpr;
|
|
||||||
asm volatile ("mtspr 0x3d6, %0" :: "r" (tmp)); /* EVPR */
|
|
||||||
tmp = exier;
|
|
||||||
asm volatile ("mtdcr 0x42, %0" :: "r" (tmp)); /* EXIER */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
asm volatile ("mr 3, %0" : : "r" ((_error)));
|
asm volatile ("mr 3, %0" : : "r" ((_error)));
|
||||||
asm volatile ("tweq 5,5");
|
asm volatile ("tweq 5,5");
|
||||||
asm volatile ("li 0,0; mtmsr 0");
|
asm volatile ("li 0,0; mtmsr 0");
|
||||||
while (1) ;
|
while (1) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PPC_SYNCHRONOUS_TRAP_BIT_MASK 0x100
|
||||||
|
#define PPC_ASYNCHRONOUS_TRAP( _trap ) (_trap)
|
||||||
|
#define PPC_SYNCHRONOUS_TRAP ( _trap ) ((_trap)+PPC_SYNCHRONOUS_TRAP_BIT_MASK)
|
||||||
|
#define PPC_REAL_TRAP_NUMBER ( _trap ) ((_trap)%PPC_SYNCHRONOUS_TRAP_BIT_MASK)
|
||||||
|
|
||||||
|
|
||||||
|
const CPU_Trap_table_entry _CPU_Trap_slot_template = {
|
||||||
|
|
||||||
|
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
|
||||||
|
#error " Vector install not tested."
|
||||||
|
#if (PPC_HAS_FPU)
|
||||||
|
#error " Vector install not tested."
|
||||||
|
0x9421feb0, /* stwu r1, -(20*4 + 18*8 + IP_END)(r1) */
|
||||||
|
#else
|
||||||
|
#error " Vector install not tested."
|
||||||
|
0x9421ff40, /* stwu r1, -(20*4 + IP_END)(r1) */
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
0x9421ff90, /* stwu r1, -(IP_END)(r1) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
0x90010008, /* stw %r0, IP_0(%r1) */
|
||||||
|
0x38000000, /* li %r0, PPC_IRQ */
|
||||||
|
0x48000002 /* ba PROC (_ISR_Handler) */
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned32 ppc_exception_vector_addr(
|
||||||
|
unsigned32 vector
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _CPU_ISR_install_raw_handler
|
||||||
|
*
|
||||||
|
* This routine installs the specified handler as a "raw" non-executive
|
||||||
|
* supported trap handler (a.k.a. interrupt service routine).
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* vector - trap table entry number plus synchronous
|
||||||
|
* vs. asynchronous information
|
||||||
|
* new_handler - address of the handler to be installed
|
||||||
|
* old_handler - pointer to an address of the handler previously installed
|
||||||
|
*
|
||||||
|
* Output Parameters: NONE
|
||||||
|
* *new_handler - address of the handler previously installed
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
*
|
||||||
|
* This routine is based on the SPARC routine _CPU_ISR_install_raw_handler.
|
||||||
|
* Install a software trap handler as an executive interrupt handler
|
||||||
|
* (which is desirable since RTEMS takes care of window and register issues),
|
||||||
|
* then the executive needs to know that the return address is to the trap
|
||||||
|
* rather than the instruction following the trap.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _CPU_ISR_install_raw_handler(
|
||||||
|
unsigned32 vector,
|
||||||
|
proc_ptr new_handler,
|
||||||
|
proc_ptr *old_handler
|
||||||
|
)
|
||||||
|
{
|
||||||
|
unsigned32 real_vector;
|
||||||
|
CPU_Trap_table_entry *slot;
|
||||||
|
unsigned32 u32_handler=0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the "real" trap number for this vector ignoring the synchronous
|
||||||
|
* versus asynchronous indicator included with our vector numbers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
real_vector = vector;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the current base address of the trap table and calculate a pointer
|
||||||
|
* to the slot we are interested in.
|
||||||
|
*/
|
||||||
|
slot = (CPU_Trap_table_entry *)ppc_exception_vector_addr( real_vector );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the address of the old_handler from the trap table.
|
||||||
|
*
|
||||||
|
* NOTE: The old_handler returned will be bogus if it does not follow
|
||||||
|
* the RTEMS model.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define HIGH_BITS_MASK 0xFFFFFC00
|
||||||
|
#define HIGH_BITS_SHIFT 10
|
||||||
|
#define LOW_BITS_MASK 0x000003FF
|
||||||
|
|
||||||
|
if (slot->stwu_r1 == _CPU_Trap_slot_template.stwu_r1) {
|
||||||
|
/*
|
||||||
|
* Set u32_handler = to target address
|
||||||
|
*/
|
||||||
|
u32_handler = slot->b_Handler & 0x03fffffc;
|
||||||
|
*old_handler = (proc_ptr) u32_handler;
|
||||||
|
} else
|
||||||
|
*old_handler = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the template to the slot and then fix it.
|
||||||
|
*/
|
||||||
|
*slot = _CPU_Trap_slot_template;
|
||||||
|
|
||||||
|
u32_handler = (unsigned32) new_handler;
|
||||||
|
slot->b_Handler |= u32_handler;
|
||||||
|
|
||||||
|
slot->li_r0_IRQ |= vector;
|
||||||
|
|
||||||
|
_CPU_Data_Cache_Block_Flush( slot );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned32 ppc_exception_vector_addr(
|
||||||
|
unsigned32 vector
|
||||||
|
)
|
||||||
|
{
|
||||||
|
unsigned32 Msr;
|
||||||
|
unsigned32 Top = 0;
|
||||||
|
unsigned32 Offset = 0x000;
|
||||||
|
|
||||||
|
_CPU_MSR_Value ( Msr );
|
||||||
|
if ( ( Msr & PPC_MSR_EP) != 0 ) /* Vectors at FFFx_xxxx */
|
||||||
|
Top = 0xfff00000;
|
||||||
|
|
||||||
|
switch ( vector ) {
|
||||||
|
case PPC_IRQ_SYSTEM_RESET: /* on 40x aka PPC_IRQ_CRIT */
|
||||||
|
Offset = 0x00100;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_MCHECK:
|
||||||
|
Offset = 0x00200;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_PROTECT:
|
||||||
|
Offset = 0x00300;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_ISI:
|
||||||
|
Offset = 0x00400;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_EXTERNAL:
|
||||||
|
Offset = 0x00500;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_ALIGNMENT:
|
||||||
|
Offset = 0x00600;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_PROGRAM:
|
||||||
|
Offset = 0x00700;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_NOFP:
|
||||||
|
Offset = 0x00800;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_DECREMENTER:
|
||||||
|
Offset = 0x00900;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_RESERVED_A:
|
||||||
|
Offset = 0x00a00;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_RESERVED_B:
|
||||||
|
Offset = 0x00b00;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_SCALL:
|
||||||
|
Offset = 0x00c00;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_TRACE:
|
||||||
|
Offset = 0x00d00;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_FP_ASST:
|
||||||
|
Offset = 0x00e00;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if defined(ppc403)
|
||||||
|
|
||||||
|
/* PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET
|
||||||
|
case PPC_IRQ_CRIT:
|
||||||
|
Offset = 0x00100;
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case PPC_IRQ_PIT:
|
||||||
|
Offset = 0x01000;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_FIT:
|
||||||
|
Offset = 0x01010;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_WATCHDOG:
|
||||||
|
Offset = 0x01020;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_DEBUG:
|
||||||
|
Offset = 0x02000;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#elif defined(ppc601)
|
||||||
|
case PPC_IRQ_TRACE:
|
||||||
|
Offset = 0x02000;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#elif defined(ppc603)
|
||||||
|
case PPC_IRQ_TRANS_MISS:
|
||||||
|
Offset = 0x1000;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_DATA_LOAD:
|
||||||
|
Offset = 0x1100;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_DATA_STORE:
|
||||||
|
Offset = 0x1200;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_ADDR_BRK:
|
||||||
|
Offset = 0x1300;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_SYS_MGT:
|
||||||
|
Offset = 0x1400;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#elif defined(ppc603e)
|
||||||
|
case PPC_TLB_INST_MISS:
|
||||||
|
Offset = 0x1000;
|
||||||
|
break;
|
||||||
|
case PPC_TLB_LOAD_MISS:
|
||||||
|
Offset = 0x1100;
|
||||||
|
break;
|
||||||
|
case PPC_TLB_STORE_MISS:
|
||||||
|
Offset = 0x1200;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_ADDRBRK:
|
||||||
|
Offset = 0x1300;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_SYS_MGT:
|
||||||
|
Offset = 0x1400;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#elif defined(ppc604)
|
||||||
|
case PPC_IRQ_ADDR_BRK:
|
||||||
|
Offset = 0x1300;
|
||||||
|
break;
|
||||||
|
case PPC_IRQ_SYS_MGT:
|
||||||
|
Offset = 0x1400;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
Top += Offset;
|
||||||
|
return Top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,12 +20,12 @@
|
|||||||
*
|
*
|
||||||
* Derived from c/src/exec/cpu/no_cpu/cpu.h:
|
* Derived from c/src/exec/cpu/no_cpu/cpu.h:
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 1989-1998.
|
* COPYRIGHT (c) 1989-1997.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
* Copyright assigned to U.S. Government, 1994.
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may in
|
||||||
* found in the file LICENSE in this distribution or at
|
* the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
@@ -285,7 +285,7 @@ struct CPU_Interrupt_frame;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define CPU_STRUCTURE_ALIGNMENT \
|
#define CPU_STRUCTURE_ALIGNMENT \
|
||||||
__attribute__ ((aligned (PPC_CACHE_ALIGNMENT)))
|
__attribute__ ((aligned (PPC_CACHE_ALIGNMENT)))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define what is required to specify how the network to host conversion
|
* Define what is required to specify how the network to host conversion
|
||||||
@@ -300,16 +300,27 @@ struct CPU_Interrupt_frame;
|
|||||||
* The following defines the number of bits actually used in the
|
* The following defines the number of bits actually used in the
|
||||||
* interrupt field of the task mode. How those bits map to the
|
* interrupt field of the task mode. How those bits map to the
|
||||||
* CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
|
* CPU interrupt levels is defined by the routine _CPU_ISR_Set_level().
|
||||||
*/
|
*
|
||||||
/*
|
* The interrupt level is bit mapped for the PowerPC family. The
|
||||||
* ACB Note: Levels are:
|
* bits are set to 0 to indicate that a particular exception source
|
||||||
* 0: All maskable interrupts enabled
|
* enabled and 1 if it is disabled. This keeps with RTEMS convention
|
||||||
* 1: Other critical exceptions enabled
|
* that interrupt level 0 means all sources are enabled.
|
||||||
* 2: Machine check enabled
|
*
|
||||||
* 3: All maskable IRQs disabled
|
* The bits are assigned to correspond to enable bits in the MSR.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CPU_MODES_INTERRUPT_MASK 0x00000003
|
#define PPC_INTERRUPT_LEVEL_ME 0x01
|
||||||
|
#define PPC_INTERRUPT_LEVEL_EE 0x02
|
||||||
|
#define PPC_INTERRUPT_LEVEL_CE 0x04
|
||||||
|
|
||||||
|
/* XXX should these be maskable? */
|
||||||
|
#if 0
|
||||||
|
#define PPC_INTERRUPT_LEVEL_DE 0x08
|
||||||
|
#define PPC_INTERRUPT_LEVEL_BE 0x10
|
||||||
|
#define PPC_INTERRUPT_LEVEL_SE 0x20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CPU_MODES_INTERRUPT_MASK 0x00000007
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Processor defined structures
|
* Processor defined structures
|
||||||
@@ -450,17 +461,37 @@ typedef struct {
|
|||||||
void (*stack_free_hook)( void* );
|
void (*stack_free_hook)( void* );
|
||||||
/* end of fields required on all CPUs */
|
/* end of fields required on all CPUs */
|
||||||
|
|
||||||
unsigned32 clicks_per_usec; /* Timer clicks per microsecond */
|
unsigned32 clicks_per_usec; /* Timer clicks per microsecond */
|
||||||
unsigned32 serial_per_sec; /* Serial clocks per second */
|
void (*spurious_handler)(unsigned32 vector, CPU_Interrupt_frame *);
|
||||||
|
boolean exceptions_in_RAM; /* TRUE if in RAM */
|
||||||
|
|
||||||
|
#if defined(ppc403)
|
||||||
|
unsigned32 serial_per_sec; /* Serial clocks per second */
|
||||||
boolean serial_external_clock;
|
boolean serial_external_clock;
|
||||||
boolean serial_xon_xoff;
|
boolean serial_xon_xoff;
|
||||||
boolean serial_cts_rts;
|
boolean serial_cts_rts;
|
||||||
unsigned32 serial_rate;
|
unsigned32 serial_rate;
|
||||||
unsigned32 timer_average_overhead; /* Average overhead of timer in ticks */
|
unsigned32 timer_average_overhead; /* Average overhead of timer in ticks */
|
||||||
unsigned32 timer_least_valid; /* Least valid number from timer */
|
unsigned32 timer_least_valid; /* Least valid number from timer */
|
||||||
void (*spurious_handler)(unsigned32 vector, CPU_Interrupt_frame *);
|
#endif
|
||||||
} rtems_cpu_table;
|
} rtems_cpu_table;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following type defines an entry in the PPC's trap table.
|
||||||
|
*
|
||||||
|
* NOTE: The instructions chosen are RTEMS dependent although one is
|
||||||
|
* obligated to use two of the four instructions to perform a
|
||||||
|
* long jump. The other instructions load one register with the
|
||||||
|
* trap type (a.k.a. vector) and another with the psr.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned32 stwu_r1; /* stwu %r1, -(??+IP_END)(%1)*/
|
||||||
|
unsigned32 stw_r0; /* stw %r0, IP_0(%r1) */
|
||||||
|
unsigned32 li_r0_IRQ; /* li %r0, _IRQ */
|
||||||
|
unsigned32 b_Handler; /* b PROC (_ISR_Handler) */
|
||||||
|
} CPU_Trap_table_entry;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This variable is optional. It is used on CPUs on which it is difficult
|
* This variable is optional. It is used on CPUs on which it is difficult
|
||||||
* to generate an "uninitialized" FP context. It is filled in by
|
* to generate an "uninitialized" FP context. It is filled in by
|
||||||
@@ -502,6 +533,7 @@ SCORE_EXTERN void *_CPU_Interrupt_stack_high;
|
|||||||
* Nothing prevents the porter from declaring more CPU specific variables.
|
* Nothing prevents the porter from declaring more CPU specific variables.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
SCORE_EXTERN struct {
|
SCORE_EXTERN struct {
|
||||||
unsigned32 *Nest_level;
|
unsigned32 *Nest_level;
|
||||||
unsigned32 *Disable_level;
|
unsigned32 *Disable_level;
|
||||||
@@ -517,6 +549,8 @@ SCORE_EXTERN struct {
|
|||||||
#endif
|
#endif
|
||||||
volatile boolean *Switch_necessary;
|
volatile boolean *Switch_necessary;
|
||||||
boolean *Signal;
|
boolean *Signal;
|
||||||
|
|
||||||
|
unsigned32 msr_initial;
|
||||||
} _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT;
|
} _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -549,8 +583,8 @@ SCORE_EXTERN struct {
|
|||||||
* by RTEMS.
|
* by RTEMS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)
|
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)
|
||||||
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
|
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (PPC_INTERRUPT_MAX - 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Should be large enough to run all RTEMS tests. This insures
|
* Should be large enough to run all RTEMS tests. This insures
|
||||||
@@ -609,45 +643,94 @@ SCORE_EXTERN struct {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable all interrupts for an RTEMS critical section. The previous
|
* Disable all interrupts for an RTEMS critical section. The previous
|
||||||
* level is returned in _level.
|
* level is returned in _isr_cookie.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define loc_string(a,b) a " (" #b ")\n"
|
#define loc_string(a,b) a " (" #b ")\n"
|
||||||
|
|
||||||
|
#define _CPU_MSR_Value( _msr_value ) \
|
||||||
|
do { \
|
||||||
|
_msr_value = 0; \
|
||||||
|
asm volatile ("mfmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define _CPU_MSR_SET( _msr_value ) \
|
||||||
|
{ asm volatile ("mtmsr %0" : "=&r" ((_msr_value)) : "0" ((_msr_value))); }
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define _CPU_ISR_Disable( _isr_cookie ) \
|
#define _CPU_ISR_Disable( _isr_cookie ) \
|
||||||
{ \
|
{ register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \
|
||||||
|
_isr_cookie = 0; \
|
||||||
|
asm volatile (
|
||||||
|
"mfmsr %0" : \
|
||||||
|
"=r" ((_isr_cookie)) : \
|
||||||
|
"0" ((_isr_cookie)) \
|
||||||
|
); \
|
||||||
|
asm volatile (
|
||||||
|
"andc %1,%0,%1" : \
|
||||||
|
"=r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
|
||||||
|
"0" ((_isr_cookie)), "1" ((_disable_mask)) \
|
||||||
|
); \
|
||||||
|
asm volatile (
|
||||||
|
"mtmsr %1" : \
|
||||||
|
"=r" ((_disable_mask)) : \
|
||||||
|
"0" ((_disable_mask)) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _CPU_ISR_Disable( _isr_cookie ) \
|
||||||
|
{ register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \
|
||||||
|
_isr_cookie = 0; \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"mfmsr %0; andc %1,%0,%1; mtmsr %1" : \
|
"mfmsr %0; andc %1,%0,%1; mtmsr %1" : \
|
||||||
"=&r" ((_isr_cookie)) : "r" ((PPC_MSR_DISABLE_MASK)) \
|
"=&r" ((_isr_cookie)), "=&r" ((_disable_mask)) : \
|
||||||
|
"0" ((_isr_cookie)), "1" ((_disable_mask)) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define _CPU_Data_Cache_Block_Flush( _address ) \
|
||||||
|
do { register void *__address = (_address); \
|
||||||
|
register unsigned32 _zero = 0; \
|
||||||
|
asm volatile ( "dcbf %0,%1" : \
|
||||||
|
"=r" (_zero), "=r" (__address) : \
|
||||||
|
"0" (_zero), "1" (__address) \
|
||||||
|
); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
|
* Enable interrupts to the previous level (returned by _CPU_ISR_Disable).
|
||||||
* This indicates the end of an RTEMS critical section. The parameter
|
* This indicates the end of an RTEMS critical section. The parameter
|
||||||
* _level is not modified.
|
* _isr_cookie is not modified.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_ISR_Enable( _isr_cookie ) \
|
#define _CPU_ISR_Enable( _isr_cookie ) \
|
||||||
{ \
|
{ \
|
||||||
asm volatile ( "mtmsr %0" : \
|
asm volatile ( "mtmsr %0" : \
|
||||||
"=&r" ((_isr_cookie)) : "0" ((_isr_cookie))); \
|
"=r" ((_isr_cookie)) : \
|
||||||
|
"0" ((_isr_cookie))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This temporarily restores the interrupt to _level before immediately
|
* This temporarily restores the interrupt to _isr_cookie before immediately
|
||||||
* disabling them again. This is used to divide long RTEMS critical
|
* disabling them again. This is used to divide long RTEMS critical
|
||||||
* sections into two or more parts. The parameter _level is not
|
* sections into two or more parts. The parameter _isr_cookie is not
|
||||||
* modified.
|
* modified.
|
||||||
|
*
|
||||||
|
* NOTE: The version being used is not very optimized but it does
|
||||||
|
* not trip a problem in gcc where the disable mask does not
|
||||||
|
* get loaded. Check this for future (post 10/97 gcc versions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_ISR_Flash( _isr_cookie ) \
|
#define _CPU_ISR_Flash( _isr_cookie ) \
|
||||||
{ \
|
{ register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \
|
||||||
asm volatile ( \
|
asm volatile ( \
|
||||||
"mtmsr %0; andc %1,%0,%1; mtmsr %1" : \
|
"mtmsr %0; andc %1,%0,%1; mtmsr %1" : \
|
||||||
"=r" ((_isr_cookie)) : \
|
"=r" ((_isr_cookie)), "=r" ((_disable_mask)) : \
|
||||||
"r" ((PPC_MSR_DISABLE_MASK)), "0" ((_isr_cookie)) \
|
"0" ((_isr_cookie)), "1" ((_disable_mask)) \
|
||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -661,20 +744,53 @@ SCORE_EXTERN struct {
|
|||||||
* via the rtems_task_mode directive.
|
* via the rtems_task_mode directive.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _CPU_ISR_Set_level( new_level ) \
|
unsigned32 _CPU_ISR_Calculate_level(
|
||||||
{ \
|
unsigned32 new_level
|
||||||
register unsigned32 tmp = 0; \
|
);
|
||||||
asm volatile ( \
|
|
||||||
"mfmsr %0; andc %0,%0,%1; and %2, %2, %1; or %0, %0, %2; mtmsr %0" : \
|
|
||||||
"=r" ((tmp)) : \
|
|
||||||
"r" ((PPC_MSR_DISABLE_MASK)), "r" ((_CPU_msrs[new_level])), "0" ((tmp)) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void _CPU_ISR_Set_level(
|
||||||
|
unsigned32 new_level
|
||||||
|
);
|
||||||
|
|
||||||
unsigned32 _CPU_ISR_Get_level( void );
|
unsigned32 _CPU_ISR_Get_level( void );
|
||||||
|
|
||||||
|
void _CPU_ISR_install_raw_handler(
|
||||||
|
unsigned32 vector,
|
||||||
|
proc_ptr new_handler,
|
||||||
|
proc_ptr *old_handler
|
||||||
|
);
|
||||||
|
|
||||||
/* end of ISR handler macros */
|
/* end of ISR handler macros */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Simple spin delay in microsecond units for device drivers.
|
||||||
|
* This is very dependent on the clock speed of the target.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CPU_Get_timebase_low( _value ) \
|
||||||
|
asm volatile( "mftb %0" : "=r" (_value) )
|
||||||
|
|
||||||
|
#define delay( _microseconds ) \
|
||||||
|
do { \
|
||||||
|
unsigned32 start, ticks, now; \
|
||||||
|
CPU_Get_timebase_low( start ) ; \
|
||||||
|
ticks = (_microseconds) * Cpu_table.clicks_per_usec; \
|
||||||
|
do \
|
||||||
|
CPU_Get_timebase_low( now ) ; \
|
||||||
|
while (now - start < ticks); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define delay_in_bus_cycles( _cycles ) \
|
||||||
|
do { \
|
||||||
|
unsigned32 start, now; \
|
||||||
|
CPU_Get_timebase_low( start ); \
|
||||||
|
do \
|
||||||
|
CPU_Get_timebase_low( now ); \
|
||||||
|
while (now - start < (_cycles)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Context handler macros */
|
/* Context handler macros */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -691,63 +807,18 @@ unsigned32 _CPU_ISR_Get_level( void );
|
|||||||
* This routine generally does not set any unnecessary register
|
* This routine generally does not set any unnecessary register
|
||||||
* in the context. The state of the "general data" registers is
|
* in the context. The state of the "general data" registers is
|
||||||
* undefined at task start time.
|
* undefined at task start time.
|
||||||
|
*
|
||||||
|
* NOTE: Implemented as a subroutine for the SPARC port.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if PPC_ABI == PPC_ABI_POWEROPEN
|
void _CPU_Context_Initialize(
|
||||||
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
|
Context_Control *the_context,
|
||||||
_isr, _entry_point, _is_fp ) \
|
unsigned32 *stack_base,
|
||||||
{ \
|
unsigned32 size,
|
||||||
unsigned32 sp, *desc; \
|
unsigned32 new_level,
|
||||||
\
|
void *entry_point,
|
||||||
sp = ((unsigned32)_stack_base) + (_size) - 56; \
|
boolean is_fp
|
||||||
*((unsigned32 *)sp) = 0; \
|
);
|
||||||
\
|
|
||||||
desc = (unsigned32 *)_entry_point; \
|
|
||||||
\
|
|
||||||
(_the_context)->msr = PPC_MSR_INITIAL | \
|
|
||||||
_CPU_msrs[ _isr ]; \
|
|
||||||
(_the_context)->pc = desc[0]; \
|
|
||||||
(_the_context)->gpr1 = sp; \
|
|
||||||
(_the_context)->gpr2 = desc[1]; \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if PPC_ABI == PPC_ABI_SVR4
|
|
||||||
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
|
|
||||||
_isr, _entry_point ) \
|
|
||||||
{ \
|
|
||||||
unsigned32 sp, r13; \
|
|
||||||
\
|
|
||||||
sp = ((unsigned32)_stack_base) + (_size) - 8; \
|
|
||||||
*((unsigned32 *)sp) = 0; \
|
|
||||||
\
|
|
||||||
asm volatile ("mr %0, 13" : "=r" ((r13))); \
|
|
||||||
\
|
|
||||||
(_the_context->msr) = PPC_MSR_INITIAL | \
|
|
||||||
_CPU_msrs[ _isr ]; \
|
|
||||||
(_the_context->pc) = _entry_point; \
|
|
||||||
(_the_context->gpr1) = sp; \
|
|
||||||
(_the_context->gpr13) = r13; \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if PPC_ABI == PPC_ABI_EABI
|
|
||||||
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
|
|
||||||
_isr, _entry_point ) \
|
|
||||||
{ \
|
|
||||||
unsigned32 sp, r2, r13; \
|
|
||||||
\
|
|
||||||
sp = ((unsigned32)_stack_base) + (_size) - 8; \
|
|
||||||
*((unsigned32 *)sp) = 0; \
|
|
||||||
\
|
|
||||||
asm volatile ("mr %0,2; mr %1,13" : "=r" ((r2)), "=r" ((r13))); \
|
|
||||||
\
|
|
||||||
(_the_context)->msr = PPC_MSR_INITIAL | \
|
|
||||||
_CPU_msrs[ _isr ]; \
|
|
||||||
(_the_context->pc) = _entry_point; \
|
|
||||||
(_the_context->gpr1) = sp; \
|
|
||||||
(_the_context->gpr2) = r2; \
|
|
||||||
(_the_context->gpr13) = r13; \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine is responsible for somehow restarting the currently
|
* This routine is responsible for somehow restarting the currently
|
||||||
@@ -911,7 +982,7 @@ extern const unsigned32 _CPU_msrs[4];
|
|||||||
|
|
||||||
void _CPU_Initialize(
|
void _CPU_Initialize(
|
||||||
rtems_cpu_table *cpu_table,
|
rtems_cpu_table *cpu_table,
|
||||||
void (*thread_dispatch)
|
void (*thread_dispatch)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -951,7 +1022,7 @@ void _CPU_Context_switch(
|
|||||||
/*
|
/*
|
||||||
* _CPU_Context_restore
|
* _CPU_Context_restore
|
||||||
*
|
*
|
||||||
* This routine is generally used only to restart self in an
|
* This routine is generallu used only to restart self in an
|
||||||
* efficient manner. It may simply be a label in _CPU_Context_switch.
|
* efficient manner. It may simply be a label in _CPU_Context_switch.
|
||||||
*
|
*
|
||||||
* NOTE: May be unnecessary to reload some registers.
|
* NOTE: May be unnecessary to reload some registers.
|
||||||
|
|||||||
@@ -21,12 +21,12 @@
|
|||||||
*
|
*
|
||||||
* Derived from c/src/exec/cpu/no_cpu/cpu_asm.c:
|
* Derived from c/src/exec/cpu/no_cpu/cpu_asm.c:
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 1989-1998.
|
* COPYRIGHT (c) 1989-1997.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
* Copyright assigned to U.S. Government, 1994.
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may in
|
||||||
* found in the file LICENSE in this distribution or at
|
* the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
@@ -174,6 +174,7 @@
|
|||||||
.set IP_END, (IP_MSR + 16)
|
.set IP_END, (IP_MSR + 16)
|
||||||
|
|
||||||
/* _CPU_IRQ_info offsets */
|
/* _CPU_IRQ_info offsets */
|
||||||
|
|
||||||
/* These must be in this order */
|
/* These must be in this order */
|
||||||
.set Nest_level, 0
|
.set Nest_level, 0
|
||||||
.set Disable_level, 4
|
.set Disable_level, 4
|
||||||
@@ -192,7 +193,8 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
.set Signal, Switch_necessary + 4
|
.set Signal, Switch_necessary + 4
|
||||||
|
.set msr_initial, Signal + 4
|
||||||
|
|
||||||
BEGIN_CODE
|
BEGIN_CODE
|
||||||
/*
|
/*
|
||||||
* _CPU_Context_save_fp_context
|
* _CPU_Context_save_fp_context
|
||||||
@@ -453,45 +455,66 @@ PROC (_CPU_Context_switch):
|
|||||||
/* This assumes that all the registers are in the given order */
|
/* This assumes that all the registers are in the given order */
|
||||||
li r5, 16
|
li r5, 16
|
||||||
addi r3,r3,-4
|
addi r3,r3,-4
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stw r1, GP_1+4(r3)
|
stw r1, GP_1+4(r3)
|
||||||
stw r2, GP_2+4(r3)
|
stw r2, GP_2+4(r3)
|
||||||
#if (PPC_USE_MULTIPLE == 1)
|
#if (PPC_USE_MULTIPLE == 1)
|
||||||
addi r3, r3, GP_14+4
|
addi r3, r3, GP_14+4
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
|
|
||||||
addi r3, r3, GP_18-GP_14
|
addi r3, r3, GP_18-GP_14
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
addi r3, r3, GP_22-GP_18
|
addi r3, r3, GP_22-GP_18
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
addi r3, r3, GP_26-GP_22
|
addi r3, r3, GP_26-GP_22
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stmw r13, GP_13-GP_26(r3)
|
stmw r13, GP_13-GP_26(r3)
|
||||||
#else
|
#else
|
||||||
stw r13, GP_13+4(r3)
|
stw r13, GP_13+4(r3)
|
||||||
stwu r14, GP_14+4(r3)
|
stwu r14, GP_14+4(r3)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stw r15, GP_15-GP_14(r3)
|
stw r15, GP_15-GP_14(r3)
|
||||||
stw r16, GP_16-GP_14(r3)
|
stw r16, GP_16-GP_14(r3)
|
||||||
stw r17, GP_17-GP_14(r3)
|
stw r17, GP_17-GP_14(r3)
|
||||||
stwu r18, GP_18-GP_14(r3)
|
stwu r18, GP_18-GP_14(r3)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stw r19, GP_19-GP_18(r3)
|
stw r19, GP_19-GP_18(r3)
|
||||||
stw r20, GP_20-GP_18(r3)
|
stw r20, GP_20-GP_18(r3)
|
||||||
stw r21, GP_21-GP_18(r3)
|
stw r21, GP_21-GP_18(r3)
|
||||||
stwu r22, GP_22-GP_18(r3)
|
stwu r22, GP_22-GP_18(r3)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stw r23, GP_23-GP_22(r3)
|
stw r23, GP_23-GP_22(r3)
|
||||||
stw r24, GP_24-GP_22(r3)
|
stw r24, GP_24-GP_22(r3)
|
||||||
stw r25, GP_25-GP_22(r3)
|
stw r25, GP_25-GP_22(r3)
|
||||||
stwu r26, GP_26-GP_22(r3)
|
stwu r26, GP_26-GP_22(r3)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stw r27, GP_27-GP_26(r3)
|
stw r27, GP_27-GP_26(r3)
|
||||||
stw r28, GP_28-GP_26(r3)
|
stw r28, GP_28-GP_26(r3)
|
||||||
stw r29, GP_29-GP_26(r3)
|
stw r29, GP_29-GP_26(r3)
|
||||||
stw r30, GP_30-GP_26(r3)
|
stw r30, GP_30-GP_26(r3)
|
||||||
stw r31, GP_31-GP_26(r3)
|
stw r31, GP_31-GP_26(r3)
|
||||||
#endif
|
#endif
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r0, r4
|
dcbt r0, r4
|
||||||
|
#endif
|
||||||
mfcr r6
|
mfcr r6
|
||||||
stw r6, GP_CR-GP_26(r3)
|
stw r6, GP_CR-GP_26(r3)
|
||||||
mflr r7
|
mflr r7
|
||||||
@@ -499,39 +522,57 @@ PROC (_CPU_Context_switch):
|
|||||||
mfmsr r8
|
mfmsr r8
|
||||||
stw r8, GP_MSR-GP_26(r3)
|
stw r8, GP_MSR-GP_26(r3)
|
||||||
|
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lwz r1, GP_1(r4)
|
lwz r1, GP_1(r4)
|
||||||
lwz r2, GP_2(r4)
|
lwz r2, GP_2(r4)
|
||||||
#if (PPC_USE_MULTIPLE == 1)
|
#if (PPC_USE_MULTIPLE == 1)
|
||||||
addi r4, r4, GP_15
|
addi r4, r4, GP_15
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
addi r4, r4, GP_19-GP_15
|
addi r4, r4, GP_19-GP_15
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
addi r4, r4, GP_23-GP_19
|
addi r4, r4, GP_23-GP_19
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
addi r4, r4, GP_27-GP_23
|
addi r4, r4, GP_27-GP_23
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lmw r13, GP_13-GP_27(r4)
|
lmw r13, GP_13-GP_27(r4)
|
||||||
#else
|
#else
|
||||||
lwz r13, GP_13(r4)
|
lwz r13, GP_13(r4)
|
||||||
lwz r14, GP_14(r4)
|
lwz r14, GP_14(r4)
|
||||||
lwzu r15, GP_15(r4)
|
lwzu r15, GP_15(r4)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lwz r16, GP_16-GP_15(r4)
|
lwz r16, GP_16-GP_15(r4)
|
||||||
lwz r17, GP_17-GP_15(r4)
|
lwz r17, GP_17-GP_15(r4)
|
||||||
lwz r18, GP_18-GP_15(r4)
|
lwz r18, GP_18-GP_15(r4)
|
||||||
lwzu r19, GP_19-GP_15(r4)
|
lwzu r19, GP_19-GP_15(r4)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lwz r20, GP_20-GP_19(r4)
|
lwz r20, GP_20-GP_19(r4)
|
||||||
lwz r21, GP_21-GP_19(r4)
|
lwz r21, GP_21-GP_19(r4)
|
||||||
lwz r22, GP_22-GP_19(r4)
|
lwz r22, GP_22-GP_19(r4)
|
||||||
lwzu r23, GP_23-GP_19(r4)
|
lwzu r23, GP_23-GP_19(r4)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lwz r24, GP_24-GP_23(r4)
|
lwz r24, GP_24-GP_23(r4)
|
||||||
lwz r25, GP_25-GP_23(r4)
|
lwz r25, GP_25-GP_23(r4)
|
||||||
lwz r26, GP_26-GP_23(r4)
|
lwz r26, GP_26-GP_23(r4)
|
||||||
lwzu r27, GP_27-GP_23(r4)
|
lwzu r27, GP_27-GP_23(r4)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lwz r28, GP_28-GP_27(r4)
|
lwz r28, GP_28-GP_27(r4)
|
||||||
lwz r29, GP_29-GP_27(r4)
|
lwz r29, GP_29-GP_27(r4)
|
||||||
lwz r30, GP_30-GP_27(r4)
|
lwz r30, GP_30-GP_27(r4)
|
||||||
@@ -548,12 +589,16 @@ PROC (_CPU_Context_switch):
|
|||||||
/* This assumes that all the registers are in the given order */
|
/* This assumes that all the registers are in the given order */
|
||||||
li r5, 32
|
li r5, 32
|
||||||
addi r3,r3,-4
|
addi r3,r3,-4
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stw r1, GP_1+4(r3)
|
stw r1, GP_1+4(r3)
|
||||||
stw r2, GP_2+4(r3)
|
stw r2, GP_2+4(r3)
|
||||||
#if (PPC_USE_MULTIPLE == 1)
|
#if (PPC_USE_MULTIPLE == 1)
|
||||||
addi r3, r3, GP_18+4
|
addi r3, r3, GP_18+4
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stmw r13, GP_13-GP_18(r3)
|
stmw r13, GP_13-GP_18(r3)
|
||||||
#else
|
#else
|
||||||
stw r13, GP_13+4(r3)
|
stw r13, GP_13+4(r3)
|
||||||
@@ -562,7 +607,9 @@ PROC (_CPU_Context_switch):
|
|||||||
stw r16, GP_16+4(r3)
|
stw r16, GP_16+4(r3)
|
||||||
stw r17, GP_17+4(r3)
|
stw r17, GP_17+4(r3)
|
||||||
stwu r18, GP_18+4(r3)
|
stwu r18, GP_18+4(r3)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbz r5, r3
|
dcbz r5, r3
|
||||||
|
#endif
|
||||||
stw r19, GP_19-GP_18(r3)
|
stw r19, GP_19-GP_18(r3)
|
||||||
stw r20, GP_20-GP_18(r3)
|
stw r20, GP_20-GP_18(r3)
|
||||||
stw r21, GP_21-GP_18(r3)
|
stw r21, GP_21-GP_18(r3)
|
||||||
@@ -577,7 +624,9 @@ PROC (_CPU_Context_switch):
|
|||||||
stw r30, GP_30-GP_18(r3)
|
stw r30, GP_30-GP_18(r3)
|
||||||
stw r31, GP_31-GP_18(r3)
|
stw r31, GP_31-GP_18(r3)
|
||||||
#endif
|
#endif
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r0, r4
|
dcbt r0, r4
|
||||||
|
#endif
|
||||||
mfcr r6
|
mfcr r6
|
||||||
stw r6, GP_CR-GP_18(r3)
|
stw r6, GP_CR-GP_18(r3)
|
||||||
mflr r7
|
mflr r7
|
||||||
@@ -585,12 +634,16 @@ PROC (_CPU_Context_switch):
|
|||||||
mfmsr r8
|
mfmsr r8
|
||||||
stw r8, GP_MSR-GP_18(r3)
|
stw r8, GP_MSR-GP_18(r3)
|
||||||
|
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lwz r1, GP_1(r4)
|
lwz r1, GP_1(r4)
|
||||||
lwz r2, GP_2(r4)
|
lwz r2, GP_2(r4)
|
||||||
#if (PPC_USE_MULTIPLE == 1)
|
#if (PPC_USE_MULTIPLE == 1)
|
||||||
addi r4, r4, GP_19
|
addi r4, r4, GP_19
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lmw r13, GP_13-GP_19(r4)
|
lmw r13, GP_13-GP_19(r4)
|
||||||
#else
|
#else
|
||||||
lwz r13, GP_13(r4)
|
lwz r13, GP_13(r4)
|
||||||
@@ -600,7 +653,9 @@ PROC (_CPU_Context_switch):
|
|||||||
lwz r17, GP_17(r4)
|
lwz r17, GP_17(r4)
|
||||||
lwz r18, GP_18(r4)
|
lwz r18, GP_18(r4)
|
||||||
lwzu r19, GP_19(r4)
|
lwzu r19, GP_19(r4)
|
||||||
|
#if ( PPC_USE_DATA_CACHE )
|
||||||
dcbt r5, r4
|
dcbt r5, r4
|
||||||
|
#endif
|
||||||
lwz r20, GP_20-GP_19(r4)
|
lwz r20, GP_20-GP_19(r4)
|
||||||
lwz r21, GP_21-GP_19(r4)
|
lwz r21, GP_21-GP_19(r4)
|
||||||
lwz r22, GP_22-GP_19(r4)
|
lwz r22, GP_22-GP_19(r4)
|
||||||
@@ -626,7 +681,7 @@ PROC (_CPU_Context_switch):
|
|||||||
/*
|
/*
|
||||||
* _CPU_Context_restore
|
* _CPU_Context_restore
|
||||||
*
|
*
|
||||||
* This routine is generally used only to restart self in an
|
* This routine is generallu used only to restart self in an
|
||||||
* efficient manner. It may simply be a label in _CPU_Context_switch.
|
* efficient manner. It may simply be a label in _CPU_Context_switch.
|
||||||
*
|
*
|
||||||
* NOTE: May be unnecessary to reload some registers.
|
* NOTE: May be unnecessary to reload some registers.
|
||||||
@@ -697,12 +752,15 @@ PROC (_CPU_Context_restore):
|
|||||||
PUBLIC_PROC (_ISR_Handler)
|
PUBLIC_PROC (_ISR_Handler)
|
||||||
PROC (_ISR_Handler):
|
PROC (_ISR_Handler):
|
||||||
#define LABEL(x) x
|
#define LABEL(x) x
|
||||||
|
/* XXX ??
|
||||||
#define MTSAVE(x) mtspr sprg0, x
|
#define MTSAVE(x) mtspr sprg0, x
|
||||||
#define MFSAVE(x) mfspr x, sprg0
|
#define MFSAVE(x) mfspr x, sprg0
|
||||||
|
*/
|
||||||
#define MTPC(x) mtspr srr0, x
|
#define MTPC(x) mtspr srr0, x
|
||||||
#define MFPC(x) mfspr x, srr0
|
#define MFPC(x) mfspr x, srr0
|
||||||
#define MTMSR(x) mtspr srr1, x
|
#define MTMSR(x) mtspr srr1, x
|
||||||
#define MFMSR(x) mfspr x, srr1
|
#define MFMSR(x) mfspr x, srr1
|
||||||
|
|
||||||
#include "irq_stub.s"
|
#include "irq_stub.s"
|
||||||
rfi
|
rfi
|
||||||
|
|
||||||
@@ -724,8 +782,10 @@ PROC (_ISR_HandlerC):
|
|||||||
#undef MTMSR
|
#undef MTMSR
|
||||||
#undef MFMSR
|
#undef MFMSR
|
||||||
#define LABEL(x) x##_C
|
#define LABEL(x) x##_C
|
||||||
|
/* XXX??
|
||||||
#define MTSAVE(x) mtspr sprg1, x
|
#define MTSAVE(x) mtspr sprg1, x
|
||||||
#define MFSAVE(x) mfspr x, sprg1
|
#define MFSAVE(x) mfspr x, sprg1
|
||||||
|
*/
|
||||||
#define MTPC(x) mtspr srr2, x
|
#define MTPC(x) mtspr srr2, x
|
||||||
#define MFPC(x) mfspr x, srr2
|
#define MFPC(x) mfspr x, srr2
|
||||||
#define MTMSR(x) mtspr srr3, x
|
#define MTMSR(x) mtspr srr3, x
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
/* irq_stub.s 1.1 - 95/12/04
|
/*
|
||||||
*
|
|
||||||
* This file contains the interrupt handler assembly code for the PowerPC
|
* This file contains the interrupt handler assembly code for the PowerPC
|
||||||
* implementation of RTEMS. It is #included from cpu_asm.s.
|
* implementation of RTEMS. It is #included from cpu_asm.s.
|
||||||
*
|
*
|
||||||
@@ -27,7 +26,9 @@
|
|||||||
* The vector number is in r0. R0 has already been stacked.
|
* The vector number is in r0. R0 has already been stacked.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* Finish off the interrupt frame */
|
PUBLIC_VAR (_CPU_IRQ_info )
|
||||||
|
|
||||||
|
/* Finish off the interrupt frame */
|
||||||
stw r2, IP_2(r1)
|
stw r2, IP_2(r1)
|
||||||
stw r3, IP_3(r1)
|
stw r3, IP_3(r1)
|
||||||
stw r4, IP_4(r1)
|
stw r4, IP_4(r1)
|
||||||
@@ -48,7 +49,12 @@
|
|||||||
MFPC (r9)
|
MFPC (r9)
|
||||||
MFMSR (r10)
|
MFMSR (r10)
|
||||||
/* Establish addressing */
|
/* Establish addressing */
|
||||||
mfspr r11, sprg3
|
#if (PPC_USE_SPRG)
|
||||||
|
mfspr r11, sprg3
|
||||||
|
#else
|
||||||
|
lis r11,_CPU_IRQ_info@ha
|
||||||
|
addi r11,r11,_CPU_IRQ_info@l
|
||||||
|
#endif
|
||||||
dcbt r0, r11
|
dcbt r0, r11
|
||||||
stw r5, IP_CR(r1)
|
stw r5, IP_CR(r1)
|
||||||
stw r6, IP_CTR(r1)
|
stw r6, IP_CTR(r1)
|
||||||
@@ -72,8 +78,16 @@
|
|||||||
* #endif
|
* #endif
|
||||||
*/
|
*/
|
||||||
/* Switch stacks, here we must prevent ALL interrupts */
|
/* Switch stacks, here we must prevent ALL interrupts */
|
||||||
mfmsr r5
|
#if (PPC_USE_SPRG)
|
||||||
mfspr r6, sprg2
|
mfmsr r5
|
||||||
|
mfspr r6, sprg2
|
||||||
|
#else
|
||||||
|
lwz r6,msr_initial(r11)
|
||||||
|
lis r5,~PPC_MSR_DISABLE_MASK@ha
|
||||||
|
ori r5,r5,~PPC_MSR_DISABLE_MASK@l
|
||||||
|
and r6,r6,r5
|
||||||
|
mfmsr r5
|
||||||
|
#endif
|
||||||
mtmsr r6
|
mtmsr r6
|
||||||
cmpwi r30, 0
|
cmpwi r30, 0
|
||||||
lwz r29, Disable_level(r11)
|
lwz r29, Disable_level(r11)
|
||||||
@@ -96,7 +110,14 @@ LABEL (nested):
|
|||||||
*/
|
*/
|
||||||
addi r31,r31,1
|
addi r31,r31,1
|
||||||
stw r31, 0(r29)
|
stw r31, 0(r29)
|
||||||
|
/* SCE 980217
|
||||||
|
*
|
||||||
|
* We need address translation ON when we call our ISR routine
|
||||||
|
|
||||||
mtmsr r5
|
mtmsr r5
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (*_ISR_Vector_table[ vector ])( vector );
|
* (*_ISR_Vector_table[ vector ])( vector );
|
||||||
*/
|
*/
|
||||||
@@ -109,14 +130,14 @@ LABEL (nested):
|
|||||||
#if (PPC_ABI == PPC_ABI_GCC27)
|
#if (PPC_ABI == PPC_ABI_GCC27)
|
||||||
lwz r2, Default_r2(r11)
|
lwz r2, Default_r2(r11)
|
||||||
mtlr r4
|
mtlr r4
|
||||||
lwz r2, 0(r2)
|
#lwz r2, 0(r2)
|
||||||
#endif
|
#endif
|
||||||
#if (PPC_ABI == PPC_ABI_SVR4 || PPC_ABI == PPC_ABI_EABI)
|
#if (PPC_ABI == PPC_ABI_SVR4 || PPC_ABI == PPC_ABI_EABI)
|
||||||
mtlr r4
|
mtlr r4
|
||||||
lwz r2, Default_r2(r11)
|
lwz r2, Default_r2(r11)
|
||||||
lwz r13, Default_r13(r11)
|
lwz r13, Default_r13(r11)
|
||||||
lwz r2, 0(r2)
|
#lwz r2, 0(r2)
|
||||||
lwz r13, 0(r13)
|
#lwz r13, 0(r13)
|
||||||
#endif
|
#endif
|
||||||
mr r4,r1
|
mr r4,r1
|
||||||
blrl
|
blrl
|
||||||
@@ -124,8 +145,17 @@ LABEL (nested):
|
|||||||
or r6,r6,r6
|
or r6,r6,r6
|
||||||
|
|
||||||
/* We must re-disable the interrupts */
|
/* We must re-disable the interrupts */
|
||||||
|
#if (PPC_USE_SPRG)
|
||||||
mfspr r11, sprg3
|
mfspr r11, sprg3
|
||||||
mfspr r0, sprg2
|
mfspr r0, sprg2
|
||||||
|
#else
|
||||||
|
lis r11,_CPU_IRQ_info@ha
|
||||||
|
addi r11,r11,_CPU_IRQ_info@l
|
||||||
|
lwz r0,msr_initial(r11)
|
||||||
|
lis r30,~PPC_MSR_DISABLE_MASK@ha
|
||||||
|
ori r30,r30,~PPC_MSR_DISABLE_MASK@l
|
||||||
|
and r0,r0,r30
|
||||||
|
#endif
|
||||||
mtmsr r0
|
mtmsr r0
|
||||||
lwz r30, 0(r28)
|
lwz r30, 0(r28)
|
||||||
lwz r31, 0(r29)
|
lwz r31, 0(r29)
|
||||||
@@ -191,8 +221,18 @@ LABEL (switch):
|
|||||||
* prepare to get out of interrupt
|
* prepare to get out of interrupt
|
||||||
*/
|
*/
|
||||||
/* Re-disable IRQs */
|
/* Re-disable IRQs */
|
||||||
|
#if (PPC_USE_SPRG)
|
||||||
mfspr r0, sprg2
|
mfspr r0, sprg2
|
||||||
|
#else
|
||||||
|
lis r11,_CPU_IRQ_info@ha
|
||||||
|
addi r11,r11,_CPU_IRQ_info@l
|
||||||
|
lwz r0,msr_initial(r11)
|
||||||
|
lis r5,~PPC_MSR_DISABLE_MASK@ha
|
||||||
|
ori r5,r5,~PPC_MSR_DISABLE_MASK@l
|
||||||
|
and r0,r0,r5
|
||||||
|
#endif
|
||||||
mtmsr r0
|
mtmsr r0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* easy_exit:
|
* easy_exit:
|
||||||
* prepare to get out of interrupt
|
* prepare to get out of interrupt
|
||||||
|
|||||||
@@ -20,11 +20,11 @@
|
|||||||
*
|
*
|
||||||
* Derived from c/src/exec/cpu/no_cpu/no_cpu.h:
|
* Derived from c/src/exec/cpu/no_cpu/no_cpu.h:
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 1989-1998.
|
* COPYRIGHT (c) 1989-1997.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may in
|
||||||
* found in the file LICENSE in this distribution or at
|
* the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _INCLUDE_PPC_h
|
#ifndef _INCLUDE_PPC_h
|
||||||
#define _INCLUDE_PPC_h
|
#define _INCLUDE_PPC_h
|
||||||
|
|
||||||
@@ -41,148 +42,140 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the name of the CPU family.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CPU_NAME "PowerPC"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file contains the information required to build
|
* This file contains the information required to build
|
||||||
* RTEMS for a particular member of the "no cpu"
|
* RTEMS for a particular member of the PowerPC family. It does
|
||||||
* family when executing in protected mode. It does
|
|
||||||
* this by setting variables to indicate which implementation
|
* this by setting variables to indicate which implementation
|
||||||
* dependent features are present in a particular member
|
* dependent features are present in a particular member
|
||||||
* of the family.
|
* of the family.
|
||||||
|
*
|
||||||
|
* The following architectural feature definitions are defaulted
|
||||||
|
* unless specifically set by the model definition:
|
||||||
|
*
|
||||||
|
* + PPC_DEBUG_MODEL - PPC_DEBUG_MODEL_STANDARD
|
||||||
|
* + PPC_INTERRUPT_MAX - 16
|
||||||
|
* + PPC_CACHE_ALIGNMENT - 32
|
||||||
|
* + PPC_LOW_POWER_MODE - PPC_LOW_POWER_MODE_NONE
|
||||||
|
* + PPC_HAS_EXCEPTION_PREFIX - 1
|
||||||
|
* + PPC_HAS_FPU - 1
|
||||||
|
* + PPC_HAS_DOUBLE - 1 if PPC_HAS_FPU,
|
||||||
|
* - 0 otherwise
|
||||||
|
* + PPC_USE_MULTIPLE - 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(ppc403)
|
/*
|
||||||
|
* Define the debugging assistance models found in the PPC family.
|
||||||
#define CPU_MODEL_NAME "PowerPC 403"
|
*
|
||||||
|
* Standard: single step and branch trace
|
||||||
|
* Single Step Only: single step only
|
||||||
|
* IBM 4xx: debug exception
|
||||||
|
*/
|
||||||
|
|
||||||
#define PPC_ALIGNMENT 4
|
#define PPC_DEBUG_MODEL_STANDARD 1
|
||||||
|
#define PPC_DEBUG_MODEL_SINGLE_STEP_ONLY 2
|
||||||
|
#define PPC_DEBUG_MODEL_IBM4xx 3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define the low power mode models
|
||||||
|
*
|
||||||
|
* Standard: as defined for 603e
|
||||||
|
* Nap Mode: nap mode only (604)
|
||||||
|
* XXX 403GB, 603, 603e, 604, 821
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PPC_LOW_POWER_MODE_NONE 0
|
||||||
|
#define PPC_LOW_POWER_MODE_STANDARD 1
|
||||||
|
|
||||||
|
#if defined(ppc403)
|
||||||
|
/*
|
||||||
|
* IBM 403
|
||||||
|
*
|
||||||
|
* Developed for 403GA. Book checked for 403GB.
|
||||||
|
*
|
||||||
|
* Does not have user mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CPU_MODEL_NAME "PowerPC 403"
|
||||||
|
#define PPC_ALIGNMENT 4
|
||||||
#define PPC_CACHE_ALIGNMENT 16
|
#define PPC_CACHE_ALIGNMENT 16
|
||||||
#define PPC_CACHE_ALIGN_POWER 4
|
#define PPC_HAS_RFCI 1
|
||||||
#define PPC_INTERRUPT_MAX 16
|
|
||||||
#define PPC_HAS_FPU 0
|
#define PPC_HAS_FPU 0
|
||||||
#define PPC_HAS_DOUBLE 0
|
|
||||||
#define PPC_HAS_RFCI 1
|
|
||||||
#define PPC_MSR_DISABLE_MASK 0x00029200
|
|
||||||
#define PPC_MSR_INITIAL 0x00000000
|
|
||||||
#define PPC_INIT_FPSCR 0x00000000
|
|
||||||
#define PPC_USE_MULTIPLE 1
|
#define PPC_USE_MULTIPLE 1
|
||||||
#define PPC_I_CACHE 2048
|
#define PPC_I_CACHE 2048
|
||||||
#define PPC_D_CACHE 1024
|
#define PPC_D_CACHE 1024
|
||||||
|
|
||||||
#define PPC_MSR_0 0x00029200
|
#define PPC_DEBUG_MODEL PPC_DEBUG_MODEL_IBM4xx
|
||||||
#define PPC_MSR_1 0x00021200
|
#define PPC_HAS_EXCEPTION_PREFIX 0
|
||||||
#define PPC_MSR_2 0x00021000
|
|
||||||
#define PPC_MSR_3 0x00000000
|
|
||||||
|
|
||||||
#elif defined(ppc601)
|
#elif defined(ppc601)
|
||||||
|
/*
|
||||||
|
* Submitted with original port -- book checked only.
|
||||||
|
*/
|
||||||
|
|
||||||
#define CPU_MODEL_NAME "PowerPC 601"
|
#define CPU_MODEL_NAME "PowerPC 601"
|
||||||
|
|
||||||
#define PPC_ALIGNMENT 8
|
#define PPC_ALIGNMENT 8
|
||||||
#define PPC_CACHE_ALIGNMENT 32
|
|
||||||
#define PPC_CACHE_ALIGN_POWER 5
|
|
||||||
#define PPC_INTERRUPT_MAX 16
|
|
||||||
#define PPC_HAS_FPU 1
|
|
||||||
#define PPC_HAS_DOUBLE 1
|
|
||||||
#define PPC_HAS_RFCI 0
|
|
||||||
#define PPC_MSR_DISABLE_MASK 0x00009900
|
|
||||||
#define PPC_MSR_INITIAL 0x00002000
|
|
||||||
#define PPC_INIT_FPSCR 0x000000f8
|
|
||||||
#define PPC_USE_MULTIPLE 1
|
#define PPC_USE_MULTIPLE 1
|
||||||
#define PPC_I_CACHE 0
|
#define PPC_I_CACHE 0
|
||||||
#define PPC_D_CACHE 32768
|
#define PPC_D_CACHE 32768
|
||||||
|
|
||||||
#define PPC_MSR_0 0x00009900
|
#define PPC_DEBUG_MODEL PPC_DEBUG_MODEL_SINGLE_STEP_ONLY
|
||||||
#define PPC_MSR_1 0x00001000
|
|
||||||
#define PPC_MSR_2 0x00001000
|
|
||||||
#define PPC_MSR_3 0x00000000
|
|
||||||
|
|
||||||
#elif defined(ppc602)
|
#elif defined(ppc602)
|
||||||
|
/*
|
||||||
|
* Submitted with original port -- book checked only.
|
||||||
|
*/
|
||||||
|
|
||||||
#define CPU_MODEL_NAME "PowerPC 602"
|
#define CPU_MODEL_NAME "PowerPC 602"
|
||||||
|
|
||||||
#define PPC_ALIGNMENT 4
|
#define PPC_ALIGNMENT 4
|
||||||
#define PPC_CACHE_ALIGNMENT 32
|
|
||||||
#define PPC_CACHE_ALIGN_POWER 5
|
|
||||||
#define PPC_INTERRUPT_MAX 16
|
|
||||||
#define PPC_HAS_FPU 1
|
|
||||||
#define PPC_HAS_DOUBLE 0
|
#define PPC_HAS_DOUBLE 0
|
||||||
#define PPC_HAS_RFCI 0
|
|
||||||
#define PPC_MSR_DISABLE_MASK
|
|
||||||
#define PPC_MSR_INITIAL
|
|
||||||
#define PPC_INIT_FPSCR
|
|
||||||
#define PPC_USE_MULTIPLE 0
|
|
||||||
#define PPC_I_CACHE 4096
|
#define PPC_I_CACHE 4096
|
||||||
#define PPC_D_CACHE 4096
|
#define PPC_D_CACHE 4096
|
||||||
|
|
||||||
#elif defined(ppc603)
|
#elif defined(ppc603)
|
||||||
|
/*
|
||||||
|
* Submitted with original port -- book checked only.
|
||||||
|
*/
|
||||||
|
|
||||||
#define CPU_MODEL_NAME "PowerPC 603"
|
#define CPU_MODEL_NAME "PowerPC 603"
|
||||||
|
|
||||||
#define PPC_ALIGNMENT 8
|
#define PPC_ALIGNMENT 8
|
||||||
#define PPC_CACHE_ALIGNMENT 32
|
|
||||||
#define PPC_CACHE_ALIGN_POWER 5
|
|
||||||
#define PPC_INTERRUPT_MAX 16
|
|
||||||
#define PPC_HAS_FPU 1
|
|
||||||
#define PPC_HAS_DOUBLE 1
|
|
||||||
#define PPC_HAS_RFCI 0
|
|
||||||
#define PPC_MSR_DISABLE_MASK 0x00009900
|
|
||||||
#define PPC_MSR_INITIAL 0x00002000
|
|
||||||
#define PPC_INIT_FPSCR 0x000000f8
|
|
||||||
#define PPC_USE_MULTIPLE 0
|
|
||||||
#define PPC_I_CACHE 8192
|
#define PPC_I_CACHE 8192
|
||||||
#define PPC_D_CACHE 8192
|
#define PPC_D_CACHE 8192
|
||||||
|
|
||||||
#define PPC_MSR_0 0x00009900
|
|
||||||
#define PPC_MSR_1 0x00001000
|
|
||||||
#define PPC_MSR_2 0x00001000
|
|
||||||
#define PPC_MSR_3 0x00000000
|
|
||||||
|
|
||||||
#elif defined(ppc603e)
|
#elif defined(ppc603e)
|
||||||
|
|
||||||
#define CPU_MODEL_NAME "PowerPC 603e"
|
#define CPU_MODEL_NAME "PowerPC 603e"
|
||||||
|
/*
|
||||||
|
* Submitted with original port.
|
||||||
|
*
|
||||||
|
* Known to work on real hardware.
|
||||||
|
*/
|
||||||
|
|
||||||
#define PPC_ALIGNMENT 8
|
#define PPC_ALIGNMENT 8
|
||||||
#define PPC_CACHE_ALIGNMENT 32
|
|
||||||
#define PPC_CACHE_ALIGN_POWER 5
|
|
||||||
#define PPC_INTERRUPT_MAX 16
|
|
||||||
#define PPC_HAS_FPU 1
|
|
||||||
#define PPC_HAS_DOUBLE 1
|
|
||||||
#define PPC_HAS_RFCI 0
|
|
||||||
#define PPC_MSR_DISABLE_MASK 0x00009900
|
|
||||||
#define PPC_MSR_INITIAL 0x00002000
|
|
||||||
#define PPC_INIT_FPSCR 0x000000f8
|
|
||||||
#define PPC_USE_MULTIPLE 0
|
|
||||||
#define PPC_I_CACHE 16384
|
#define PPC_I_CACHE 16384
|
||||||
#define PPC_D_CACHE 16384
|
#define PPC_D_CACHE 16384
|
||||||
|
|
||||||
#define PPC_MSR_0 0x00009900
|
#define PPC_LOW_POWER_MODE PPC_LOW_POWER_MODE_STANDARD
|
||||||
#define PPC_MSR_1 0x00001000
|
|
||||||
#define PPC_MSR_2 0x00001000
|
|
||||||
#define PPC_MSR_3 0x00000000
|
|
||||||
|
|
||||||
#elif defined(ppc604)
|
#elif defined(ppc604)
|
||||||
|
/*
|
||||||
|
* Submitted with original port -- book checked only.
|
||||||
|
*/
|
||||||
|
|
||||||
#define CPU_MODEL_NAME "PowerPC 604"
|
#define CPU_MODEL_NAME "PowerPC 604"
|
||||||
|
|
||||||
#define PPC_ALIGNMENT 8
|
#define PPC_ALIGNMENT 8
|
||||||
#define PPC_CACHE_ALIGNMENT 32
|
|
||||||
#define PPC_CACHE_ALIGN_POWER 5
|
|
||||||
#define PPC_INTERRUPT_MAX 16
|
|
||||||
#define PPC_HAS_FPU 1
|
|
||||||
#define PPC_HAS_DOUBLE 1
|
|
||||||
#define PPC_HAS_RFCI 0
|
|
||||||
#define PPC_MSR_DISABLE_MASK 0x00009900
|
|
||||||
#define PPC_MSR_INITIAL 0x00002000
|
|
||||||
#define PPC_INIT_FPSCR 0x000000f8
|
|
||||||
#define PPC_USE_MULTIPLE 0
|
|
||||||
#define PPC_I_CACHE 16384
|
#define PPC_I_CACHE 16384
|
||||||
#define PPC_D_CACHE 16384
|
#define PPC_D_CACHE 16384
|
||||||
|
|
||||||
#define PPC_MSR_0 0x00009900
|
|
||||||
#define PPC_MSR_1 0x00001000
|
|
||||||
#define PPC_MSR_2 0x00001000
|
|
||||||
#define PPC_MSR_3 0x00000000
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#error "Unsupported CPU Model"
|
#error "Unsupported CPU Model"
|
||||||
@@ -191,6 +184,7 @@ extern "C" {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Application binary interfaces.
|
* Application binary interfaces.
|
||||||
|
*
|
||||||
* PPC_ABI MUST be defined as one of these.
|
* PPC_ABI MUST be defined as one of these.
|
||||||
* Only PPC_ABI_POWEROPEN is currently fully supported.
|
* Only PPC_ABI_POWEROPEN is currently fully supported.
|
||||||
* Only EABI will be supported in the end when
|
* Only EABI will be supported in the end when
|
||||||
@@ -237,48 +231,110 @@ extern "C" {
|
|||||||
/*
|
/*
|
||||||
* Assemblers.
|
* Assemblers.
|
||||||
* PPC_ASM MUST be defined as one of these.
|
* PPC_ASM MUST be defined as one of these.
|
||||||
* Only PPC_ABI_ELF is currently fully supported.
|
*
|
||||||
*/
|
* PPC_ASM_ELF: ELF assembler. Currently used for all ABIs.
|
||||||
/*
|
* PPC_ASM_XCOFF: XCOFF assembler. May be needed for PowerOpen ABI.
|
||||||
* ELF assembler. Currently used for all ABIs.
|
*
|
||||||
*/
|
* NOTE: Only PPC_ABI_ELF is currently fully supported.
|
||||||
#define PPC_ASM_ELF 0
|
|
||||||
/*
|
|
||||||
* XCOFF assembler, may be needed for PowerOpen ABI.
|
|
||||||
*/
|
|
||||||
#define PPC_ASM_XCOFF 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Define the name of the CPU family.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CPU_NAME "PowerPC"
|
#define PPC_ASM_ELF 0
|
||||||
|
#define PPC_ASM_XCOFF 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupt vectors.
|
* Use the default debug scheme defined in the architectural specification
|
||||||
|
* if another model has not been specified.
|
||||||
*/
|
*/
|
||||||
/* Machine check */
|
|
||||||
#define PPC_IRQ_MCHECK 0
|
#ifndef PPC_DEBUG_MODEL
|
||||||
/* Protection violation */
|
#define PPC_DEBUG_MODEL PPC_DEBUG_MODEL_STANDARD
|
||||||
#define PPC_IRQ_PROTECT 1
|
#endif
|
||||||
/* External interrupt */
|
|
||||||
#define PPC_IRQ_EXTERNAL 2
|
/*
|
||||||
/* Program exception */
|
* If the maximum number of exception sources has not been defined,
|
||||||
#define PPC_IRQ_PROGRAM 3
|
* then default it to 16.
|
||||||
/* System call */
|
*/
|
||||||
#define PPC_IRQ_SCALL 4
|
|
||||||
/* Floating point unavailable */
|
#ifndef PPC_INTERRUPT_MAX
|
||||||
#define PPC_IRQ_NOFP 5
|
#define PPC_INTERRUPT_MAX 16
|
||||||
/* Program interval timer */
|
#endif
|
||||||
#define PPC_IRQ_PIT 6
|
|
||||||
/* Fixed interval timer */
|
/*
|
||||||
#define PPC_IRQ_FIT 7
|
* Unless specified otherwise, the cache line size is defaulted to 32.
|
||||||
/* Critical interrupt pin */
|
*
|
||||||
#define PPC_IRQ_CRIT 8
|
* The derive the power of 2 the cache line is.
|
||||||
/* Watchdog timer */
|
*/
|
||||||
#define PPC_IRQ_WATCHDOG 9
|
|
||||||
/* Debug exceptions */
|
#ifndef PPC_CACHE_ALIGNMENT
|
||||||
#define PPC_IRQ_DEBUG 10
|
#define PPC_CACHE_ALIGNMENT 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PPC_CACHE_ALIGNMENT == 16)
|
||||||
|
#define PPC_CACHE_ALIGN_POWER 4
|
||||||
|
#elif (PPC_CACHE_ALIGNMENT == 32)
|
||||||
|
#define PPC_CACHE_ALIGN_POWER 5
|
||||||
|
#else
|
||||||
|
#error "Undefined power of 2 for PPC_CACHE_ALIGNMENT"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unless otherwise specified, assume the model has an IP/EP bit to
|
||||||
|
* set the exception address prefix.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PPC_HAS_EXCEPTION_PREFIX
|
||||||
|
#define PPC_HAS_EXCEPTION_PREFIX 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If no low power mode model was specified, then assume there is none.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PPC_LOW_POWER_MODE
|
||||||
|
#define PPC_LOW_POWER_MODE PPC_LOW_POWER_MODE_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unless specified above, then assume the model has FP support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PPC_HAS_FPU
|
||||||
|
#define PPC_HAS_FPU 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unless specified above, If the model has FP support, it is assumed to
|
||||||
|
* support doubles (8-byte floating point numbers).
|
||||||
|
*
|
||||||
|
* If the model does NOT have FP support, then the model does
|
||||||
|
* NOT have double length FP registers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PPC_HAS_DOUBLE
|
||||||
|
#if (PPC_HAS_FPU)
|
||||||
|
#define PPC_HAS_DOUBLE 1
|
||||||
|
#else
|
||||||
|
#define PPC_HAS_DOUBLE 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unless specified above, then assume the model does NOT have critical
|
||||||
|
* interrupt support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PPC_HAS_RFCI
|
||||||
|
#define PPC_HAS_RFCI 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unless specified above, do not use the load/store multiple instructions
|
||||||
|
* in a context switch.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PPC_USE_MULTIPLE
|
||||||
|
#define PPC_USE_MULTIPLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following exceptions are not maskable, and are not
|
* The following exceptions are not maskable, and are not
|
||||||
@@ -288,9 +344,141 @@ extern "C" {
|
|||||||
* Instruction exceptions.
|
* Instruction exceptions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Base Interrupt vectors supported on all models.
|
||||||
|
*/
|
||||||
|
#define PPC_IRQ_SYSTEM_RESET 0 /* 0x00100 - System reset. */
|
||||||
|
#define PPC_IRQ_MCHECK 1 /* 0x00200 - Machine check */
|
||||||
|
#define PPC_IRQ_PROTECT 2 /* 0x00300 - Protection violation */
|
||||||
|
#define PPC_IRQ_ISI 3 /* 0x00400 - Instruction Fetch error */
|
||||||
|
#define PPC_IRQ_EXTERNAL 4 /* 0x00500 - External interrupt */
|
||||||
|
#define PPC_IRQ_ALIGNMENT 5 /* 0X00600 - Alignment exception */
|
||||||
|
#define PPC_IRQ_PROGRAM 6 /* 0x00700 - Program exception */
|
||||||
|
#define PPC_IRQ_NOFP 7 /* 0x00800 - Floating point unavailable */
|
||||||
|
#define PPC_IRQ_DECREMENTER 8 /* 0x00900 - Decrementer interrupt */
|
||||||
|
#define PPC_IRQ_RESERVED_A 9 /* 0x00a00 - Implementation Reserved */
|
||||||
|
#define PPC_IRQ_RESERVED_B 10 /* 0x00a00 - Implementation Reserved */
|
||||||
|
#define PPC_IRQ_SCALL 11 /* 0x00c00 - System call */
|
||||||
|
#define PPC_IRQ_TRACE 12 /* 0x00d00 - Trace Exception */
|
||||||
|
#define PPC_IRQ_FP_ASST 13 /* ox00e00 - Floating point assist */
|
||||||
|
#define PPC_STD_IRQ_LAST PPC_IRQ_FP_ASST
|
||||||
|
|
||||||
|
#define PPC_IRQ_FIRST PPC_IRQ_SYSTEM_RESET
|
||||||
|
|
||||||
|
#if defined(ppc403)
|
||||||
|
|
||||||
|
#define PPC_IRQ_CRIT PPC_IRQ_SYSTEM_RESET /*0x00100- Critical int. pin */
|
||||||
|
#define PPC_IRQ_PIT (PPC_STD_IRQ_LAST+1) /*0x01000- Pgm interval timer*/
|
||||||
|
#define PPC_IRQ_FIT (PPC_STD_IRQ_LAST+2) /*0x01010- Fixed int. timer */
|
||||||
|
#define PPC_IRQ_WATCHDOG (PPC_STD_IRQ_LAST+3) /*0x01020- Watchdog timer */
|
||||||
|
#define PPC_IRQ_DEBUG (PPC_STD_IRQ_LAST+4) /*0x02000- Debug exceptions */
|
||||||
|
#define PPC_IRQ_LAST PPC_IRQ_DEBUG
|
||||||
|
|
||||||
|
#elif defined(ppc601)
|
||||||
|
#define PPC_IRQ_TRACE (PPC_STD_IRQ_LAST+1) /*0x02000-Run/Trace Exception*/
|
||||||
|
#define PPC_IRQ_LAST PPC_IRQ_TRACE
|
||||||
|
|
||||||
|
#elif defined(ppc602)
|
||||||
|
#define PPC_IRQ_LAST (PPC_STD_IRQ_LAST)
|
||||||
|
|
||||||
|
#elif defined(ppc603)
|
||||||
|
#define PPC_IRQ_TRANS_MISS (PPC_STD_IRQ_LAST+1) /*0x1000-Ins Translation Miss*/
|
||||||
|
#define PPC_IRQ_DATA_LOAD (PPC_STD_IRQ_LAST+2) /*0x1100-Data Load Trans Miss*/
|
||||||
|
#define PPC_IRQ_DATA_STORE (PPC_STD_IRQ_LAST+3) /*0x1200-Data Store Miss */
|
||||||
|
#define PPC_IRQ_ADDR_BRK (PPC_STD_IRQ_LAST+4) /*0x1300-Instruction Bkpoint */
|
||||||
|
#define PPC_IRQ_SYS_MGT (PPC_STD_IRQ_LAST+5) /*0x1400-System Management */
|
||||||
|
#define PPC_IRQ_LAST PPC_IRQ_SYS_MGT
|
||||||
|
|
||||||
|
#elif defined(ppc603e)
|
||||||
|
#define PPC_TLB_INST_MISS (PPC_STD_IRQ_LAST+1) /*0x1000-Instruction TLB Miss*/
|
||||||
|
#define PPC_TLB_LOAD_MISS (PPC_STD_IRQ_LAST+2) /*0x1100-TLB miss on load */
|
||||||
|
#define PPC_TLB_STORE_MISS (PPC_STD_IRQ_LAST+3) /*0x1200-TLB Miss on store */
|
||||||
|
#define PPC_IRQ_ADDRBRK (PPC_STD_IRQ_LAST+4) /*0x1300-Instruct addr break */
|
||||||
|
#define PPC_IRQ_SYS_MGT (PPC_STD_IRQ_LAST+5) /*0x1400-System Management */
|
||||||
|
#define PPC_IRQ_LAST PPC_IRQ_SYS_MGT
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined(ppc604)
|
||||||
|
#define PPC_IRQ_ADDR_BRK (PPC_STD_IRQ_LAST+1) /*0x1300- Inst. addr break */
|
||||||
|
#define PPC_IRQ_SYS_MGT (PPC_STD_IRQ_LAST+2) /*0x1400- System Management */
|
||||||
|
#define PPC_IRQ_LAST PPC604_IRQ_SYS_MGT
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine Status Register (MSR) Constants Used by RTEMS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some PPC model manuals refer to the Exception Prefix (EP) bit as
|
||||||
|
* IP for no apparent reason.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PPC_MSR_RI 0x000000002 /* bit 30 - recoverable exception */
|
||||||
|
#define PPC_MSR_DR 0x000000010 /* bit 27 - data address translation */
|
||||||
|
#define PPC_MSR_IR 0x000000020 /* bit 26 - instruction addr translation*/
|
||||||
|
|
||||||
|
#if (PPC_HAS_EXCEPTION_PREFIX)
|
||||||
|
#define PPC_MSR_EP 0x000000040 /* bit 25 - exception prefix */
|
||||||
|
#else
|
||||||
|
#define PPC_MSR_EP 0x000000000 /* bit 25 - exception prefix */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PPC_HAS_FPU)
|
||||||
|
#define PPC_MSR_FP 0x000002000 /* bit 18 - floating point enable */
|
||||||
|
#else
|
||||||
|
#define PPC_MSR_FP 0x000000000 /* bit 18 - floating point enable */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PPC_LOW_POWER_MODE == PPC_LOW_POWER_MODE_NONE)
|
||||||
|
#define PPC_MSR_POW 0x000000000 /* bit 13 - power management enable */
|
||||||
|
#else
|
||||||
|
#define PPC_MSR_POW 0x000040000 /* bit 13 - power management enable */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt/exception MSR bits set as defined on p. 2-20 in "The Programming
|
||||||
|
* Environments" and the manuals for various PPC models.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (PPC_DEBUG_MODEL == PPC_DEBUG_MODEL_STANDARD)
|
||||||
|
#define PPC_MSR_DE 0x000000000 /* bit 22 - debug exception enable */
|
||||||
|
#define PPC_MSR_BE 0x000000200 /* bit 22 - branch trace enable */
|
||||||
|
#define PPC_MSR_SE 0x000000400 /* bit 21 - single step trace enable */
|
||||||
|
#elif (PPC_DEBUG_MODEL == PPC_DEBUG_MODEL_SINGLE_STEP_ONLY)
|
||||||
|
#define PPC_MSR_DE 0x000000000 /* bit 22 - debug exception enable */
|
||||||
|
#define PPC_MSR_BE 0x000000200 /* bit 22 - branch trace enable */
|
||||||
|
#define PPC_MSR_SE 0x000000000 /* bit 21 - single step trace enable */
|
||||||
|
#elif (PPC_DEBUG_MODEL == PPC_DEBUG_MODEL_IBM4xx)
|
||||||
|
#define PPC_MSR_DE 0x000000200 /* bit 22 - debug exception enable */
|
||||||
|
#define PPC_MSR_BE 0x000000000 /* bit 22 - branch trace enable */
|
||||||
|
#define PPC_MSR_SE 0x000000000 /* bit 21 - single step trace enable */
|
||||||
|
#else
|
||||||
|
#error "MSR constants -- unknown PPC_DEBUG_MODEL!!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PPC_MSR_ME 0x000001000 /* bit 19 - machine check enable */
|
||||||
|
#define PPC_MSR_EE 0x000008000 /* bit 16 - external interrupt enable */
|
||||||
|
|
||||||
|
#if (PPC_HAS_RFCI)
|
||||||
|
#define PPC_MSR_CE 0x000020000 /* bit 14 - critical interrupt enable */
|
||||||
|
#else
|
||||||
|
#define PPC_MSR_CE 0x000000000 /* bit 14 - critical interrupt enable */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PPC_MSR_DISABLE_MASK (PPC_MSR_ME|PPC_MSR_EE|PPC_MSR_CE)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initial value for the FPSCR register
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PPC_INIT_FPSCR 0x000000f8
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ! _INCLUDE_PPC_h */
|
#endif /* ! _INCLUDE_PPC_h */
|
||||||
/* end of include file */
|
/* end of include file */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,12 +20,12 @@
|
|||||||
*
|
*
|
||||||
* Derived from c/src/exec/cpu/no_cpu/no_cputypes.h:
|
* Derived from c/src/exec/cpu/no_cpu/no_cputypes.h:
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 1989-1998.
|
* COPYRIGHT (c) 1989-1997.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
* Copyright assigned to U.S. Government, 1994.
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may in
|
||||||
* found in the file LICENSE in this distribution or at
|
* the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
|
|||||||
@@ -20,12 +20,12 @@
|
|||||||
*
|
*
|
||||||
* Derived from c/src/exec/cpu/no_cpu/rtems.c:
|
* Derived from c/src/exec/cpu/no_cpu/rtems.c:
|
||||||
*
|
*
|
||||||
* COPYRIGHT (c) 1989-1998.
|
* COPYRIGHT (c) 1989-1997.
|
||||||
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
||||||
* Copyright assigned to U.S. Government, 1994.
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
*
|
*
|
||||||
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may in
|
||||||
* found in the file LICENSE in this distribution or at
|
* the file LICENSE in this distribution or at
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
|
|||||||
Reference in New Issue
Block a user