Enable/Restore alignment fault state on interrupt handler entry/exit.

This commit is contained in:
scw 2003-11-05 21:10:59 +00:00
parent aad37eaff6
commit f77bf2bb0c
4 changed files with 23 additions and 200 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: iomd_irq.S,v 1.3 2002/10/14 22:32:51 bjh21 Exp $ */
/* $NetBSD: iomd_irq.S,v 1.4 2003/11/05 21:10:59 scw Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
@ -96,6 +96,8 @@ Lcurrent_intr_depth:
Lspl_masks:
.word _C_LABEL(spl_masks)
AST_ALIGNMENT_FAULT_LOCALS
/*
* Register usage
*
@ -117,6 +119,7 @@ ASENTRY_NP(irq_entry)
sub lr, lr, #0x00000004 /* Adjust the lr */
PUSHFRAMEINSVC /* Push an interrupt frame */
ENABLE_ALIGNMENT_FAULTS
/* Load r8 with the IOMD interrupt requests */
@ -323,17 +326,6 @@ exitirq:
bl _C_LABEL(dosoftints) /* Handle the soft interrupts */
/* Manage AST's. Maybe this should be done as a soft interrupt ? */
ldr r0, [sp] /* Get the SPSR from stack */
and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */
teq r0, #(PSR_USR32_MODE)
ldreq r0, Lastpending /* Do we have an AST pending ? */
ldreq r1, [r0]
teqeq r1, #0x00000001
beq irqast /* call the AST handler */
/* Kill IRQ's in preparation for exit */
mrs r0, cpsr_all
orr r0, r0, #(I32_bit)
@ -345,51 +337,12 @@ exitirq:
sub r1, r1, #1
str r1, [r0]
DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
PULLFRAMEFROMSVCANDEXIT
/* NOT REACHED */
b . - 8
/*
* Ok, snag with current intr depth ...
* If ast() calls mi_sleep() the current_intr_depth will not be
* decremented until the process is woken up. This can result
* in the system believing it is still in the interrupt handler.
* If we are calling ast() then correct the current_intr_depth
* before the call.
*/
irqast:
mov r1, #0x00000000 /* Clear ast_pending */
str r1, [r0]
/* Kill IRQ's so we atomically decrement current_intr_depth */
mrs r2, cpsr_all
orr r3, r2, #(I32_bit)
msr cpsr_all, r3
/* Decrement the interrupt nesting count */
ldr r0, Lcurrent_intr_depth
ldr r1, [r0]
sub r1, r1, #1
str r1, [r0]
/* Restore IRQ's */
msr cpsr_all, r2
mov r0, sp
bl _C_LABEL(ast)
/* Kill IRQ's in preparation for exit */
mrs r0, cpsr_all
orr r0, r0, #(I32_bit)
msr cpsr_all, r0
PULLFRAMEFROMSVCANDEXIT
/* NOT REACHED */
b . - 8
Lspl_mask:
.word _C_LABEL(spl_mask) /* irq's allowed at current spl level */
@ -454,9 +407,6 @@ Lintrcnt:
Lirqhandlers:
.word _C_LABEL(irqhandlers) /* Pointer to array of irqhandlers */
Lastpending:
.word _C_LABEL(astpending)
#ifdef IRQSTATS
/* These symbols are used by vmstat */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ofw_irq.S,v 1.2 2002/10/14 22:32:52 bjh21 Exp $ */
/* $NetBSD: ofw_irq.S,v 1.3 2003/11/05 21:10:59 scw Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
@ -95,6 +95,8 @@ Lirq_entry:
Lofwirqstk: /* hack */
.word ofwirqstk + 4096
AST_ALIGNMENT_FAULT_LOCALS
/*
* Regsister usage
*
@ -187,6 +189,11 @@ ASENTRY_NP(irq_entry)
* which follows it.
*/
ofwtakeint:
#if defined(COMPAT_15) && defined(EXEC_AOUT)
ldr r0, [sp] /* Fetch SPSR */
#endif
ENABLE_ALIGNMENT_FAULTS
mov r8, #0x00000001 /* timer interrupt pending! */
mov r8, r8, lsl #IRQ_TIMER0
@ -317,17 +324,6 @@ nextirq:
bl _C_LABEL(dosoftints) /* Handle the soft interrupts */
/* Manage AST's. Maybe this should be done as a soft interrupt ? */
ldr r0, [sp] /* Get the SPSR from stack */
and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */
teq r0, #(PSR_USR32_MODE)
ldreq r0, Lastpending /* Do we have an AST pending ? */
ldreq r1, [r0]
teqeq r1, #0x00000001
beq irqast /* call the AST handler */
/* Kill IRQ's in preparation for exit */
mrs r0, cpsr_all
orr r0, r0, #(I32_bit)
@ -339,52 +335,10 @@ nextirq:
sub r1, r1, #1
str r1, [r0]
DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
PULLFRAMEFROMSVCANDEXIT
movs pc, lr /* Exit */
/*
* Ok, snag with current intr depth ...
* If ast() calls mi_sleep() the current_intr_depth will not be
* decremented until the process is woken up. This can result
* in the system believing it is still in the interrupt handler.
* If we are calling ast() then correct the current_intr_depth
* before the call.
*/
irqast:
mov r1, #0x00000000 /* Clear ast_pending */
str r1, [r0]
/* Kill IRQ's so we atomically decrement current_intr_depth */
mrs r2, cpsr_all
orr r3, r2, #(I32_bit)
msr cpsr_all, r3
/* Decrement the nest count */
ldr r0, Lcurrent_intr_depth
ldr r1, [r0]
sub r1, r1, #1
str r1, [r0]
/* Restore IRQ's */
msr cpsr_all, r2
mov r0, sp
bl _C_LABEL(ast)
/* Kill IRQ's in preparation for exit */
mrs r0, cpsr_all
orr r0, r0, #(I32_bit)
msr cpsr_all, r0
PULLFRAMEFROMSVCANDEXIT
movs pc, lr /* Exit */
Lspl_mask:
.word _C_LABEL(spl_mask) /* irq's allowed at current spl level */
@ -407,9 +361,6 @@ Lintrcnt:
Lirqhandlers:
.word _C_LABEL(irqhandlers) /* Pointer to array of irqhandlers */
Lastpending:
.word _C_LABEL(astpending)
.text
.global _C_LABEL(dotickgrovelling)

