summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-08-04 00:08:39 +0000
committermarcel <marcel@FreeBSD.org>2003-08-04 00:08:39 +0000
commit47e1af7da85f4a66bb2b605035aedf62a1eaaa2b (patch)
tree84535f5c21edb1dc060917dc5f7c76dcbcf370b6 /sys
parenta506e844d169350a3ac4998c79b3c441fd5ef7bd (diff)
downloadFreeBSD-src-47e1af7da85f4a66bb2b605035aedf62a1eaaa2b.zip
FreeBSD-src-47e1af7da85f4a66bb2b605035aedf62a1eaaa2b.tar.gz
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
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 795ec93..feffb65 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 302c441..0c0ec81 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));
OpenPOWER on IntegriCloud