mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-08-14 05:42:59 +02:00
Additional I/O interrupt cleanup; only wakeup a waiting CPU if enabled for I/O interrupts.
This commit is contained in:
@@ -322,7 +322,11 @@ scsw_clear_ac_Nr (SCSW* scsw)
|
||||
static INLINE void
|
||||
scsw_clear_sc_Cs (SCSW* scsw)
|
||||
{
|
||||
scsw->flag3 &= ~SCSW3_SC_PEND;
|
||||
scsw->flag3 &= ~(SCSW3_SC_ALERT |
|
||||
SCSW3_SC_INTER |
|
||||
SCSW3_SC_PRI |
|
||||
SCSW3_SC_SEC |
|
||||
SCSW3_SC_PEND);
|
||||
}
|
||||
|
||||
|
||||
@@ -3775,13 +3779,13 @@ int rc; /* Return code */
|
||||
|
||||
/* Initialize the subchannel status word */
|
||||
memset (&dev->scsw, 0, sizeof(SCSW));
|
||||
dev->scsw.flag0 = (orb->flag4 & SCSW0_KEY); /*@IWZ*/
|
||||
if (orb->flag4 & ORB4_S) dev->scsw.flag0 |= SCSW0_S; /*@IWZ*/
|
||||
if (orb->flag5 & ORB5_F) dev->scsw.flag1 |= SCSW1_F; /*@IWZ*/
|
||||
if (orb->flag5 & ORB5_P) dev->scsw.flag1 |= SCSW1_P; /*@IWZ*/
|
||||
if (orb->flag5 & ORB5_I) dev->scsw.flag1 |= SCSW1_I; /*@IWZ*/
|
||||
if (orb->flag5 & ORB5_A) dev->scsw.flag1 |= SCSW1_A; /*@IWZ*/
|
||||
if (orb->flag5 & ORB5_U) dev->scsw.flag1 |= SCSW1_U; /*@IWZ*/
|
||||
dev->scsw.flag0 = (orb->flag4 & (SCSW0_KEY |
|
||||
SCSW0_S));
|
||||
dev->scsw.flag1 = (orb->flag5 & (SCSW1_F |
|
||||
SCSW1_P |
|
||||
SCSW1_I |
|
||||
SCSW1_A |
|
||||
SCSW1_U));
|
||||
|
||||
/* Set the device busy indicator */
|
||||
set_subchannel_busy(dev);
|
||||
@@ -5538,7 +5542,38 @@ retry:
|
||||
}
|
||||
|
||||
/* See if another CPU can take this interrupt */
|
||||
WAKEUP_CPU_MASK (sysblk.waiting_mask);
|
||||
{
|
||||
REGS *regs;
|
||||
CPU_BITMAP mask = sysblk.waiting_mask;
|
||||
CPU_BITMAP wake;
|
||||
int i;
|
||||
|
||||
/* If any CPUs are waiting, isolate to subgroup enabled for
|
||||
* I/O interrupts.
|
||||
*/
|
||||
if (mask)
|
||||
{
|
||||
wake = mask;
|
||||
|
||||
/* Turn off wake mask bits for waiting CPUs that aren't
|
||||
* enabled for I/O interrupts.
|
||||
*/
|
||||
for (i = 0; mask; mask >>= 1, ++i)
|
||||
{
|
||||
if (mask & 1)
|
||||
{
|
||||
regs = sysblk.regs[i];
|
||||
if (!OPEN_IC_IOPENDING(regs))
|
||||
wake ^= regs->cpubit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wakeup the LRU waiting CPU enabled for I/O
|
||||
* interrupts.
|
||||
*/
|
||||
WAKEUP_CPU_MASK(wake);
|
||||
}
|
||||
}
|
||||
|
||||
} /* end for(io) */
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
Interrupts_State & Interrupts_Mask bits definition (Initial_Mask=800E)
|
||||
Machine check, PER and external interrupt subclass bit positions
|
||||
are fixed by the architecture and cannot be changed
|
||||
Floating interrupts are made pending to all CPUs, and are
|
||||
Floating interrupts are made pending to all CPUs, and are
|
||||
recorded in the sysblk structure, CPU specific interrupts
|
||||
are recorded in the regs structure.
|
||||
hi0m mmmm pppp p00p xxxx xxxx xxxx h0hs : type U32
|
||||
@@ -25,22 +25,22 @@
|
||||
|| | |||| |||| | | |||| ||+-------------> '1' : SERVSIG
|
||||
|| | |||| |||| | | |||| |+--------------> '1' : PTIMER
|
||||
|| | |||| |||| | | |||| +---------------> '1' : CLKC
|
||||
|| | |||| |||| | | ||||
|
||||
|| | |||| |||| | | ||||
|
||||
|| | |||| |||| | | |||+-----------------> '1' : TODSYNC
|
||||
|| | |||| |||| | | ||+------------------> '1' : EXTCALL
|
||||
|| | |||| |||| | | |+-------------------> '1' : EMERSIG
|
||||
|| | |||| |||| | | +--------------------> '1' : MALFALT
|
||||
|| | |||| |||| | |
|
||||
|| | |||| |||| | +----------------------> '1' : PER IFNUL
|
||||
|| | |||| |||| |
|
||||
|| | |||| |||| |
|
||||
|| | |||| |||| |
|
||||
|| | |||| |||| |
|
||||
|| | |||| |||| +-------------------------> '1' : PER STURA
|
||||
|| | |||| ||||
|
||||
|| | |||| ||||
|
||||
|| | |||| |||+---------------------------> '1' : PER GRA
|
||||
|| | |||| ||+----------------------------> '1' : PER SA
|
||||
|| | |||| |+-----------------------------> '1' : PER IF
|
||||
|| | |||| +------------------------------> '1' : PER SB
|
||||
|| | ||||
|
||||
|| | ||||
|
||||
|| | |||+--------------------------------> '1' : WARNING
|
||||
|| | ||+---------------------------------> '1' : XDMGRPT
|
||||
|| | |+----------------------------------> '1' : DGRDRPT
|
||||
@@ -138,7 +138,7 @@
|
||||
|
||||
/* External interrupt subclasses */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Adds ECPS:VM Vtimer which has no individual
|
||||
* subclass mask in CR0
|
||||
*/
|
||||
@@ -311,19 +311,27 @@
|
||||
|
||||
#define ON_IC_IOPENDING \
|
||||
do { \
|
||||
int i; CPU_BITMAP mask; \
|
||||
if ( !(sysblk.ints_state & BIT(IC_IO)) ) { \
|
||||
REGS *regs; \
|
||||
CPU_BITMAP mask = sysblk.started_mask; \
|
||||
CPU_BITMAP wake; \
|
||||
int i; \
|
||||
if ( !(sysblk.ints_state & BIT(IC_IO)) ) \
|
||||
{ \
|
||||
sysblk.ints_state |= BIT(IC_IO); \
|
||||
mask = sysblk.started_mask; \
|
||||
for (i = 0; mask; i++) { \
|
||||
if (mask & 1) { \
|
||||
if ( sysblk.regs[i]->ints_mask & BIT(IC_IO) ) \
|
||||
sysblk.regs[i]->ints_state |= BIT(IC_INTERRUPT) | BIT(IC_IO); \
|
||||
wake = mask; \
|
||||
for (i = 0; mask; mask >>= 1, ++i) \
|
||||
{ \
|
||||
if (mask & 1) \
|
||||
{ \
|
||||
regs = sysblk.regs[i]; \
|
||||
if ( regs->ints_mask & BIT(IC_IO) ) \
|
||||
regs->ints_state |= BIT(IC_INTERRUPT) | BIT(IC_IO); \
|
||||
else \
|
||||
sysblk.regs[i]->ints_state |= BIT(IC_IO); \
|
||||
regs->ints_state |= BIT(IC_IO), \
|
||||
wake ^= regs->cpubit; \
|
||||
} \
|
||||
mask >>= 1; \
|
||||
} \
|
||||
WAKEUP_CPU_MASK(wake); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user