View File

@ -1,4 +1,4 @@
/* $NetBSD: sa11x0_irq.S,v 1.5 2003/03/31 19:52:35 chris Exp $ */
/* $NetBSD: sa11x0_irq.S,v 1.6 2003/11/05 21:10:59 scw Exp $ */
/*
* Copyright (c) 1998 Mark Brinicombe.
@ -67,6 +67,8 @@ Ldbg_str:
.asciz "irq_entry %x %x\n"
#endif
AST_ALIGNMENT_FAULT_LOCALS
/*
* Regsister usage
*
@ -81,6 +83,7 @@ ASENTRY_NP(irq_entry)
sub lr, lr, #0x00000004 /* Adjust the lr */
PUSHFRAMEINSVC /* Push an interrupt frame */
ENABLE_ALIGNMENT_FAULTS
/* Load r8 with the SAIPIC interrupt requests */
@ -223,17 +226,6 @@ nextirq:
bl _C_LABEL(dosoftints) /* Handle the soft interrupts */
/* Manage AST's. Maybe this should be done as a soft interrupt ? */
ldr r0, [sp] /* Get the SPSR from stack */
and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */
teq r0, #(PSR_USR32_MODE)
ldreq r0, Lastpending /* Do we have an AST pending ? */
ldreq r1, [r0]
teqeq r1, #0x00000001
beq irqast /* call the AST handler */
/* Kill IRQ's in preparation for exit */
mrs r0, cpsr_all
orr r0, r0, #(I32_bit)
@ -252,51 +244,12 @@ nextirq:
sub r1, r1, #1
str r1, [r0]
DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
PULLFRAMEFROMSVCANDEXIT
/* NOT REACHED */
b . - 8
/*
* Ok, snag with current intr depth ...
* If ast() calls mi_sleep() the current_intr_depth will not be
* decremented until the process is woken up. This can result
* in the system believing it is still in the interrupt handler.
* If we are calling ast() then correct the current_intr_depth
* before the call.
*/
irqast:
mov r1, #0x00000000 /* Clear ast_pending */
str r1, [r0]
/* Kill IRQ's so we atomically decrement current_intr_depth */
mrs r2, cpsr_all
orr r3, r2, #(I32_bit)
msr cpsr_all, r3
/* Decrement the interrupt nesting count */
ldr r0, Lcurrent_intr_depth
ldr r1, [r0]
sub r1, r1, #1
str r1, [r0]
/* Restore IRQ's */
msr cpsr_all, r2
mov r0, sp
bl _C_LABEL(ast)
/* Kill IRQ's in preparation for exit */
mrs r0, cpsr_all
orr r0, r0, #(I32_bit)
msr cpsr_all, r0
PULLFRAMEFROMSVCANDEXIT
/* NOT REACHED */
b . - 8
ENTRY(irq_setmasks)
/* Disable interrupts */
mrs r3, cpsr_all
@ -327,10 +280,6 @@ Lintrcnt:
Lirqhandlers:
.word _C_LABEL(irqhandlers) /* Pointer to array of irqhandlers */
Lastpending:
.word _C_LABEL(astpending)
#ifdef IRQSTATS
.global _C_LABEL(intrnames), _C_LABEL(eintrnames)

