mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +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
|
||||
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.
|
||||
|
||||
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
|
||||
point).
|
||||
This port was originally written and tested on the PPC403GA (using
|
||||
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,
|
||||
this release contains code to support the following processors
|
||||
PPC601, PPC603, PPC603e, PPC604, and PPC602.
|
||||
Andrew Bray received assistance during the initial porting effort
|
||||
from IBM and Blue Micro and we would like to gratefully acknowledge
|
||||
that help.
|
||||
|
||||
The support for these processors is incomplete, especially that for
|
||||
the PPC602 for which only sketchy data is currently available.
|
||||
The support for the PPC602 processor is incomplete as only sketchy
|
||||
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.
|
||||
|
||||
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
|
||||
on the assembler files to get them through a traditional (XCOFF) PowerOpen
|
||||
assembler.
|
||||
caveat: we used an ELF assembler and linker. So some attention may be
|
||||
required on the assembler files to get them through a traditional (XCOFF)
|
||||
PowerOpen assembler.
|
||||
|
||||
This port contains support for the other ABIs, but this may prove to be incomplete
|
||||
as it is untested.
|
||||
This port contains support for the other ABIs, but this may prove to be
|
||||
incomplete as it is untested.
|
||||
|
||||
In the long term, the RTEMS PowerPC port should move to the EABI as its primary
|
||||
or only port. This should wait on a true EABI version of GCC.
|
||||
The RTEMS PowerPC port supports EABI as the primary ABI. The powerpc-rtems
|
||||
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:
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* COPYRIGHT (c) 1989-1997.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* The license and distribution terms for this file may be found in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
@@ -37,24 +37,6 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
@@ -75,9 +57,9 @@ void _CPU_Initialize(
|
||||
proc_ptr handler = (proc_ptr)ppc_spurious;
|
||||
int i;
|
||||
#if (PPC_ABI != PPC_ABI_POWEROPEN)
|
||||
register unsigned32 r2;
|
||||
register unsigned32 r2 = 0;
|
||||
#if (PPC_ABI != PPC_ABI_GCC27)
|
||||
register unsigned32 r13;
|
||||
register unsigned32 r13 = 0;
|
||||
|
||||
asm ("mr %0,13" : "=r" ((r13)) : "0" ((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.Signal = &_ISR_Signals_to_thread_executing;
|
||||
|
||||
#if (PPC_USE_SPRG)
|
||||
i = (int)&_CPU_IRQ_info;
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
if ( cpu_table->spurious_handler )
|
||||
@@ -129,38 +104,180 @@ void _CPU_Initialize(
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Get_level
|
||||
*
|
||||
* COMMENTS FROM Andrew Bray <andy@i-cubed.co.uk>:
|
||||
* _CPU_ISR_Calculate_level
|
||||
*
|
||||
* The PowerPC puts its interrupt enable status in the MSR register
|
||||
* which also contains things like endianness control. To be more
|
||||
* awkward, the layout varies from processor to processor. This
|
||||
* is why I adopted a table approach in my interrupt handling.
|
||||
* Thus the inverse process is slow, because it requires a table
|
||||
* 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.
|
||||
*
|
||||
* is why it was necessary to adopt a scheme which allowed the user
|
||||
* to specify specifically which interrupt sources were enabled.
|
||||
*/
|
||||
|
||||
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 level, msr;
|
||||
unsigned32 level = 0;
|
||||
unsigned32 msr;
|
||||
|
||||
asm volatile("mfmsr %0" : "=r" ((msr)));
|
||||
|
||||
msr &= PPC_MSR_DISABLE_MASK;
|
||||
|
||||
for (level = 0; level < 4; level++)
|
||||
if ((_CPU_msrs[level] & PPC_MSR_DISABLE_MASK) == msr)
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
* Set the critical interrupt enable bit
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
/*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
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
@@ -181,6 +298,7 @@ void _CPU_ISR_install_vector(
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
proc_ptr ignored;
|
||||
*old_handler = _ISR_Vector_table[ vector ];
|
||||
|
||||
/*
|
||||
@@ -189,6 +307,12 @@ void _CPU_ISR_install_vector(
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
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 ("tweq 5,5");
|
||||
asm volatile ("li 0,0; mtmsr 0");
|
||||
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:
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* COPYRIGHT (c) 1989-1997.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
@@ -285,7 +285,7 @@ struct CPU_Interrupt_frame;
|
||||
*/
|
||||
|
||||
#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
|
||||
@@ -300,16 +300,27 @@ struct CPU_Interrupt_frame;
|
||||
* The following defines the number of bits actually used in 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().
|
||||
*/
|
||||
/*
|
||||
* ACB Note: Levels are:
|
||||
* 0: All maskable interrupts enabled
|
||||
* 1: Other critical exceptions enabled
|
||||
* 2: Machine check enabled
|
||||
* 3: All maskable IRQs disabled
|
||||
*
|
||||
* The interrupt level is bit mapped for the PowerPC family. The
|
||||
* bits are set to 0 to indicate that a particular exception source
|
||||
* enabled and 1 if it is disabled. This keeps with RTEMS convention
|
||||
* that interrupt level 0 means all sources are enabled.
|
||||
*
|
||||
* 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
|
||||
@@ -450,17 +461,37 @@ typedef struct {
|
||||
void (*stack_free_hook)( void* );
|
||||
/* end of fields required on all CPUs */
|
||||
|
||||
unsigned32 clicks_per_usec; /* Timer clicks per microsecond */
|
||||
unsigned32 serial_per_sec; /* Serial clocks per second */
|
||||
unsigned32 clicks_per_usec; /* Timer clicks per microsecond */
|
||||
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_xon_xoff;
|
||||
boolean serial_cts_rts;
|
||||
unsigned32 serial_rate;
|
||||
unsigned32 timer_average_overhead; /* Average overhead of timer in ticks */
|
||||
unsigned32 timer_least_valid; /* Least valid number from timer */
|
||||
void (*spurious_handler)(unsigned32 vector, CPU_Interrupt_frame *);
|
||||
unsigned32 timer_least_valid; /* Least valid number from timer */
|
||||
#endif
|
||||
} 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
SCORE_EXTERN struct {
|
||||
unsigned32 *Nest_level;
|
||||
unsigned32 *Disable_level;
|
||||
@@ -517,6 +549,8 @@ SCORE_EXTERN struct {
|
||||
#endif
|
||||
volatile boolean *Switch_necessary;
|
||||
boolean *Signal;
|
||||
|
||||
unsigned32 msr_initial;
|
||||
} _CPU_IRQ_info CPU_STRUCTURE_ALIGNMENT;
|
||||
|
||||
/*
|
||||
@@ -549,8 +583,8 @@ SCORE_EXTERN struct {
|
||||
* by RTEMS.
|
||||
*/
|
||||
|
||||
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)
|
||||
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
|
||||
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (PPC_INTERRUPT_MAX)
|
||||
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (PPC_INTERRUPT_MAX - 1)
|
||||
|
||||
/*
|
||||
* 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
|
||||
* level is returned in _level.
|
||||
* level is returned in _isr_cookie.
|
||||
*/
|
||||
|
||||
#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 ) \
|
||||
{ \
|
||||
{ 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 ( \
|
||||
"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).
|
||||
* 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 ) \
|
||||
{ \
|
||||
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
|
||||
* sections into two or more parts. The parameter _level is not
|
||||
* modified.
|
||||
* sections into two or more parts. The parameter _isr_cookie is not
|
||||
* 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 ) \
|
||||
{ \
|
||||
{ register unsigned int _disable_mask = PPC_MSR_DISABLE_MASK; \
|
||||
asm volatile ( \
|
||||
"mtmsr %0; andc %1,%0,%1; mtmsr %1" : \
|
||||
"=r" ((_isr_cookie)) : \
|
||||
"r" ((PPC_MSR_DISABLE_MASK)), "0" ((_isr_cookie)) \
|
||||
); \
|
||||
"mtmsr %0; andc %1,%0,%1; mtmsr %1" : \
|
||||
"=r" ((_isr_cookie)), "=r" ((_disable_mask)) : \
|
||||
"0" ((_isr_cookie)), "1" ((_disable_mask)) \
|
||||
); \
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -661,20 +744,53 @@ SCORE_EXTERN struct {
|
||||
* via the rtems_task_mode directive.
|
||||
*/
|
||||
|
||||
#define _CPU_ISR_Set_level( 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)) \
|
||||
); \
|
||||
}
|
||||
unsigned32 _CPU_ISR_Calculate_level(
|
||||
unsigned32 new_level
|
||||
);
|
||||
|
||||
void _CPU_ISR_Set_level(
|
||||
unsigned32 new_level
|
||||
);
|
||||
|
||||
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 */
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
/*
|
||||
@@ -691,63 +807,18 @@ unsigned32 _CPU_ISR_Get_level( void );
|
||||
* This routine generally does not set any unnecessary register
|
||||
* in the context. The state of the "general data" registers is
|
||||
* undefined at task start time.
|
||||
*
|
||||
* NOTE: Implemented as a subroutine for the SPARC port.
|
||||
*/
|
||||
|
||||
#if PPC_ABI == PPC_ABI_POWEROPEN
|
||||
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
|
||||
_isr, _entry_point, _is_fp ) \
|
||||
{ \
|
||||
unsigned32 sp, *desc; \
|
||||
\
|
||||
sp = ((unsigned32)_stack_base) + (_size) - 56; \
|
||||
*((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
|
||||
void _CPU_Context_Initialize(
|
||||
Context_Control *the_context,
|
||||
unsigned32 *stack_base,
|
||||
unsigned32 size,
|
||||
unsigned32 new_level,
|
||||
void *entry_point,
|
||||
boolean is_fp
|
||||
);
|
||||
|
||||
/*
|
||||
* This routine is responsible for somehow restarting the currently
|
||||
@@ -911,7 +982,7 @@ extern const unsigned32 _CPU_msrs[4];
|
||||
|
||||
void _CPU_Initialize(
|
||||
rtems_cpu_table *cpu_table,
|
||||
void (*thread_dispatch)
|
||||
void (*thread_dispatch)
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -951,7 +1022,7 @@ void _CPU_Context_switch(
|
||||
/*
|
||||
* _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.
|
||||
*
|
||||
* NOTE: May be unnecessary to reload some registers.
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
*
|
||||
* 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).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
@@ -174,6 +174,7 @@
|
||||
.set IP_END, (IP_MSR + 16)
|
||||
|
||||
/* _CPU_IRQ_info offsets */
|
||||
|
||||
/* These must be in this order */
|
||||
.set Nest_level, 0
|
||||
.set Disable_level, 4
|
||||
@@ -192,7 +193,8 @@
|
||||
#endif
|
||||
#endif
|
||||
.set Signal, Switch_necessary + 4
|
||||
|
||||
.set msr_initial, Signal + 4
|
||||
|
||||
BEGIN_CODE
|
||||
/*
|
||||
* _CPU_Context_save_fp_context
|
||||
@@ -453,45 +455,66 @@ PROC (_CPU_Context_switch):
|
||||
/* This assumes that all the registers are in the given order */
|
||||
li r5, 16
|
||||
addi r3,r3,-4
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stw r1, GP_1+4(r3)
|
||||
stw r2, GP_2+4(r3)
|
||||
#if (PPC_USE_MULTIPLE == 1)
|
||||
addi r3, r3, GP_14+4
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
|
||||
addi r3, r3, GP_18-GP_14
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
addi r3, r3, GP_22-GP_18
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
addi r3, r3, GP_26-GP_22
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stmw r13, GP_13-GP_26(r3)
|
||||
#else
|
||||
stw r13, GP_13+4(r3)
|
||||
stwu r14, GP_14+4(r3)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stw r15, GP_15-GP_14(r3)
|
||||
stw r16, GP_16-GP_14(r3)
|
||||
stw r17, GP_17-GP_14(r3)
|
||||
stwu r18, GP_18-GP_14(r3)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stw r19, GP_19-GP_18(r3)
|
||||
stw r20, GP_20-GP_18(r3)
|
||||
stw r21, GP_21-GP_18(r3)
|
||||
stwu r22, GP_22-GP_18(r3)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stw r23, GP_23-GP_22(r3)
|
||||
stw r24, GP_24-GP_22(r3)
|
||||
stw r25, GP_25-GP_22(r3)
|
||||
stwu r26, GP_26-GP_22(r3)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stw r27, GP_27-GP_26(r3)
|
||||
stw r28, GP_28-GP_26(r3)
|
||||
stw r29, GP_29-GP_26(r3)
|
||||
stw r30, GP_30-GP_26(r3)
|
||||
stw r31, GP_31-GP_26(r3)
|
||||
#endif
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r0, r4
|
||||
#endif
|
||||
mfcr r6
|
||||
stw r6, GP_CR-GP_26(r3)
|
||||
mflr r7
|
||||
@@ -499,39 +522,57 @@ PROC (_CPU_Context_switch):
|
||||
mfmsr r8
|
||||
stw r8, GP_MSR-GP_26(r3)
|
||||
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lwz r1, GP_1(r4)
|
||||
lwz r2, GP_2(r4)
|
||||
#if (PPC_USE_MULTIPLE == 1)
|
||||
addi r4, r4, GP_15
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
addi r4, r4, GP_19-GP_15
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
addi r4, r4, GP_23-GP_19
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
addi r4, r4, GP_27-GP_23
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lmw r13, GP_13-GP_27(r4)
|
||||
#else
|
||||
lwz r13, GP_13(r4)
|
||||
lwz r14, GP_14(r4)
|
||||
lwzu r15, GP_15(r4)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lwz r16, GP_16-GP_15(r4)
|
||||
lwz r17, GP_17-GP_15(r4)
|
||||
lwz r18, GP_18-GP_15(r4)
|
||||
lwzu r19, GP_19-GP_15(r4)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lwz r20, GP_20-GP_19(r4)
|
||||
lwz r21, GP_21-GP_19(r4)
|
||||
lwz r22, GP_22-GP_19(r4)
|
||||
lwzu r23, GP_23-GP_19(r4)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lwz r24, GP_24-GP_23(r4)
|
||||
lwz r25, GP_25-GP_23(r4)
|
||||
lwz r26, GP_26-GP_23(r4)
|
||||
lwzu r27, GP_27-GP_23(r4)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lwz r28, GP_28-GP_27(r4)
|
||||
lwz r29, GP_29-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 */
|
||||
li r5, 32
|
||||
addi r3,r3,-4
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stw r1, GP_1+4(r3)
|
||||
stw r2, GP_2+4(r3)
|
||||
#if (PPC_USE_MULTIPLE == 1)
|
||||
addi r3, r3, GP_18+4
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stmw r13, GP_13-GP_18(r3)
|
||||
#else
|
||||
stw r13, GP_13+4(r3)
|
||||
@@ -562,7 +607,9 @@ PROC (_CPU_Context_switch):
|
||||
stw r16, GP_16+4(r3)
|
||||
stw r17, GP_17+4(r3)
|
||||
stwu r18, GP_18+4(r3)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbz r5, r3
|
||||
#endif
|
||||
stw r19, GP_19-GP_18(r3)
|
||||
stw r20, GP_20-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 r31, GP_31-GP_18(r3)
|
||||
#endif
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r0, r4
|
||||
#endif
|
||||
mfcr r6
|
||||
stw r6, GP_CR-GP_18(r3)
|
||||
mflr r7
|
||||
@@ -585,12 +634,16 @@ PROC (_CPU_Context_switch):
|
||||
mfmsr r8
|
||||
stw r8, GP_MSR-GP_18(r3)
|
||||
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lwz r1, GP_1(r4)
|
||||
lwz r2, GP_2(r4)
|
||||
#if (PPC_USE_MULTIPLE == 1)
|
||||
addi r4, r4, GP_19
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lmw r13, GP_13-GP_19(r4)
|
||||
#else
|
||||
lwz r13, GP_13(r4)
|
||||
@@ -600,7 +653,9 @@ PROC (_CPU_Context_switch):
|
||||
lwz r17, GP_17(r4)
|
||||
lwz r18, GP_18(r4)
|
||||
lwzu r19, GP_19(r4)
|
||||
#if ( PPC_USE_DATA_CACHE )
|
||||
dcbt r5, r4
|
||||
#endif
|
||||
lwz r20, GP_20-GP_19(r4)
|
||||
lwz r21, GP_21-GP_19(r4)
|
||||
lwz r22, GP_22-GP_19(r4)
|
||||
@@ -626,7 +681,7 @@ PROC (_CPU_Context_switch):
|
||||
/*
|
||||
* _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.
|
||||
*
|
||||
* NOTE: May be unnecessary to reload some registers.
|
||||
@@ -697,12 +752,15 @@ PROC (_CPU_Context_restore):
|
||||
PUBLIC_PROC (_ISR_Handler)
|
||||
PROC (_ISR_Handler):
|
||||
#define LABEL(x) x
|
||||
/* XXX ??
|
||||
#define MTSAVE(x) mtspr sprg0, x
|
||||
#define MFSAVE(x) mfspr x, sprg0
|
||||
*/
|
||||
#define MTPC(x) mtspr srr0, x
|
||||
#define MFPC(x) mfspr x, srr0
|
||||
#define MTMSR(x) mtspr srr1, x
|
||||
#define MFMSR(x) mfspr x, srr1
|
||||
|
||||
#include "irq_stub.s"
|
||||
rfi
|
||||
|
||||
@@ -724,8 +782,10 @@ PROC (_ISR_HandlerC):
|
||||
#undef MTMSR
|
||||
#undef MFMSR
|
||||
#define LABEL(x) x##_C
|
||||
/* XXX??
|
||||
#define MTSAVE(x) mtspr sprg1, x
|
||||
#define MFSAVE(x) mfspr x, sprg1
|
||||
*/
|
||||
#define MTPC(x) mtspr srr2, x
|
||||
#define MFPC(x) mfspr x, srr2
|
||||
#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
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/* Finish off the interrupt frame */
|
||||
PUBLIC_VAR (_CPU_IRQ_info )
|
||||
|
||||
/* Finish off the interrupt frame */
|
||||
stw r2, IP_2(r1)
|
||||
stw r3, IP_3(r1)
|
||||
stw r4, IP_4(r1)
|
||||
@@ -48,7 +49,12 @@
|
||||
MFPC (r9)
|
||||
MFMSR (r10)
|
||||
/* 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
|
||||
stw r5, IP_CR(r1)
|
||||
stw r6, IP_CTR(r1)
|
||||
@@ -72,8 +78,16 @@
|
||||
* #endif
|
||||
*/
|
||||
/* Switch stacks, here we must prevent ALL interrupts */
|
||||
mfmsr r5
|
||||
mfspr r6, sprg2
|
||||
#if (PPC_USE_SPRG)
|
||||
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
|
||||
cmpwi r30, 0
|
||||
lwz r29, Disable_level(r11)
|
||||
@@ -96,7 +110,14 @@ LABEL (nested):
|
||||
*/
|
||||
addi r31,r31,1
|
||||
stw r31, 0(r29)
|
||||
/* SCE 980217
|
||||
*
|
||||
* We need address translation ON when we call our ISR routine
|
||||
|
||||
mtmsr r5
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* (*_ISR_Vector_table[ vector ])( vector );
|
||||
*/
|
||||
@@ -109,14 +130,14 @@ LABEL (nested):
|
||||
#if (PPC_ABI == PPC_ABI_GCC27)
|
||||
lwz r2, Default_r2(r11)
|
||||
mtlr r4
|
||||
lwz r2, 0(r2)
|
||||
#lwz r2, 0(r2)
|
||||
#endif
|
||||
#if (PPC_ABI == PPC_ABI_SVR4 || PPC_ABI == PPC_ABI_EABI)
|
||||
mtlr r4
|
||||
lwz r2, Default_r2(r11)
|
||||
lwz r13, Default_r13(r11)
|
||||
lwz r2, 0(r2)
|
||||
lwz r13, 0(r13)
|
||||
#lwz r2, 0(r2)
|
||||
#lwz r13, 0(r13)
|
||||
#endif
|
||||
mr r4,r1
|
||||
blrl
|
||||
@@ -124,8 +145,17 @@ LABEL (nested):
|
||||
or r6,r6,r6
|
||||
|
||||
/* We must re-disable the interrupts */
|
||||
#if (PPC_USE_SPRG)
|
||||
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
|
||||
lwz r30, 0(r28)
|
||||
lwz r31, 0(r29)
|
||||
@@ -191,8 +221,18 @@ LABEL (switch):
|
||||
* prepare to get out of interrupt
|
||||
*/
|
||||
/* Re-disable IRQs */
|
||||
#if (PPC_USE_SPRG)
|
||||
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
|
||||
|
||||
/*
|
||||
* easy_exit:
|
||||
* prepare to get out of interrupt
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
*
|
||||
@@ -34,6 +34,7 @@
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _INCLUDE_PPC_h
|
||||
#define _INCLUDE_PPC_h
|
||||
|
||||
@@ -41,148 +42,140 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the name of the CPU family.
|
||||
*/
|
||||
|
||||
#define CPU_NAME "PowerPC"
|
||||
|
||||
/*
|
||||
* This file contains the information required to build
|
||||
* RTEMS for a particular member of the "no cpu"
|
||||
* family when executing in protected mode. It does
|
||||
* RTEMS for a particular member of the PowerPC family. It does
|
||||
* this by setting variables to indicate which implementation
|
||||
* dependent features are present in a particular member
|
||||
* 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 CPU_MODEL_NAME "PowerPC 403"
|
||||
/*
|
||||
* Define the debugging assistance models found in the PPC family.
|
||||
*
|
||||
* 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_ALIGN_POWER 4
|
||||
#define PPC_INTERRUPT_MAX 16
|
||||
#define PPC_HAS_RFCI 1
|
||||
#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_I_CACHE 2048
|
||||
#define PPC_D_CACHE 1024
|
||||
|
||||
#define PPC_MSR_0 0x00029200
|
||||
#define PPC_MSR_1 0x00021200
|
||||
#define PPC_MSR_2 0x00021000
|
||||
#define PPC_MSR_3 0x00000000
|
||||
#define PPC_DEBUG_MODEL PPC_DEBUG_MODEL_IBM4xx
|
||||
#define PPC_HAS_EXCEPTION_PREFIX 0
|
||||
|
||||
#elif defined(ppc601)
|
||||
/*
|
||||
* Submitted with original port -- book checked only.
|
||||
*/
|
||||
|
||||
#define CPU_MODEL_NAME "PowerPC 601"
|
||||
|
||||
#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_I_CACHE 0
|
||||
#define PPC_D_CACHE 32768
|
||||
|
||||
#define PPC_MSR_0 0x00009900
|
||||
#define PPC_MSR_1 0x00001000
|
||||
#define PPC_MSR_2 0x00001000
|
||||
#define PPC_MSR_3 0x00000000
|
||||
|
||||
#define PPC_DEBUG_MODEL PPC_DEBUG_MODEL_SINGLE_STEP_ONLY
|
||||
|
||||
#elif defined(ppc602)
|
||||
/*
|
||||
* Submitted with original port -- book checked only.
|
||||
*/
|
||||
|
||||
#define CPU_MODEL_NAME "PowerPC 602"
|
||||
|
||||
#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_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_D_CACHE 4096
|
||||
|
||||
#elif defined(ppc603)
|
||||
/*
|
||||
* Submitted with original port -- book checked only.
|
||||
*/
|
||||
|
||||
#define CPU_MODEL_NAME "PowerPC 603"
|
||||
|
||||
#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_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)
|
||||
|
||||
#define CPU_MODEL_NAME "PowerPC 603e"
|
||||
/*
|
||||
* Submitted with original port.
|
||||
*
|
||||
* Known to work on real hardware.
|
||||
*/
|
||||
|
||||
#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_D_CACHE 16384
|
||||
|
||||
#define PPC_MSR_0 0x00009900
|
||||
#define PPC_MSR_1 0x00001000
|
||||
#define PPC_MSR_2 0x00001000
|
||||
#define PPC_MSR_3 0x00000000
|
||||
#define PPC_LOW_POWER_MODE PPC_LOW_POWER_MODE_STANDARD
|
||||
|
||||
#elif defined(ppc604)
|
||||
/*
|
||||
* Submitted with original port -- book checked only.
|
||||
*/
|
||||
|
||||
#define CPU_MODEL_NAME "PowerPC 604"
|
||||
|
||||
#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_D_CACHE 16384
|
||||
|
||||
#define PPC_MSR_0 0x00009900
|
||||
#define PPC_MSR_1 0x00001000
|
||||
#define PPC_MSR_2 0x00001000
|
||||
#define PPC_MSR_3 0x00000000
|
||||
|
||||
#else
|
||||
|
||||
#error "Unsupported CPU Model"
|
||||
@@ -191,6 +184,7 @@ extern "C" {
|
||||
|
||||
/*
|
||||
* Application binary interfaces.
|
||||
*
|
||||
* PPC_ABI MUST be defined as one of these.
|
||||
* Only PPC_ABI_POWEROPEN is currently fully supported.
|
||||
* Only EABI will be supported in the end when
|
||||
@@ -237,48 +231,110 @@ extern "C" {
|
||||
/*
|
||||
* Assemblers.
|
||||
* PPC_ASM MUST be defined as one of these.
|
||||
* Only PPC_ABI_ELF is currently fully supported.
|
||||
*/
|
||||
/*
|
||||
* ELF assembler. Currently used for all ABIs.
|
||||
*/
|
||||
#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.
|
||||
*
|
||||
* PPC_ASM_ELF: ELF assembler. Currently used for all ABIs.
|
||||
* PPC_ASM_XCOFF: XCOFF assembler. May be needed for PowerOpen ABI.
|
||||
*
|
||||
* NOTE: Only PPC_ABI_ELF is currently fully supported.
|
||||
*/
|
||||
|
||||
#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
|
||||
/* Protection violation */
|
||||
#define PPC_IRQ_PROTECT 1
|
||||
/* External interrupt */
|
||||
#define PPC_IRQ_EXTERNAL 2
|
||||
/* Program exception */
|
||||
#define PPC_IRQ_PROGRAM 3
|
||||
/* System call */
|
||||
#define PPC_IRQ_SCALL 4
|
||||
/* Floating point unavailable */
|
||||
#define PPC_IRQ_NOFP 5
|
||||
/* Program interval timer */
|
||||
#define PPC_IRQ_PIT 6
|
||||
/* Fixed interval timer */
|
||||
#define PPC_IRQ_FIT 7
|
||||
/* Critical interrupt pin */
|
||||
#define PPC_IRQ_CRIT 8
|
||||
/* Watchdog timer */
|
||||
#define PPC_IRQ_WATCHDOG 9
|
||||
/* Debug exceptions */
|
||||
#define PPC_IRQ_DEBUG 10
|
||||
|
||||
#ifndef PPC_DEBUG_MODEL
|
||||
#define PPC_DEBUG_MODEL PPC_DEBUG_MODEL_STANDARD
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the maximum number of exception sources has not been defined,
|
||||
* then default it to 16.
|
||||
*/
|
||||
|
||||
#ifndef PPC_INTERRUPT_MAX
|
||||
#define PPC_INTERRUPT_MAX 16
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Unless specified otherwise, the cache line size is defaulted to 32.
|
||||
*
|
||||
* The derive the power of 2 the cache line is.
|
||||
*/
|
||||
|
||||
#ifndef PPC_CACHE_ALIGNMENT
|
||||
#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
|
||||
@@ -288,9 +344,141 @@ extern "C" {
|
||||
* 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
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! _INCLUDE_PPC_h */
|
||||
/* end of include file */
|
||||
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
*
|
||||
* 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).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
*
|
||||
* Derived from c/src/exec/cpu/no_cpu/rtems.c:
|
||||
*
|
||||
* COPYRIGHT (c) 1989-1998.
|
||||
* COPYRIGHT (c) 1989-1997.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
* Copyright assigned to U.S. Government, 1994.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* The license and distribution terms for this file may in
|
||||
* the file LICENSE in this distribution or at
|
||||
* http://www.OARcorp.com/rtems/license.html.
|
||||
*
|
||||
* $Id$
|
||||
|
||||
Reference in New Issue
Block a user