aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2003-08-04 00:08:39 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2003-08-04 00:08:39 +0000
commit5192a6fc074a1b172d47210a74fd78a3463f96aa (patch)
tree84535f5c21edb1dc060917dc5f7c76dcbcf370b6 /sys
parentd7da7302f930a602753bd9f23f88c89458bb922e (diff)
downloadsrc-5192a6fc074a1b172d47210a74fd78a3463f96aa.tar.gz
src-5192a6fc074a1b172d47210a74fd78a3463f96aa.zip
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
Notes
Notes: svn path=/head/; revision=118402
Diffstat (limited to 'sys')
-rw-r--r--sys/ia64/ia64/exception.S63
-rw-r--r--sys/ia64/ia64/genassym.c2
2 files changed, 51 insertions, 14 deletions
diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S
index 795ec93e70af..feffb65db0ae 100644
--- a/sys/ia64/ia64/exception.S
+++ b/sys/ia64/ia64/exception.S
@@ -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
- add out1=16,sp
- nop 0
-}
-
-3: mov out0=cr.ivr // find interrupt vector
+ alloc r14=ar.pfs,0,0,2,0
;;
- cmp.eq p15,p0=15,out0 // check for spurious vector number
-(p15) br.dpnt.few exception_restore // if spurious, we are done
+1:
+{ .mii
+ mov out0=cr.ivr // Get interrupt vector
+ add out1=16,sp
;;
- ssm psr.i // re-enable interrupts
+ cmp.eq p15,p0=15,out0 // check for spurious vector number
+}
+{ .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
;;
- rsm psr.i // disable interrupts
+}
+{ .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)
diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c
index 302c44173e9d..0c0ec8160625 100644
--- a/sys/ia64/ia64/genassym.c
+++ b/sys/ia64/ia64/genassym.c
@@ -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));