View File

@ -1,4 +1,4 @@
/* $NetBSD: i80200_irq.S,v 1.10 2003/01/02 23:54:41 thorpej Exp $ */
/* $NetBSD: i80200_irq.S,v 1.11 2003/11/05 21:10:59 scw Exp $ */
/*
* Copyright (c) 2002 Wasabi Systems, Inc.
@ -65,13 +65,13 @@
.word _C_LABEL(xscale_pmc_dispatch)
#endif
.Lastpending:
.word _C_LABEL(astpending)
AST_ALIGNMENT_FAULT_LOCALS
ASENTRY_NP(irq_entry)
sub lr, lr, #0x00000004 /* Adjust the lr */
PUSHFRAMEINSVC /* Push an interrupt frame */
ENABLE_ALIGNMENT_FAULTS
/*
* Note that we have entered the IRQ handler. We are
@ -128,34 +128,7 @@ ASENTRY_NP(irq_entry)
sub r1, r1, #1
str r1, [r0]
/*
* If we're returning to user mode, check for pending ASTs.
*/
ldr r0, [sp] /* Get the SPSR from stack */
and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */
teq r0, #(PSR_USR32_MODE)
bne .Lirqout /* Nope, get out now */
.Lastloop:
ldr r0, .Lastpending /* Do we have an AST pending? */
ldr r1, [r0]
teq r1, #0x00000000
beq .Lirqout /* Nope, get out now */
mov r1, #0x00000000
str r1, [r0] /* Clear astpending */
mrs r4, cpsr /* save CPSR */
bic r0, r4, #(I32_bit) /* Enable IRQs */
msr cpsr_c, r0
mov r0, sp
bl _C_LABEL(ast) /* ast(frame) */
msr cpsr_c, r4 /* Disable IRQs */
b .Lastloop /* Check for more ASTs */
.Lirqout:
DO_AST_AND_RESTORE_ALIGNMENT_FAULTS
PULLFRAMEFROMSVCANDEXIT
movs pc, lr /* Exit */