1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-17 10:26:15 +00:00

Adapt the vectored interrupt handler for receiving ipis. If the second

data word in an interrupt packet is non-zero, it points to code to execute
to handle the ipi, so jump to it instead of enqueueing the packet.  It
is unclear if we will need queued ipis.
Interrupt g7 now points to pcpu, instead of to the per-cpu interrupt queue
itself, so use that instead.  Interrupt g6 is no longer reserved.
This commit is contained in:
Jake Burkholder 2002-01-08 05:27:13 +00:00
parent 91b9d75edc
commit 81f295da38
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=89049
2 changed files with 110 additions and 98 deletions

View File

@ -1195,31 +1195,6 @@ END(tl1_sfsr_trap)
.endm
ENTRY(intr_enqueue)
/*
* Find the head of the queue and advance it.
*/
ldx [IQ_REG + IQ_HEAD], %g1
add %g1, 1, %g2
and %g2, IQ_MASK, %g2
stx %g2, [IQ_REG + IQ_HEAD]
#ifdef INVARIANTS
/*
* If the new head is the same as the tail, the next interrupt will
* overwrite unserviced packets. This is bad.
*/
ldx [IQ_REG + IQ_TAIL], %g3
cmp %g3, %g2
be %xcc, 3f
nop
#endif
/*
* Find the iqe.
*/
sllx %g1, IQE_SHIFT, %g1
add %g1, IQ_REG, %g1
/*
* Load the interrupt packet from the hardware.
*/
@ -1231,6 +1206,30 @@ ENTRY(intr_enqueue)
stxa %g0, [%g0] ASI_INTR_RECEIVE
membar #Sync
/*
* If the second data word is present it points to code to execute
* directly. Jump to it.
*/
brz,a,pt %g4, 1f
nop
jmpl %g4, %g0
nop
/*
* Find the head of the queue and advance it.
*/
1: ldx [PCPU(IQ) + IQ_HEAD], %g1
add %g1, 1, %g6
and %g6, IQ_MASK, %g6
stx %g6, [PCPU(IQ) + IQ_HEAD]
/*
* Find the iqe.
*/
sllx %g1, IQE_SHIFT, %g1
add %g1, PCPU_REG, %g1
add %g1, PC_IQ, %g1
/*
* Store the tag and first data word in the iqe. These are always
* valid.
@ -1238,45 +1237,52 @@ ENTRY(intr_enqueue)
stw %g2, [%g1 + IQE_TAG]
stx %g3, [%g1 + IQE_VEC]
#ifdef INVARIANTS
/*
* Load the function and argument, if not supplied in iqe.
* If the new head is the same as the tail, the next interrupt will
* overwrite unserviced packets. This is bad.
*/
sllx %g3, IV_SHIFT, %g3
brnz,pn %g4, 1f
add %g3, IV_REG, %g3
ldx [%g3 + IV_FUNC], %g4
ldx [%g3 + IV_ARG], %g5
ldx [PCPU(IQ) + IQ_TAIL], %g2
cmp %g2, %g6
be %xcc, 2f
nop
#endif
/*
* Save the priority and the two remaining data words in the iqe.
* Load the function, argument and priority and store them in the iqe.
*/
1: lduw [%g3 + IV_PRI], %g3
stw %g3, [%g1 + IQE_PRI]
sllx %g3, IV_SHIFT, %g3
SET(intr_vectors, %g6, %g2)
add %g2, %g3, %g2
ldx [%g2 + IV_FUNC], %g4
ldx [%g2 + IV_ARG], %g5
lduw [%g2 + IV_PRI], %g6
stx %g4, [%g1 + IQE_FUNC]
stx %g5, [%g1 + IQE_ARG]
stw %g6, [%g1 + IQE_PRI]
#if KTR_COMPILE & KTR_INTR
CATR(KTR_INTR, "intr_enqueue: head=%d tail=%d pri=%p tag=%#x vec=%#x"
, %g2, %g4, %g5, 7, 8, 9)
ldx [IQ_REG + IQ_HEAD], %g4
stx %g4, [%g2 + KTR_PARM1]
ldx [IQ_REG + IQ_TAIL], %g4
stx %g4, [%g2 + KTR_PARM2]
lduw [%g1 + IQE_PRI], %g4
stx %g4, [%g2 + KTR_PARM3]
lduw [%g1 + IQE_TAG], %g4
stx %g4, [%g2 + KTR_PARM4]
ldx [%g1 + IQE_VEC], %g4
stx %g4, [%g2 + KTR_PARM5]
, %g2, %g3, %g4, 7, 8, 9)
ldx [PCPU(IQ) + IQ_HEAD], %g3
stx %g3, [%g2 + KTR_PARM1]
ldx [PCPU(IQ) + IQ_TAIL], %g3
stx %g3, [%g2 + KTR_PARM2]
lduw [%g1 + IQE_PRI], %g3
stx %g3, [%g2 + KTR_PARM3]
lduw [%g1 + IQE_TAG], %g3
stx %g3, [%g2 + KTR_PARM4]
ldx [%g1 + IQE_VEC], %g3
stx %g3, [%g2 + KTR_PARM5]
9:
#endif
/*
* Trigger a softint at the level indicated by the priority.
*/
mov 1, %g2
sllx %g2, %g3, %g2
wr %g2, 0, %asr20
mov 1, %g1
sllx %g1, %g6, %g1
wr %g1, 0, %asr20
retry
@ -1284,7 +1290,7 @@ ENTRY(intr_enqueue)
/*
* The interrupt queue is about to overflow. We are in big trouble.
*/
3: sir
2: sir
#endif
END(intr_enqueue)

