Refreshing effort from Avenger.

This commit is contained in:
Joel Sherrill
1998-04-14 19:54:24 +00:00
parent a34ab1b23a
commit 993e1b5c73
8 changed files with 1055 additions and 331 deletions
+24 -17
View File
@@ -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
File diff suppressed because it is too large Load Diff
+168 -97
View File
@@ -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.
+65 -5
View File
@@ -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
+50 -10
View File
@@ -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
File diff suppressed because it is too large Load Diff
+3 -3
View 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$
+3 -3
View File
@@ -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$