summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-04-14 19:54:24 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-04-14 19:54:24 +0000
commit993e1b5c733572b09c16cb2057a0d18a22a91d2d (patch)
tree4bcc47c847ca5789308c6b773aa3a2e9df12cb34
parentremoved shmsupp (diff)
downloadrtems-993e1b5c733572b09c16cb2057a0d18a22a91d2d.tar.bz2
Refreshing effort from Avenger.
-rw-r--r--c/src/exec/score/cpu/powerpc/README41
-rw-r--r--c/src/exec/score/cpu/powerpc/cpu.c498
-rw-r--r--c/src/exec/score/cpu/powerpc/cpu.h265
-rw-r--r--c/src/exec/score/cpu/powerpc/cpu_asm.s70
-rw-r--r--c/src/exec/score/cpu/powerpc/irq_stub.s60
-rw-r--r--c/src/exec/score/cpu/powerpc/ppc.h422
-rw-r--r--c/src/exec/score/cpu/powerpc/ppctypes.h6
-rw-r--r--c/src/exec/score/cpu/powerpc/rtems.s6
8 files changed, 1046 insertions, 322 deletions
diff --git a/c/src/exec/score/cpu/powerpc/README b/c/src/exec/score/cpu/powerpc/README
index fc0dd9c7d7..0b87ac1ea7 100644
--- a/c/src/exec/score/cpu/powerpc/README
+++ b/c/src/exec/score/cpu/powerpc/README
@@ -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
diff --git a/c/src/exec/score/cpu/powerpc/cpu.c b/c/src/exec/score/cpu/powerpc/cpu.c
index 072405425c..676e330e5f 100644
--- a/c/src/exec/score/cpu/powerpc/cpu.c
+++ b/c/src/exec/score/cpu/powerpc/cpu.c
@@ -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 */
+#endif
- i = PPC_MSR_INITIAL & ~PPC_MSR_DISABLE_MASK;
+ /*
+ * 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 */
-
-#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
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.
+ * 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
*
- * 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.
+ * _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 ];
/*
@@ -190,6 +308,12 @@ void _CPU_ISR_install_vector(
*/
/*
+ * 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;
+}
+
diff --git a/c/src/exec/score/cpu/powerpc/cpu.h b/c/src/exec/score/cpu/powerpc/cpu.h
index 3f6cb0f000..d2353bacf5 100644
--- a/c/src/exec/score/cpu/powerpc/cpu.h
+++ b/c/src/exec/score/cpu/powerpc/cpu.h
@@ -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,18 +461,38 @@ 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
* _CPU_Initialize and copied into the task's FP context area during
@@ -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.
diff --git a/c/src/exec/score/cpu/powerpc/cpu_asm.s b/c/src/exec/score/cpu/powerpc/cpu_asm.s
index fccc31b7d1..7370764607 100644
--- a/c/src/exec/score/cpu/powerpc/cpu_asm.s
+++ b/c/src/exec/score/cpu/powerpc/cpu_asm.s
@@ -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
diff --git a/c/src/exec/score/cpu/powerpc/irq_stub.s b/c/src/exec/score/cpu/powerpc/irq_stub.s
index 42a63e991f..76c8927305 100644
--- a/c/src/exec/score/cpu/powerpc/irq_stub.s
+++ b/c/src/exec/score/cpu/powerpc/irq_stub.s
@@ -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
diff --git a/c/src/exec/score/cpu/powerpc/ppc.h b/c/src/exec/score/cpu/powerpc/ppc.h
index 7785ab506e..56fd820709 100644
--- a/c/src/exec/score/cpu/powerpc/ppc.h
+++ b/c/src/exec/score/cpu/powerpc/ppc.h
@@ -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
@@ -42,147 +43,139 @@ 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
*/
+/*
+ * 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_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 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.
+ *
+ * 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 PPC_ASM_ELF 0
+#define PPC_ASM_XCOFF 1
+
+/*
+ * Use the default debug scheme defined in the architectural specification
+ * if another model has not been specified.
*/
+
+#ifndef PPC_DEBUG_MODEL
+#define PPC_DEBUG_MODEL PPC_DEBUG_MODEL_STANDARD
+#endif
+
/*
- * ELF assembler. Currently used for all ABIs.
+ * If the maximum number of exception sources has not been defined,
+ * then default it to 16.
*/
-#define PPC_ASM_ELF 0
+
+#ifndef PPC_INTERRUPT_MAX
+#define PPC_INTERRUPT_MAX 16
+#endif
+
/*
- * XCOFF assembler, may be needed for PowerOpen ABI.
+ * Unless specified otherwise, the cache line size is defaulted to 32.
+ *
+ * The derive the power of 2 the cache line is.
*/
-#define PPC_ASM_XCOFF 1
+
+#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
/*
- * Define the name of the CPU family.
+ * Unless otherwise specified, assume the model has an IP/EP bit to
+ * set the exception address prefix.
*/
-#define CPU_NAME "PowerPC"
+#ifndef PPC_HAS_EXCEPTION_PREFIX
+#define PPC_HAS_EXCEPTION_PREFIX 1
+#endif
/*
- * Interrupt vectors.
- */
-/* 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
+ * 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 */
+
+
diff --git a/c/src/exec/score/cpu/powerpc/ppctypes.h b/c/src/exec/score/cpu/powerpc/ppctypes.h
index 0663c63d8d..71f1b814b2 100644
--- a/c/src/exec/score/cpu/powerpc/ppctypes.h
+++ b/c/src/exec/score/cpu/powerpc/ppctypes.h
@@ -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$
diff --git a/c/src/exec/score/cpu/powerpc/rtems.s b/c/src/exec/score/cpu/powerpc/rtems.s
index a2280c1edc..b653152411 100644
--- a/c/src/exec/score/cpu/powerpc/rtems.s
+++ b/c/src/exec/score/cpu/powerpc/rtems.s
@@ -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$