View File

@ -1195,31 +1195,6 @@ END(tl1_sfsr_trap)
.endm
ENTRY(intr_enqueue)
/*
* Find the head of the queue and advance it.
*/
ldx [IQ_REG + IQ_HEAD], %g1
add %g1, 1, %g2
and %g2, IQ_MASK, %g2
stx %g2, [IQ_REG + IQ_HEAD]
#ifdef INVARIANTS
/*
* If the new head is the same as the tail, the next interrupt will
* overwrite unserviced packets. This is bad.
*/
ldx [IQ_REG + IQ_TAIL], %g3
cmp %g3, %g2
be %xcc, 3f
nop
#endif
/*
* Find the iqe.
*/
sllx %g1, IQE_SHIFT, %g1
add %g1, IQ_REG, %g1
/*
* Load the interrupt packet from the hardware.
*/
@ -1231,6 +1206,30 @@ ENTRY(intr_enqueue)
stxa %g0, [%g0] ASI_INTR_RECEIVE
membar #Sync
/*
* If the second data word is present it points to code to execute
* directly. Jump to it.
*/
brz,a,pt %g4, 1f
nop
jmpl %g4, %g0
nop
/*
* Find the head of the queue and advance it.
*/
1: ldx [PCPU(IQ) + IQ_HEAD], %g1
add %g1, 1, %g6
and %g6, IQ_MASK, %g6
stx %g6, [PCPU(IQ) + IQ_HEAD]
/*
* Find the iqe.
*/
sllx %g1, IQE_SHIFT, %g1
add %g1, PCPU_REG, %g1
add %g1, PC_IQ, %g1
/*
* Store the tag and first data word in the iqe. These are always
* valid.
@ -1238,45 +1237,52 @@ ENTRY(intr_enqueue)
stw %g2, [%g1 + IQE_TAG]
stx %g3, [%g1 + IQE_VEC]
#ifdef INVARIANTS
/*
* Load the function and argument, if not supplied in iqe.
* If the new head is the same as the tail, the next interrupt will
* overwrite unserviced packets. This is bad.
*/
sllx %g3, IV_SHIFT, %g3
brnz,pn %g4, 1f
add %g3, IV_REG, %g3
ldx [%g3 + IV_FUNC], %g4
ldx [%g3 + IV_ARG], %g5
ldx [PCPU(IQ) + IQ_TAIL], %g2
cmp %g2, %g6
be %xcc, 2f
nop
#endif
/*
* Save the priority and the two remaining data words in the iqe.
* Load the function, argument and priority and store them in the iqe.
*/
1: lduw [%g3 + IV_PRI], %g3
stw %g3, [%g1 + IQE_PRI]
sllx %g3, IV_SHIFT, %g3
SET(intr_vectors, %g6, %g2)
add %g2, %g3, %g2
ldx [%g2 + IV_FUNC], %g4
ldx [%g2 + IV_ARG], %g5
lduw [%g2 + IV_PRI], %g6
stx %g4, [%g1 + IQE_FUNC]
stx %g5, [%g1 + IQE_ARG]
stw %g6, [%g1 + IQE_PRI]
#if KTR_COMPILE & KTR_INTR
CATR(KTR_INTR, "intr_enqueue: head=%d tail=%d pri=%p tag=%#x vec=%#x"
, %g2, %g4, %g5, 7, 8, 9)
ldx [IQ_REG + IQ_HEAD], %g4
stx %g4, [%g2 + KTR_PARM1]
ldx [IQ_REG + IQ_TAIL], %g4
stx %g4, [%g2 + KTR_PARM2]
lduw [%g1 + IQE_PRI], %g4
stx %g4, [%g2 + KTR_PARM3]
lduw [%g1 + IQE_TAG], %g4
stx %g4, [%g2 + KTR_PARM4]
ldx [%g1 + IQE_VEC], %g4
stx %g4, [%g2 + KTR_PARM5]
, %g2, %g3, %g4, 7, 8, 9)
ldx [PCPU(IQ) + IQ_HEAD], %g3
stx %g3, [%g2 + KTR_PARM1]
ldx [PCPU(IQ) + IQ_TAIL], %g3
stx %g3, [%g2 + KTR_PARM2]
lduw [%g1 + IQE_PRI], %g3
stx %g3, [%g2 + KTR_PARM3]
lduw [%g1 + IQE_TAG], %g3
stx %g3, [%g2 + KTR_PARM4]
ldx [%g1 + IQE_VEC], %g3
stx %g3, [%g2 + KTR_PARM5]
9:
#endif
/*
* Trigger a softint at the level indicated by the priority.
*/
mov 1, %g2
sllx %g2, %g3, %g2
wr %g2, 0, %asr20
mov 1, %g1
sllx %g1, %g6, %g1
wr %g1, 0, %asr20
retry
@ -1284,7 +1290,7 @@ ENTRY(intr_enqueue)
/*
* The interrupt queue is about to overflow. We are in big trouble.
*/
3: sir
2: sir
#endif
END(intr_enqueue)