Fix handling of external interrupts: we weren't calling ast() when

interrupting user mode. The net effect of this bug is that a clock
interrupt does not cause rescheduling and processes are not
preempted. It only takes a "while (1);" to render the machine
useless.

This bug was introduced by the context changes and EPC syscall code.
Handling of ASTs was moved to C for clarity and ease of maintenance,
but was not added for the external interrupt case.

This needs to be revisited. We now have calls to do_ast() in trap(),
break_syscall() and ivt_External_Interrupt(). A single call in
exception_restore covers these 3 places without duplication. This
is where we handled ASTs prior to the overhaul, except that the
meat has been moved to do_ast(), a C function. This was the goal
to begin with.

Pointy hat: marcel
This commit is contained in:
marcel 2003-08-04 00:08:39 +00:00
parent 69229c2af6
commit 3704dfdebb
2 changed files with 52 additions and 15 deletions

View File

@ -1150,28 +1150,65 @@ IVT_ENTRY(External_Interrupt, 0x3000)
br.sptk exception_save
;;
}
{ .mmb
2: alloc r14=ar.pfs,0,0,2,0 // make a frame for calling with
alloc r14=ar.pfs,0,0,2,0
;;
1:
{ .mii
mov out0=cr.ivr // Get interrupt vector
add out1=16,sp
nop 0
}
3: mov out0=cr.ivr // find interrupt vector
;;
cmp.eq p15,p0=15,out0 // check for spurious vector number
(p15) br.dpnt.few exception_restore // if spurious, we are done
;;
}
{ .mbb
ssm psr.i // re-enable interrupts
(p15) br.dpnt.few 2f // if spurious, we are done
br.call.sptk.many rp=interrupt // call high-level handler
;;
}
{ .mmi
rsm psr.i // disable interrupts
;;
srlz.d
mov cr.eoi=r0 // and ack the interrupt
nop 0
}
{ .mmi
mov cr.eoi=r0 // ack the interrupt
;;
srlz.d
br.sptk.few 3b // loop for more
nop 0
}
{ .mfb
nop 0
nop 0
br.sptk 1b // loop for more
;;
}
2:
{ .mmi
add r14=16+TF_SPECIAL_IIP,sp
;;
ld8 r14=[r14]
add out0=16,sp
;;
}
{ .mii
nop 0
extr.u r14=r14,61,3
;;
cmp.ge p15,p0=5,r14
}
{ .mfb
nop 0
nop 0
(p15) br.call.sptk rp=do_ast
;;
}
{ .mfb
nop 0
nop 0
br.sptk exception_restore
;;
}
IVT_END(External_Interrupt)
IVT_ENTRY(Reserved_3400, 0x3400)

View File

@ -112,7 +112,7 @@ ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
ASSYM(TF_SPECIAL_NDIRTY, offsetof(struct trapframe, tf_special.ndirty));
ASSYM(TF_SPECIAL_IIP, offsetof(struct trapframe, tf_special.iip));
ASSYM(UC_MCONTEXT, offsetof(ucontext_t, uc_mcontext));