mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
updartes from Tony Bennett
This commit is contained in:
@@ -19,117 +19,52 @@
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/isr.h>
|
||||
void hppa_cpu_halt(unsigned32 the_error);
|
||||
|
||||
void hppa_external_interrupt_initialize(void);
|
||||
void hppa_external_interrupt_enable(unsigned32);
|
||||
void hppa_external_interrupt_disable(unsigned32);
|
||||
void hppa_external_interrupt(unsigned32, CPU_Interrupt_frame *);
|
||||
void hppa_cpu_halt(unsigned32);
|
||||
|
||||
/*
|
||||
* The first level interrupt handler for first 32 interrupts/traps.
|
||||
* Indexed by vector; generally each entry is _Generic_ISR_Handler.
|
||||
* Some TLB traps may have their own first level handler.
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
extern void _Generic_ISR_Handler(void);
|
||||
unsigned32 HPPA_first_level_interrupt_handler[HPPA_INTERNAL_INTERRUPTS];
|
||||
|
||||
/* _CPU_Initialize
|
||||
*
|
||||
* This routine performs processor dependent initialization.
|
||||
*
|
||||
* INPUT PARAMETERS:
|
||||
* cpu_table - CPU table to initialize
|
||||
* thread_dispatch - address of disptaching routine
|
||||
*
|
||||
*/
|
||||
|
||||
void _CPU_Initialize(
|
||||
rtems_cpu_table *cpu_table,
|
||||
void (*thread_dispatch) /* ignored on this CPU */
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
register unsigned8 *fp_context;
|
||||
unsigned32 iva;
|
||||
unsigned32 iva_table;
|
||||
int i;
|
||||
/*
|
||||
* This is unsupported. For HPPA this function is handled by BSP
|
||||
*/
|
||||
|
||||
extern void IVA_Table(void);
|
||||
|
||||
/*
|
||||
* XXX; need to setup fpsr smarter perhaps
|
||||
*/
|
||||
|
||||
fp_context = (unsigned8*) &_CPU_Null_fp_context;
|
||||
for (i=0 ; i<sizeof(Context_Control_fp); i++)
|
||||
*fp_context++ = 0;
|
||||
|
||||
/*
|
||||
* Set _CPU_Default_gr27 here so it will hopefully be the correct
|
||||
* global data pointer for the entire system.
|
||||
*/
|
||||
|
||||
asm volatile( "stw %%r27,%0" : "=m" (_CPU_Default_gr27): );
|
||||
|
||||
/*
|
||||
* Init the first level interrupt handlers
|
||||
*/
|
||||
|
||||
for (i=0; i <= HPPA_INTERNAL_INTERRUPTS; i++)
|
||||
HPPA_first_level_interrupt_handler[i] = (unsigned32) _Generic_ISR_Handler;
|
||||
|
||||
/*
|
||||
* Init the 2nd level interrupt handlers
|
||||
*/
|
||||
|
||||
for (i=0; i <= CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
|
||||
_ISR_Vector_table[i] = (ISR_Handler_entry) hppa_cpu_halt;
|
||||
|
||||
/*
|
||||
* Stabilize the interrupt stuff
|
||||
*/
|
||||
|
||||
(void) hppa_external_interrupt_initialize();
|
||||
|
||||
/*
|
||||
* Set the IVA to point to physical address of the IVA_Table
|
||||
*/
|
||||
|
||||
iva_table = (unsigned32) IVA_Table;
|
||||
#if defined(hppa1_1)
|
||||
/*
|
||||
* HACK: (from PA72000 TRM, page 4-19)
|
||||
* "The hardware TLB miss handler will never attempt to service
|
||||
* a non-access TLB miss or a TLB protection violation. It
|
||||
* will only attempt to service TLB accesses that would cause
|
||||
* Trap Numbers 6 (Instruction TLB miss) and 15 (Data TLB miss)."
|
||||
*
|
||||
* The LPA instruction is used to translate a virtual address to
|
||||
* a physical address, however, if the requested virtual address
|
||||
* is not currently resident in the TLB, the hardware TLB miss
|
||||
* handler will NOT insert it. In this situation Trap Number
|
||||
* #17 is invoked (Non-access Data TLB miss fault).
|
||||
*
|
||||
* To work around this, a dummy data access is first performed
|
||||
* to the virtual address prior to the LPA. The dummy access
|
||||
* causes the TLB entry to be inserted (if not already present)
|
||||
* and then the following LPA instruction will not generate
|
||||
* a non-access data TLB miss fault.
|
||||
*
|
||||
* It is unclear whether or not this behaves the same way for
|
||||
* the PA8000.
|
||||
*
|
||||
*/
|
||||
iva = *(volatile unsigned32 *)iva_table; /* dummy access */
|
||||
#endif
|
||||
|
||||
HPPA_ASM_LPA(0, iva_table, iva);
|
||||
set_iva(iva);
|
||||
|
||||
_CPU_Table = *cpu_table;
|
||||
_CPU_Fatal_halt( 0xdeaddead );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This is the default handler which is called if
|
||||
* _CPU_ISR_install_vector() has not been called for the
|
||||
* specified vector. It simply forwards onto the spurious
|
||||
* handler defined in the cpu-table.
|
||||
*/
|
||||
|
||||
static ISR_Handler
|
||||
hppa_interrupt_report_spurious(ISR_Vector_number vector,
|
||||
void* rtems_isr_frame) /* HPPA extension */
|
||||
{
|
||||
|
||||
/*
|
||||
* If the CPU table defines a spurious_handler, then
|
||||
* call it. If the handler returns halt.
|
||||
*/
|
||||
if ( _CPU_Table.spurious_handler )
|
||||
_CPU_Table.spurious_handler(vector, rtems_isr_frame);
|
||||
|
||||
hppa_cpu_halt(vector);
|
||||
}
|
||||
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Get_level
|
||||
@@ -144,30 +79,12 @@ unsigned32 _CPU_ISR_Get_level(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
/*
|
||||
* This is unsupported.
|
||||
*/
|
||||
|
||||
_CPU_Fatal_halt( 0xdeaddead );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
* specified vector. The handler is a C callable routine.
|
||||
*
|
||||
* Input parameters:
|
||||
* vector - interrupt vector number
|
||||
@@ -178,12 +95,6 @@ void _CPU_ISR_install_raw_handler(
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* HPPA has 8w for each vector instead of an address to jump to.
|
||||
* We put the actual ISR address in '_ISR_vector_table'. This will
|
||||
* be pulled by the code in the vector.
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
@@ -193,156 +104,55 @@ void _CPU_ISR_install_vector(
|
||||
*old_handler = _ISR_Vector_table[vector];
|
||||
|
||||
_ISR_Vector_table[vector] = new_handler;
|
||||
|
||||
if (vector >= HPPA_INTERRUPT_EXTERNAL_BASE)
|
||||
{
|
||||
unsigned32 external_vector;
|
||||
|
||||
external_vector = vector - HPPA_INTERRUPT_EXTERNAL_BASE;
|
||||
if (new_handler)
|
||||
hppa_external_interrupt_enable(external_vector);
|
||||
else
|
||||
/* XXX this can never happen due to _ISR_Is_valid_user_handler */
|
||||
hppa_external_interrupt_disable(external_vector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Support for external and spurious interrupts on HPPA
|
||||
/* _CPU_Initialize
|
||||
*
|
||||
* This routine performs processor dependent initialization.
|
||||
*
|
||||
* INPUT PARAMETERS:
|
||||
* cpu_table - CPU table to initialize
|
||||
* thread_dispatch - address of disptaching routine
|
||||
*
|
||||
* TODO:
|
||||
* Count interrupts
|
||||
* make sure interrupts disabled properly
|
||||
*/
|
||||
|
||||
#define DISMISS(mask) set_eirr(mask)
|
||||
#define DISABLE(mask) set_eiem(get_eiem() & ~(mask))
|
||||
#define ENABLE(mask) set_eiem(get_eiem() | (mask))
|
||||
#define VECTOR_TO_MASK(v) (1 << (31 - (v)))
|
||||
|
||||
/*
|
||||
* Init the external interrupt scheme
|
||||
* called by bsp_start()
|
||||
*/
|
||||
|
||||
void
|
||||
hppa_external_interrupt_initialize(void)
|
||||
void _CPU_Initialize(
|
||||
rtems_cpu_table *cpu_table,
|
||||
void (*thread_dispatch) /* ignored on this CPU */
|
||||
)
|
||||
{
|
||||
proc_ptr ignore;
|
||||
register unsigned8 *fp_context;
|
||||
int i;
|
||||
proc_ptr old_handler;
|
||||
|
||||
/* mark them all unused */
|
||||
DISABLE(~0);
|
||||
DISMISS(~0);
|
||||
/*
|
||||
* XXX; need to setup fpsr smarter perhaps
|
||||
*/
|
||||
|
||||
/* install the external interrupt handler */
|
||||
_CPU_ISR_install_vector(
|
||||
HPPA_INTERRUPT_EXTERNAL_INTERRUPT,
|
||||
(proc_ptr)hppa_external_interrupt, &ignore
|
||||
);
|
||||
fp_context = (unsigned8*) &_CPU_Null_fp_context;
|
||||
for (i=0 ; i<sizeof(Context_Control_fp); i++)
|
||||
*fp_context++ = 0;
|
||||
|
||||
/*
|
||||
* Set _CPU_Default_gr27 here so it will hopefully be the correct
|
||||
* global data pointer for the entire system.
|
||||
*/
|
||||
|
||||
asm volatile( "stw %%r27,%0" : "=m" (_CPU_Default_gr27): );
|
||||
|
||||
/*
|
||||
* Init the 2nd level interrupt handlers
|
||||
*/
|
||||
|
||||
for (i=0; i < CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
|
||||
_CPU_ISR_install_vector(i,
|
||||
hppa_interrupt_report_spurious,
|
||||
&old_handler);
|
||||
|
||||
_CPU_Table = *cpu_table;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable a specific external interrupt
|
||||
*/
|
||||
|
||||
void
|
||||
hppa_external_interrupt_enable(unsigned32 v)
|
||||
{
|
||||
unsigned32 isrlevel;
|
||||
|
||||
_CPU_ISR_Disable(isrlevel);
|
||||
ENABLE(VECTOR_TO_MASK(v));
|
||||
_CPU_ISR_Enable(isrlevel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Does not clear or otherwise affect any pending requests
|
||||
*/
|
||||
|
||||
void
|
||||
hppa_external_interrupt_disable(unsigned32 v)
|
||||
{
|
||||
unsigned32 isrlevel;
|
||||
|
||||
_CPU_ISR_Disable(isrlevel);
|
||||
DISABLE(VECTOR_TO_MASK(v));
|
||||
_CPU_ISR_Enable(isrlevel);
|
||||
}
|
||||
|
||||
void
|
||||
hppa_external_interrupt_spurious_handler(unsigned32 vector,
|
||||
CPU_Interrupt_frame *iframe)
|
||||
{
|
||||
/* XXX should not be printing :)
|
||||
printf("spurious external interrupt: %d at pc 0x%x; disabling\n",
|
||||
vector, iframe->Interrupt.pcoqfront);
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
hppa_external_interrupt_report_spurious(unsigned32 spurious_mask,
|
||||
CPU_Interrupt_frame *iframe)
|
||||
{
|
||||
int v;
|
||||
for (v=0; v < HPPA_EXTERNAL_INTERRUPTS; v++)
|
||||
if (VECTOR_TO_MASK(v) & spurious_mask)
|
||||
{
|
||||
DISMISS(VECTOR_TO_MASK(v));
|
||||
DISABLE(VECTOR_TO_MASK(v));
|
||||
hppa_external_interrupt_spurious_handler(v, iframe);
|
||||
}
|
||||
DISMISS(spurious_mask);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* External interrupt handler.
|
||||
* This is installed as cpu interrupt handler for
|
||||
* HPPA_INTERRUPT_EXTERNAL_INTERRUPT. It vectors out to
|
||||
* specific external interrupt handlers.
|
||||
*/
|
||||
|
||||
void
|
||||
hppa_external_interrupt(unsigned32 vector,
|
||||
CPU_Interrupt_frame *iframe)
|
||||
{
|
||||
unsigned32 mask;
|
||||
unsigned32 *vp, *max_vp;
|
||||
unsigned32 external_vector;
|
||||
unsigned32 global_vector;
|
||||
hppa_rtems_isr_entry handler;
|
||||
|
||||
max_vp = &_CPU_Table.external_interrupt[_CPU_Table.external_interrupts];
|
||||
while ( (mask = (get_eirr() & get_eiem())) )
|
||||
{
|
||||
for (vp = _CPU_Table.external_interrupt; (vp < max_vp) && mask; vp++)
|
||||
{
|
||||
unsigned32 m;
|
||||
|
||||
external_vector = *vp;
|
||||
global_vector = external_vector + HPPA_INTERRUPT_EXTERNAL_BASE;
|
||||
m = VECTOR_TO_MASK(external_vector);
|
||||
handler = (hppa_rtems_isr_entry) _ISR_Vector_table[global_vector];
|
||||
if ((m & mask) && handler)
|
||||
{
|
||||
DISMISS(m);
|
||||
mask &= ~m;
|
||||
handler(global_vector, iframe);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask != 0) {
|
||||
if ( _CPU_Table.spurious_handler )
|
||||
{
|
||||
handler = (hppa_rtems_isr_entry) _CPU_Table.spurious_handler;
|
||||
handler(mask, iframe);
|
||||
}
|
||||
else
|
||||
hppa_external_interrupt_report_spurious(mask, iframe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Halt the system.
|
||||
@@ -351,8 +161,17 @@ hppa_external_interrupt(unsigned32 vector,
|
||||
* XXX
|
||||
* Later on, this will allow us to return to the prom.
|
||||
* For now, we just ignore 'type_of_halt'
|
||||
*
|
||||
* XXX
|
||||
* NOTE: for gcc, this function must be at the bottom
|
||||
* of the file, that is because if it is at the top
|
||||
* of the file, gcc will inline it's calls. Since
|
||||
* the function uses the HPPA_ASM_LABEL() macro, when
|
||||
* gcc inlines it, you get two definitions of the same
|
||||
* label name, which is an assembly error.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
hppa_cpu_halt(unsigned32 the_error)
|
||||
{
|
||||
@@ -360,6 +179,11 @@ hppa_cpu_halt(unsigned32 the_error)
|
||||
|
||||
_CPU_ISR_Disable(isrlevel);
|
||||
|
||||
/*
|
||||
* XXXXX NOTE: This label is only needed that that when
|
||||
* the simulator stops, it shows the label name specified
|
||||
*/
|
||||
HPPA_ASM_LABEL("_hppa_cpu_halt");
|
||||
HPPA_ASM_BREAK(1, 0);
|
||||
HPPA_ASM_BREAK(0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,26 +216,12 @@ typedef struct {
|
||||
void (*predriver_hook)( void );
|
||||
void (*postdriver_hook)( void );
|
||||
void (*idle_task)( void );
|
||||
|
||||
/* HPPA simulator is slow enough; don't waste time
|
||||
* zeroing memory that is already zero
|
||||
*/
|
||||
boolean do_zero_of_workspace;
|
||||
|
||||
unsigned32 interrupt_stack_size;
|
||||
unsigned32 extra_mpci_receive_server_stack;
|
||||
|
||||
/*
|
||||
* Control of external interrupts.
|
||||
* We keep a table of external vector numbers (0 - 31)
|
||||
* The table is sorted by priority, that is: the first entry
|
||||
* in the table indicates the vector that is highest priorty.
|
||||
* The handler function is stored in _ISR_Vector_Table[] and
|
||||
* is set by rtems_interrupt_catch()
|
||||
*/
|
||||
|
||||
unsigned32 external_interrupts; /* # of external interrupts we use */
|
||||
unsigned32 external_interrupt[HPPA_EXTERNAL_INTERRUPTS];
|
||||
void * (*stack_allocate_hook)( unsigned32 );
|
||||
void (*stack_free_hook)( void * );
|
||||
/* end of fields required on all CPUs */
|
||||
|
||||
hppa_rtems_isr_entry spurious_handler;
|
||||
|
||||
@@ -249,9 +235,6 @@ EXTERN unsigned32 _CPU_Default_gr27;
|
||||
EXTERN void *_CPU_Interrupt_stack_low;
|
||||
EXTERN void *_CPU_Interrupt_stack_high;
|
||||
|
||||
/* entry points */
|
||||
void hppa_external_interrupt_spurious_handler(unsigned32, CPU_Interrupt_frame *);
|
||||
|
||||
#endif /* ! ASM */
|
||||
|
||||
/*
|
||||
@@ -285,15 +268,12 @@ void hppa_external_interrupt_spurious_handler(unsigned32, CPU_Interrupt_frame *)
|
||||
|
||||
/*
|
||||
* HPPA has 32 interrupts, then 32 external interrupts
|
||||
* Rtems (_ISR_Vector_Table) is aware of the first 64
|
||||
* A BSP may reserve more.
|
||||
* Rtems (_ISR_Vector_Table) is aware ONLY of the first 32
|
||||
* The BSP is aware of the external interrupts and possibly more.
|
||||
*
|
||||
* External interrupts all come thru the same vector (4)
|
||||
* The external handler is the only person aware of the other
|
||||
* interrupts (genie, rhino, etc)
|
||||
*/
|
||||
|
||||
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (HPPA_INTERRUPT_MAX)
|
||||
#define CPU_INTERRUPT_NUMBER_OF_VECTORS (HPPA_INTERNAL_INTERRUPTS)
|
||||
#define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1)
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# @(#)cpu_asm.S 1.7 - 95/09/21
|
||||
#
|
||||
#
|
||||
# TODO:
|
||||
# Context_switch needs to only save callee save registers
|
||||
@@ -30,7 +28,6 @@
|
||||
#include <rtems/score/hppa.h>
|
||||
#include <rtems/score/cpu_asm.h>
|
||||
#include <rtems/score/cpu.h>
|
||||
|
||||
#include <rtems/score/offsets.h>
|
||||
|
||||
.SPACE $PRIVATE$
|
||||
@@ -64,20 +61,12 @@ isr_r8 .reg %cr26
|
||||
|
||||
|
||||
# PAGE^L
|
||||
# void __Generic_ISR_Handler()
|
||||
# void _Generic_ISR_Handler()
|
||||
#
|
||||
# This routine provides the RTEMS interrupt management.
|
||||
#
|
||||
# NOTE:
|
||||
# Upon entry, the stack will contain a stack frame back to the
|
||||
# interrupted task. If dispatching is enabled, this is the
|
||||
# outer most interrupt, (and a context switch is necessary or
|
||||
# the current task has signals), then set up the stack to
|
||||
# transfer control to the interrupt dispatcher.
|
||||
#
|
||||
#
|
||||
# We jump here from the interrupt vector.
|
||||
# The hardware has done some stuff for us:
|
||||
# The HPPA hardware has done some stuff for us:
|
||||
# PSW saved in IPSW
|
||||
# PSW set to 0
|
||||
# PSW[E] set to default (0)
|
||||
@@ -89,117 +78,30 @@ isr_r8 .reg %cr26
|
||||
# registers GR 1,8,9,16,17,24,25 copied to shadow regs
|
||||
# SHR 0 1 2 3 4 5 6
|
||||
#
|
||||
# Our vector stub did the following
|
||||
# placed vector number is in r1
|
||||
# Our vector stub (in the BSP) MUST have done the following:
|
||||
#
|
||||
# stub
|
||||
# r1 <- vector number
|
||||
# save ipsw under rock
|
||||
# ipsw = ipsw & ~1 -- disable ints
|
||||
# save qregs under rock
|
||||
# qra = _Generic_ISR_handler
|
||||
# rfi
|
||||
# a) Saved the original %r9 into %isr_r9 (%cr25)
|
||||
# b) Placed the vector number in %r9
|
||||
# c) Was allowed to also destroy $isr_r8 (%cr26),
|
||||
# but the stub was NOT allowed to destroy any other registers.
|
||||
#
|
||||
################################################
|
||||
|
||||
# Distinct Interrupt Entry Points
|
||||
# The typical stub sequence (in the BSP) should look like this:
|
||||
#
|
||||
# a) mtctl %r9,isr_r9 ; (save r9 in cr25)
|
||||
# b) ldi vector,%r9 ; (load constant vector number in r9)
|
||||
# c) mtctl %r8,isr_r8 ; (save r8 in cr26)
|
||||
# d) ldil L%MY_BSP_first_level_interrupt_handler,%r8
|
||||
# e) ldo R%MY_BSP_first_level_interrupt_handler(%r8),%r8
|
||||
# ; (point to BSP raw handler table)
|
||||
# f) ldwx,s %r9(%r8),%r8 ; (load value from raw handler table)
|
||||
# g) bv 0(%r8) ; (call raw handler: _Generic_ISR_Handler)
|
||||
# h) mfctl isr_r8,%r8 ; (restore r8 from cr26 in delay slot)
|
||||
#
|
||||
# Optionally, steps (c) thru (h) _could_ be replaced with a single
|
||||
# bl,n _Generic_ISR_Handler,%r0
|
||||
#
|
||||
# The following macro and the 32 instantiations of the macro
|
||||
# are necessary to determine which interrupt vector occurred.
|
||||
#
|
||||
# r9 is loaded with the vector number and then we jump to
|
||||
# the first level interrupt handler. In most cases this
|
||||
# is _Generic_ISR_Handler. In a few cases (such as TLB misc)
|
||||
# it may be to some other entry point.
|
||||
#
|
||||
|
||||
# table for first level interrupt handlers
|
||||
.import HPPA_first_level_interrupt_handler, data
|
||||
|
||||
#define THANDLER(vector) \
|
||||
mtctl %r9, isr_r9 ! \
|
||||
mtctl %r8, isr_r8 ! \
|
||||
ldi vector, %r9 ! \
|
||||
ldil L%HPPA_first_level_interrupt_handler,%r8 ! \
|
||||
ldo R%HPPA_first_level_interrupt_handler(%r8),%r8 ! \
|
||||
ldwx,s %r9(%r8),%r8 ! \
|
||||
bv 0(%r8) ! \
|
||||
mfctl isr_r8, %r8
|
||||
|
||||
.align 4096
|
||||
.EXPORT IVA_Table,ENTRY,PRIV_LEV=0
|
||||
IVA_Table:
|
||||
.PROC
|
||||
.CALLINFO FRAME=0,NO_CALLS
|
||||
.ENTRY
|
||||
|
||||
THANDLER(0) /* unused */
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_HIGH_PRIORITY_MACHINE_CHECK)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_POWER_FAIL)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_RECOVERY_COUNTER)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_EXTERNAL_INTERRUPT)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_LOW_PRIORITY_MACHINE_CHECK)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_INSTRUCTION_TLB_MISS)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_INSTRUCTION_MEMORY_PROTECTION)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_ILLEGAL_INSTRUCTION)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_BREAK_INSTRUCTION)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_PRIVILEGED_OPERATION)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_PRIVILEGED_REGISTER)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_OVERFLOW)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_CONDITIONAL)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_ASSIST_EXCEPTION)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_DATA_TLB_MISS)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_NON_ACCESS_INSTRUCTION_TLB_MISS)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_NON_ACCESS_DATA_TLB_MISS)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_DATA_MEMORY_PROTECTION)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_DATA_MEMORY_BREAK)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_TLB_DIRTY_BIT)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_PAGE_REFERENCE)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_ASSIST_EMULATION)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_HIGHER_PRIVILEGE_TRANSFER)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_LOWER_PRIVILEGE_TRANSFER)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_TAKEN_BRANCH)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_DATA_MEMORY_ACCESS_RIGHTS)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_DATA_MEMORY_PROTECTION_ID)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_UNALIGNED_DATA_REFERENCE)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_PERFORMANCE_MONITOR)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_INSTRUCTION_DEBUG)
|
||||
|
||||
THANDLER(HPPA_INTERRUPT_DATA_DEBUG)
|
||||
|
||||
.EXIT
|
||||
.PROCEND
|
||||
|
||||
.EXPORT _Generic_ISR_Handler,ENTRY,PRIV_LEV=0
|
||||
_Generic_ISR_Handler:
|
||||
.PROC
|
||||
@@ -235,8 +137,8 @@ _Generic_ISR_Handler:
|
||||
# At this point the following registers are damaged wrt the interrupt
|
||||
# reg current value saved value
|
||||
# ------------------------------------------------
|
||||
# arg0 scratch isr_arg0 (ctl)
|
||||
# r9 vector number isr_r9 (ctl)
|
||||
# arg0 scratch isr_arg0 (cr24)
|
||||
# r9 vector number isr_r9 (cr25)
|
||||
#
|
||||
# Point to beginning of integer context and
|
||||
# save the integer context
|
||||
@@ -277,8 +179,8 @@ _Generic_ISR_Handler:
|
||||
# The following items are currently wrong in the integer context
|
||||
# reg current value saved value
|
||||
# ------------------------------------------------
|
||||
# arg0 scratch isr_arg0 (ctl)
|
||||
# r9 vector number isr_r9 (ctl)
|
||||
# arg0 scratch isr_arg0 (cr24)
|
||||
# r9 vector number isr_r9 (cr25)
|
||||
#
|
||||
# Fix them
|
||||
|
||||
@@ -377,6 +279,9 @@ stack_done:
|
||||
stw %r6, 0(%r4)
|
||||
|
||||
# load address of user handler
|
||||
# Note: No error checking is done, it is assumed that the
|
||||
# vector table contains a valid address or a stub
|
||||
# spurious handler.
|
||||
.import _ISR_Vector_table,data
|
||||
ldil L%_ISR_Vector_table,%r8
|
||||
ldo R%_ISR_Vector_table(%r8),%r8
|
||||
@@ -388,7 +293,7 @@ stack_done:
|
||||
# NOTE: can not use 'bl' since it uses "pc-relative" addressing
|
||||
# and we are using a hard coded address from a table
|
||||
# So... we fudge r2 ourselves (ala dynacall)
|
||||
#
|
||||
# arg0 = vector number, arg1 = ptr to rtems_interrupt_frame
|
||||
copy %r9, %r26
|
||||
.call ARGW0=GR, ARGW1=GR
|
||||
blr %r0, rp
|
||||
@@ -404,29 +309,32 @@ post_user_interrupt_handler:
|
||||
rsm HPPA_PSW_I + HPPA_PSW_R, %r0
|
||||
ldw -4(sp), sp
|
||||
|
||||
# r3 -- &_ISR_Nest_level
|
||||
# r3 -- (most of) &_ISR_Nest_level
|
||||
# r5 -- value _ISR_Nest_level
|
||||
# r4 -- &_Thread_Dispatch_disable_level
|
||||
# r4 -- (most of) &_Thread_Dispatch_disable_level
|
||||
# r6 -- value _Thread_Dispatch_disable_level
|
||||
# r7 -- (most of) &_ISR_Signals_to_thread_executing
|
||||
# r8 -- value _ISR_Signals_to_thread_executing
|
||||
|
||||
.import _ISR_Nest_level,data
|
||||
ldil L%_ISR_Nest_level,%r3
|
||||
ldo R%_ISR_Nest_level(%r3),%r3
|
||||
ldw 0(%r3),%r5
|
||||
ldw R%_ISR_Nest_level(%r3),%r5
|
||||
|
||||
.import _Thread_Dispatch_disable_level,data
|
||||
ldil L%_Thread_Dispatch_disable_level,%r4
|
||||
ldo R%_Thread_Dispatch_disable_level(%r4),%r4
|
||||
ldw 0(%r4), %r6
|
||||
ldw R%_Thread_Dispatch_disable_level(%r4),%r6
|
||||
|
||||
.import _ISR_Signals_to_thread_executing,data
|
||||
ldil L%_ISR_Signals_to_thread_executing,%r7
|
||||
|
||||
# decrement isr nest level
|
||||
addi -1, %r5, %r5
|
||||
stw %r5, 0(%r3)
|
||||
stw %r5, R%_ISR_Nest_level(%r3)
|
||||
|
||||
# decrement dispatch disable level counter and, if not 0, go on
|
||||
addi -1,%r6,%r6
|
||||
comibf,= 0,%r6,isr_restore
|
||||
stw %r6, 0(%r4)
|
||||
stw %r6, R%_Thread_Dispatch_disable_level(%r4)
|
||||
|
||||
# check whether or not a context switch is necessary
|
||||
.import _Context_Switch_necessary,data
|
||||
@@ -436,9 +344,7 @@ post_user_interrupt_handler:
|
||||
|
||||
# check whether or not a context switch is necessary because an ISR
|
||||
# sent signals to the interrupted task
|
||||
.import _ISR_Signals_to_thread_executing,data
|
||||
ldil L%_ISR_Signals_to_thread_executing,%r8
|
||||
ldw R%_ISR_Signals_to_thread_executing(%r8),%r8
|
||||
ldw R%_ISR_Signals_to_thread_executing(%r7),%r8
|
||||
comibt,=,n 0,%r8,isr_restore
|
||||
|
||||
|
||||
@@ -450,6 +356,8 @@ post_user_interrupt_handler:
|
||||
#
|
||||
|
||||
ISR_dispatch:
|
||||
stw %r0, R%_ISR_Signals_to_thread_executing(%r7)
|
||||
|
||||
ssm HPPA_PSW_I, %r0
|
||||
|
||||
.import _Thread_Dispatch,code
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
/*
|
||||
* @(#)hppa.h 1.17 - 95/12/13
|
||||
*
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Definitions for HP PA Risc
|
||||
|
||||
@@ -19,117 +19,52 @@
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/score/isr.h>
|
||||
void hppa_cpu_halt(unsigned32 the_error);
|
||||
|
||||
void hppa_external_interrupt_initialize(void);
|
||||
void hppa_external_interrupt_enable(unsigned32);
|
||||
void hppa_external_interrupt_disable(unsigned32);
|
||||
void hppa_external_interrupt(unsigned32, CPU_Interrupt_frame *);
|
||||
void hppa_cpu_halt(unsigned32);
|
||||
|
||||
/*
|
||||
* The first level interrupt handler for first 32 interrupts/traps.
|
||||
* Indexed by vector; generally each entry is _Generic_ISR_Handler.
|
||||
* Some TLB traps may have their own first level handler.
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
extern void _Generic_ISR_Handler(void);
|
||||
unsigned32 HPPA_first_level_interrupt_handler[HPPA_INTERNAL_INTERRUPTS];
|
||||
|
||||
/* _CPU_Initialize
|
||||
*
|
||||
* This routine performs processor dependent initialization.
|
||||
*
|
||||
* INPUT PARAMETERS:
|
||||
* cpu_table - CPU table to initialize
|
||||
* thread_dispatch - address of disptaching routine
|
||||
*
|
||||
*/
|
||||
|
||||
void _CPU_Initialize(
|
||||
rtems_cpu_table *cpu_table,
|
||||
void (*thread_dispatch) /* ignored on this CPU */
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
register unsigned8 *fp_context;
|
||||
unsigned32 iva;
|
||||
unsigned32 iva_table;
|
||||
int i;
|
||||
/*
|
||||
* This is unsupported. For HPPA this function is handled by BSP
|
||||
*/
|
||||
|
||||
extern void IVA_Table(void);
|
||||
|
||||
/*
|
||||
* XXX; need to setup fpsr smarter perhaps
|
||||
*/
|
||||
|
||||
fp_context = (unsigned8*) &_CPU_Null_fp_context;
|
||||
for (i=0 ; i<sizeof(Context_Control_fp); i++)
|
||||
*fp_context++ = 0;
|
||||
|
||||
/*
|
||||
* Set _CPU_Default_gr27 here so it will hopefully be the correct
|
||||
* global data pointer for the entire system.
|
||||
*/
|
||||
|
||||
asm volatile( "stw %%r27,%0" : "=m" (_CPU_Default_gr27): );
|
||||
|
||||
/*
|
||||
* Init the first level interrupt handlers
|
||||
*/
|
||||
|
||||
for (i=0; i <= HPPA_INTERNAL_INTERRUPTS; i++)
|
||||
HPPA_first_level_interrupt_handler[i] = (unsigned32) _Generic_ISR_Handler;
|
||||
|
||||
/*
|
||||
* Init the 2nd level interrupt handlers
|
||||
*/
|
||||
|
||||
for (i=0; i <= CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
|
||||
_ISR_Vector_table[i] = (ISR_Handler_entry) hppa_cpu_halt;
|
||||
|
||||
/*
|
||||
* Stabilize the interrupt stuff
|
||||
*/
|
||||
|
||||
(void) hppa_external_interrupt_initialize();
|
||||
|
||||
/*
|
||||
* Set the IVA to point to physical address of the IVA_Table
|
||||
*/
|
||||
|
||||
iva_table = (unsigned32) IVA_Table;
|
||||
#if defined(hppa1_1)
|
||||
/*
|
||||
* HACK: (from PA72000 TRM, page 4-19)
|
||||
* "The hardware TLB miss handler will never attempt to service
|
||||
* a non-access TLB miss or a TLB protection violation. It
|
||||
* will only attempt to service TLB accesses that would cause
|
||||
* Trap Numbers 6 (Instruction TLB miss) and 15 (Data TLB miss)."
|
||||
*
|
||||
* The LPA instruction is used to translate a virtual address to
|
||||
* a physical address, however, if the requested virtual address
|
||||
* is not currently resident in the TLB, the hardware TLB miss
|
||||
* handler will NOT insert it. In this situation Trap Number
|
||||
* #17 is invoked (Non-access Data TLB miss fault).
|
||||
*
|
||||
* To work around this, a dummy data access is first performed
|
||||
* to the virtual address prior to the LPA. The dummy access
|
||||
* causes the TLB entry to be inserted (if not already present)
|
||||
* and then the following LPA instruction will not generate
|
||||
* a non-access data TLB miss fault.
|
||||
*
|
||||
* It is unclear whether or not this behaves the same way for
|
||||
* the PA8000.
|
||||
*
|
||||
*/
|
||||
iva = *(volatile unsigned32 *)iva_table; /* dummy access */
|
||||
#endif
|
||||
|
||||
HPPA_ASM_LPA(0, iva_table, iva);
|
||||
set_iva(iva);
|
||||
|
||||
_CPU_Table = *cpu_table;
|
||||
_CPU_Fatal_halt( 0xdeaddead );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This is the default handler which is called if
|
||||
* _CPU_ISR_install_vector() has not been called for the
|
||||
* specified vector. It simply forwards onto the spurious
|
||||
* handler defined in the cpu-table.
|
||||
*/
|
||||
|
||||
static ISR_Handler
|
||||
hppa_interrupt_report_spurious(ISR_Vector_number vector,
|
||||
void* rtems_isr_frame) /* HPPA extension */
|
||||
{
|
||||
|
||||
/*
|
||||
* If the CPU table defines a spurious_handler, then
|
||||
* call it. If the handler returns halt.
|
||||
*/
|
||||
if ( _CPU_Table.spurious_handler )
|
||||
_CPU_Table.spurious_handler(vector, rtems_isr_frame);
|
||||
|
||||
hppa_cpu_halt(vector);
|
||||
}
|
||||
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_Get_level
|
||||
@@ -144,30 +79,12 @@ unsigned32 _CPU_ISR_Get_level(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_raw_handler
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_raw_handler(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
proc_ptr *old_handler
|
||||
)
|
||||
{
|
||||
/*
|
||||
* This is unsupported.
|
||||
*/
|
||||
|
||||
_CPU_Fatal_halt( 0xdeaddead );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CPU_ISR_install_vector
|
||||
*
|
||||
* This kernel routine installs the RTEMS handler for the
|
||||
* specified vector.
|
||||
* specified vector. The handler is a C callable routine.
|
||||
*
|
||||
* Input parameters:
|
||||
* vector - interrupt vector number
|
||||
@@ -178,12 +95,6 @@ void _CPU_ISR_install_raw_handler(
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* HPPA has 8w for each vector instead of an address to jump to.
|
||||
* We put the actual ISR address in '_ISR_vector_table'. This will
|
||||
* be pulled by the code in the vector.
|
||||
*/
|
||||
|
||||
void _CPU_ISR_install_vector(
|
||||
unsigned32 vector,
|
||||
proc_ptr new_handler,
|
||||
@@ -193,156 +104,55 @@ void _CPU_ISR_install_vector(
|
||||
*old_handler = _ISR_Vector_table[vector];
|
||||
|
||||
_ISR_Vector_table[vector] = new_handler;
|
||||
|
||||
if (vector >= HPPA_INTERRUPT_EXTERNAL_BASE)
|
||||
{
|
||||
unsigned32 external_vector;
|
||||
|
||||
external_vector = vector - HPPA_INTERRUPT_EXTERNAL_BASE;
|
||||
if (new_handler)
|
||||
hppa_external_interrupt_enable(external_vector);
|
||||
else
|
||||
/* XXX this can never happen due to _ISR_Is_valid_user_handler */
|
||||
hppa_external_interrupt_disable(external_vector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Support for external and spurious interrupts on HPPA
|
||||
/* _CPU_Initialize
|
||||
*
|
||||
* This routine performs processor dependent initialization.
|
||||
*
|
||||
* INPUT PARAMETERS:
|
||||
* cpu_table - CPU table to initialize
|
||||
* thread_dispatch - address of disptaching routine
|
||||
*
|
||||
* TODO:
|
||||
* Count interrupts
|
||||
* make sure interrupts disabled properly
|
||||
*/
|
||||
|
||||
#define DISMISS(mask) set_eirr(mask)
|
||||
#define DISABLE(mask) set_eiem(get_eiem() & ~(mask))
|
||||
#define ENABLE(mask) set_eiem(get_eiem() | (mask))
|
||||
#define VECTOR_TO_MASK(v) (1 << (31 - (v)))
|
||||
|
||||
/*
|
||||
* Init the external interrupt scheme
|
||||
* called by bsp_start()
|
||||
*/
|
||||
|
||||
void
|
||||
hppa_external_interrupt_initialize(void)
|
||||
void _CPU_Initialize(
|
||||
rtems_cpu_table *cpu_table,
|
||||
void (*thread_dispatch) /* ignored on this CPU */
|
||||
)
|
||||
{
|
||||
proc_ptr ignore;
|
||||
register unsigned8 *fp_context;
|
||||
int i;
|
||||
proc_ptr old_handler;
|
||||
|
||||
/* mark them all unused */
|
||||
DISABLE(~0);
|
||||
DISMISS(~0);
|
||||
/*
|
||||
* XXX; need to setup fpsr smarter perhaps
|
||||
*/
|
||||
|
||||
/* install the external interrupt handler */
|
||||
_CPU_ISR_install_vector(
|
||||
HPPA_INTERRUPT_EXTERNAL_INTERRUPT,
|
||||
(proc_ptr)hppa_external_interrupt, &ignore
|
||||
);
|
||||
fp_context = (unsigned8*) &_CPU_Null_fp_context;
|
||||
for (i=0 ; i<sizeof(Context_Control_fp); i++)
|
||||
*fp_context++ = 0;
|
||||
|
||||
/*
|
||||
* Set _CPU_Default_gr27 here so it will hopefully be the correct
|
||||
* global data pointer for the entire system.
|
||||
*/
|
||||
|
||||
asm volatile( "stw %%r27,%0" : "=m" (_CPU_Default_gr27): );
|
||||
|
||||
/*
|
||||
* Init the 2nd level interrupt handlers
|
||||
*/
|
||||
|
||||
for (i=0; i < CPU_INTERRUPT_NUMBER_OF_VECTORS; i++)
|
||||
_CPU_ISR_install_vector(i,
|
||||
hppa_interrupt_report_spurious,
|
||||
&old_handler);
|
||||
|
||||
_CPU_Table = *cpu_table;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable a specific external interrupt
|
||||
*/
|
||||
|
||||
void
|
||||
hppa_external_interrupt_enable(unsigned32 v)
|
||||
{
|
||||
unsigned32 isrlevel;
|
||||
|
||||
_CPU_ISR_Disable(isrlevel);
|
||||
ENABLE(VECTOR_TO_MASK(v));
|
||||
_CPU_ISR_Enable(isrlevel);
|
||||
}
|
||||
|
||||
/*
|
||||
* Does not clear or otherwise affect any pending requests
|
||||
*/
|
||||
|
||||
void
|
||||
hppa_external_interrupt_disable(unsigned32 v)
|
||||
{
|
||||
unsigned32 isrlevel;
|
||||
|
||||
_CPU_ISR_Disable(isrlevel);
|
||||
DISABLE(VECTOR_TO_MASK(v));
|
||||
_CPU_ISR_Enable(isrlevel);
|
||||
}
|
||||
|
||||
void
|
||||
hppa_external_interrupt_spurious_handler(unsigned32 vector,
|
||||
CPU_Interrupt_frame *iframe)
|
||||
{
|
||||
/* XXX should not be printing :)
|
||||
printf("spurious external interrupt: %d at pc 0x%x; disabling\n",
|
||||
vector, iframe->Interrupt.pcoqfront);
|
||||
*/
|
||||
}
|
||||
|
||||
void
|
||||
hppa_external_interrupt_report_spurious(unsigned32 spurious_mask,
|
||||
CPU_Interrupt_frame *iframe)
|
||||
{
|
||||
int v;
|
||||
for (v=0; v < HPPA_EXTERNAL_INTERRUPTS; v++)
|
||||
if (VECTOR_TO_MASK(v) & spurious_mask)
|
||||
{
|
||||
DISMISS(VECTOR_TO_MASK(v));
|
||||
DISABLE(VECTOR_TO_MASK(v));
|
||||
hppa_external_interrupt_spurious_handler(v, iframe);
|
||||
}
|
||||
DISMISS(spurious_mask);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* External interrupt handler.
|
||||
* This is installed as cpu interrupt handler for
|
||||
* HPPA_INTERRUPT_EXTERNAL_INTERRUPT. It vectors out to
|
||||
* specific external interrupt handlers.
|
||||
*/
|
||||
|
||||
void
|
||||
hppa_external_interrupt(unsigned32 vector,
|
||||
CPU_Interrupt_frame *iframe)
|
||||
{
|
||||
unsigned32 mask;
|
||||
unsigned32 *vp, *max_vp;
|
||||
unsigned32 external_vector;
|
||||
unsigned32 global_vector;
|
||||
hppa_rtems_isr_entry handler;
|
||||
|
||||
max_vp = &_CPU_Table.external_interrupt[_CPU_Table.external_interrupts];
|
||||
while ( (mask = (get_eirr() & get_eiem())) )
|
||||
{
|
||||
for (vp = _CPU_Table.external_interrupt; (vp < max_vp) && mask; vp++)
|
||||
{
|
||||
unsigned32 m;
|
||||
|
||||
external_vector = *vp;
|
||||
global_vector = external_vector + HPPA_INTERRUPT_EXTERNAL_BASE;
|
||||
m = VECTOR_TO_MASK(external_vector);
|
||||
handler = (hppa_rtems_isr_entry) _ISR_Vector_table[global_vector];
|
||||
if ((m & mask) && handler)
|
||||
{
|
||||
DISMISS(m);
|
||||
mask &= ~m;
|
||||
handler(global_vector, iframe);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask != 0) {
|
||||
if ( _CPU_Table.spurious_handler )
|
||||
{
|
||||
handler = (hppa_rtems_isr_entry) _CPU_Table.spurious_handler;
|
||||
handler(mask, iframe);
|
||||
}
|
||||
else
|
||||
hppa_external_interrupt_report_spurious(mask, iframe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Halt the system.
|
||||
@@ -351,8 +161,17 @@ hppa_external_interrupt(unsigned32 vector,
|
||||
* XXX
|
||||
* Later on, this will allow us to return to the prom.
|
||||
* For now, we just ignore 'type_of_halt'
|
||||
*
|
||||
* XXX
|
||||
* NOTE: for gcc, this function must be at the bottom
|
||||
* of the file, that is because if it is at the top
|
||||
* of the file, gcc will inline it's calls. Since
|
||||
* the function uses the HPPA_ASM_LABEL() macro, when
|
||||
* gcc inlines it, you get two definitions of the same
|
||||
* label name, which is an assembly error.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
hppa_cpu_halt(unsigned32 the_error)
|
||||
{
|
||||
@@ -360,6 +179,11 @@ hppa_cpu_halt(unsigned32 the_error)
|
||||
|
||||
_CPU_ISR_Disable(isrlevel);
|
||||
|
||||
/*
|
||||
* XXXXX NOTE: This label is only needed that that when
|
||||
* the simulator stops, it shows the label name specified
|
||||
*/
|
||||
HPPA_ASM_LABEL("_hppa_cpu_halt");
|
||||
HPPA_ASM_BREAK(1, 0);
|
||||
HPPA_ASM_BREAK(0, 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user