summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-09-25 04:27:44 +0000
committermarcel <marcel@FreeBSD.org>2004-09-25 04:27:44 +0000
commit883da4df6b30c6a6a1889e38615386b37af594de (patch)
tree8de6820f7af882f731e1d689d5d242fb96cc1bc7 /sys/ia64
parent954ae57b986db4b14140e76aebb189c88e5634d8 (diff)
downloadFreeBSD-src-883da4df6b30c6a6a1889e38615386b37af594de.zip
FreeBSD-src-883da4df6b30c6a6a1889e38615386b37af594de.tar.gz
Move the IA-32 trap handling from trap() to ia32_trap(). Move the
ia32_syscall() function along with it to ia32_trap.c. When COMPAT_IA32 is not defined, we'll raise SIGEMT instead.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia32/ia32_trap.c288
-rw-r--r--sys/ia64/ia64/exception.S144
-rw-r--r--sys/ia64/ia64/genassym.c6
-rw-r--r--sys/ia64/ia64/trap.c232
-rw-r--r--sys/ia64/include/md_var.h2
5 files changed, 373 insertions, 299 deletions
diff --git a/sys/ia64/ia32/ia32_trap.c b/sys/ia64/ia32/ia32_trap.c
new file mode 100644
index 0000000..cbc6c09
--- /dev/null
+++ b/sys/ia64/ia32/ia32_trap.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2004 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ktr.h>
+#include <sys/sysproto.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/pioctl.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/syscall.h>
+#include <sys/sysent.h>
+#include <machine/fpu.h>
+#include <machine/frame.h>
+#include <machine/md_var.h>
+#include <i386/include/psl.h>
+
+static void
+ia32_syscall(struct trapframe *tf)
+{
+ uint64_t args64[8];
+ uint32_t args[8];
+ struct thread *td;
+ struct proc *p;
+ struct sysent *callp;
+ caddr_t params;
+ register_t eflags;
+ u_int code;
+ int error, i, narg;
+
+ atomic_add_int(&cnt.v_syscall, 1);
+
+ td = curthread;
+ params = (caddr_t)(tf->tf_special.sp & ((1L<<32)-1)) +
+ sizeof(uint32_t);
+ code = tf->tf_scratch.gr8; /* eax */
+ eflags = ia64_get_eflag();
+ p = td->td_proc;
+
+ if (p->p_sysent->sv_prepsyscall == NULL) {
+ if (code == SYS_syscall) {
+ /* Code is first argument, followed by actual args. */
+ code = fuword32(params);
+ params += sizeof(int);
+ } else if (code == SYS___syscall) {
+ /*
+ * Like syscall, but code is a quad, so as to maintain
+ * quad alignment for the rest of the arguments. We
+ * use a 32-bit fetch in case params is not aligned.
+ */
+ code = fuword32(params);
+ params += sizeof(quad_t);
+ }
+ } else
+ (*p->p_sysent->sv_prepsyscall)(tf, args, &code, &params);
+
+ if (p->p_sysent->sv_mask)
+ code &= p->p_sysent->sv_mask;
+
+ if (code >= p->p_sysent->sv_size)
+ callp = &p->p_sysent->sv_table[0];
+ else
+ callp = &p->p_sysent->sv_table[code];
+
+ narg = callp->sy_narg & SYF_ARGMASK;
+
+ /* copyin and the ktrsyscall()/ktrsysret() code is MP-aware */
+ if (params != NULL && narg != 0)
+ error = copyin(params, (caddr_t)args, narg * sizeof(int));
+ else
+ error = 0;
+
+ for (i = 0; i < narg; i++)
+ args64[i] = args[i];
+
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_SYSCALL))
+ ktrsyscall(code, narg, args64);
+#endif
+ /*
+ * Try to run the syscall without Giant if the syscall
+ * is MP safe.
+ */
+ if ((callp->sy_narg & SYF_MPSAFE) == 0)
+ mtx_lock(&Giant);
+
+ if (error == 0) {
+ td->td_retval[0] = 0;
+ td->td_retval[1] = tf->tf_scratch.gr10; /* edx */
+
+ STOPEVENT(p, S_SCE, narg);
+
+ error = (*callp->sy_call)(td, args64);
+ }
+
+ switch (error) {
+ case 0:
+ tf->tf_scratch.gr8 = td->td_retval[0]; /* eax */
+ tf->tf_scratch.gr10 = td->td_retval[1]; /* edx */
+ ia64_set_eflag(ia64_get_eflag() & ~PSL_C);
+ break;
+
+ case ERESTART:
+ /*
+ * Reconstruct pc, assuming lcall $X,y is 7 bytes,
+ * int 0x80 is 2 bytes. XXX Assume int 0x80.
+ */
+ tf->tf_special.iip -= 2;
+ break;
+
+ case EJUSTRETURN:
+ break;
+
+ default:
+ if (p->p_sysent->sv_errsize) {
+ if (error >= p->p_sysent->sv_errsize)
+ error = -1; /* XXX */
+ else
+ error = p->p_sysent->sv_errtbl[error];
+ }
+ tf->tf_scratch.gr8 = error;
+ ia64_set_eflag(ia64_get_eflag() | PSL_C);
+ break;
+ }
+
+ /*
+ * Release Giant if we previously set it.
+ */
+ if ((callp->sy_narg & SYF_MPSAFE) == 0)
+ mtx_unlock(&Giant);
+
+ /*
+ * Traced syscall.
+ */
+ if ((eflags & PSL_T) && !(eflags & PSL_VM)) {
+ ia64_set_eflag(ia64_get_eflag() & ~PSL_T);
+ trapsignal(td, SIGTRAP, 0);
+ }
+
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_SYSRET))
+ ktrsysret(code, error, td->td_retval[0]);
+#endif
+
+ /*
+ * This works because errno is findable through the
+ * register set. If we ever support an emulation where this
+ * is not the case, this code will need to be revisited.
+ */
+ STOPEVENT(p, S_SCX, code);
+
+ WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+ (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
+ mtx_assert(&sched_lock, MA_NOTOWNED);
+ mtx_assert(&Giant, MA_NOTOWNED);
+}
+
+/*
+ * ia32_trap() is called from exception.S to handle the IA-32 specific
+ * interruption vectors.
+ */
+void
+ia32_trap(int vector, struct trapframe *tf)
+{
+ struct proc *p;
+ struct thread *td;
+ uint64_t ucode;
+ int sig;
+ u_int sticks;
+
+ KASSERT(TRAPF_USERMODE(tf), ("%s: In kernel mode???", __func__));
+
+ ia64_set_fpsr(IA64_FPSR_DEFAULT);
+ atomic_add_int(&cnt.v_trap, 1);
+
+ td = curthread;
+ td->td_frame = tf;
+ sticks = td->td_sticks;
+ p = td->td_proc;
+ if (td->td_ucred != p->p_ucred)
+ cred_update_thread(td);
+ sig = 0;
+ ucode = 0;
+ switch (vector) {
+ case IA64_VEC_IA32_EXCEPTION:
+ switch ((tf->tf_special.isr >> 16) & 0xffff) {
+ case IA32_EXCEPTION_DIVIDE:
+ ucode = FPE_INTDIV;
+ sig = SIGFPE;
+ break;
+ case IA32_EXCEPTION_DEBUG:
+ case IA32_EXCEPTION_BREAK:
+ sig = SIGTRAP;
+ break;
+ case IA32_EXCEPTION_OVERFLOW:
+ ucode = FPE_INTOVF;
+ sig = SIGFPE;
+ break;
+ case IA32_EXCEPTION_BOUND:
+ ucode = FPE_FLTSUB;
+ sig = SIGFPE;
+ break;
+ case IA32_EXCEPTION_DNA:
+ ucode = 0;
+ sig = SIGFPE;
+ break;
+ case IA32_EXCEPTION_NOT_PRESENT:
+ case IA32_EXCEPTION_STACK_FAULT:
+ case IA32_EXCEPTION_GPFAULT:
+ ucode = (tf->tf_special.isr & 0xffff) + BUS_SEGM_FAULT;
+ sig = SIGBUS;
+ break;
+ case IA32_EXCEPTION_FPERROR:
+ ucode = 0; /* XXX */
+ sig = SIGFPE;
+ break;
+ case IA32_EXCEPTION_ALIGNMENT_CHECK:
+ ucode = tf->tf_special.ifa; /* VA */
+ sig = SIGBUS;
+ break;
+ case IA32_EXCEPTION_STREAMING_SIMD:
+ ucode = 0; /* XXX */
+ sig = SIGFPE;
+ break;
+ default:
+ trap_panic(vector, tf);
+ break;
+ }
+ break;
+
+ case IA64_VEC_IA32_INTERCEPT:
+ /* XXX Maybe need to emulate ia32 instruction. */
+ trap_panic(vector, tf);
+
+ case IA64_VEC_IA32_INTERRUPT:
+ /* INT n instruction - probably a syscall. */
+ if (((tf->tf_special.isr >> 16) & 0xffff) == 0x80) {
+ ia32_syscall(tf);
+ goto out;
+ }
+ ucode = (tf->tf_special.isr >> 16) & 0xffff;
+ sig = SIGILL;
+ break;
+
+ default:
+ /* Should never happen of course. */
+ trap_panic(vector, tf);
+ break;
+ }
+
+ KASSERT(sig != 0, ("%s: signal not set", __func__));
+
+ trapsignal(td, sig, ucode);
+
+out:
+ userret(td, tf, sticks);
+ mtx_assert(&Giant, MA_NOTOWNED);
+ do_ast(tf);
+}
diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S
index 54ceab3..1130461 100644
--- a/sys/ia64/ia64/exception.S
+++ b/sys/ia64/ia64/exception.S
@@ -23,11 +23,11 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
#include <machine/pte.h>
#include <assym.s>
@@ -576,7 +576,7 @@ END(exception_restore)
* which will restore the interrupted state before executing an rfi to
* resume it.
*/
-#define TRAP(_n_, _ifa_) \
+#define CALL(_func_, _n_, _ifa_) \
{ .mib ; \
mov r17=_ifa_ ; \
mov r16=ip ; \
@@ -590,7 +590,7 @@ END(exception_restore)
{ .mfb ; \
add out1=16,sp ; \
nop 0 ; \
- br.call.sptk rp=trap ; \
+ br.call.sptk rp=_func_ ; \
} ; \
{ .mfb ; \
nop 0 ; \
@@ -611,6 +611,12 @@ ivt_##name:
#define IVT_END(name) \
.endp ivt_##name
+#ifdef COMPAT_IA32
+#define IA32_TRAP ia32_trap
+#else
+#define IA32_TRAP trap
+#endif
+
/*
* The IA64 Interrupt Vector Table (IVT) contains 20 slots with 64
* bundles per vector and 48 slots with 16 bundles per vector.
@@ -624,7 +630,7 @@ ivt_##name:
ia64_vector_table:
IVT_ENTRY(VHPT_Translation, 0x0000)
- TRAP(0, cr.ifa)
+ CALL(trap, 0, cr.ifa)
IVT_END(VHPT_Translation)
IVT_ENTRY(Instruction_TLB, 0x0400)
@@ -702,7 +708,7 @@ IVT_ENTRY(Instruction_TLB, 0x0400)
;;
srlz.d
;;
- TRAP(20, cr.ifa) // Page Not Present trap
+ CALL(trap, 20, cr.ifa) // Page Not Present trap
IVT_END(Instruction_TLB)
IVT_ENTRY(Data_TLB, 0x0800)
@@ -780,7 +786,7 @@ IVT_ENTRY(Data_TLB, 0x0800)
;;
srlz.d
;;
- TRAP(20, cr.ifa) // Page Not Present trap
+ CALL(trap, 20, cr.ifa) // Page Not Present trap
IVT_END(Data_TLB)
IVT_ENTRY(Alternate_Instruction_TLB, 0x0c00)
@@ -807,7 +813,7 @@ IVT_ENTRY(Alternate_Instruction_TLB, 0x0c00)
;;
rfi
9: mov pr=r18,0x1ffff // restore predicates
- TRAP(3, cr.ifa)
+ CALL(trap, 3, cr.ifa)
IVT_END(Alternate_Instruction_TLB)
IVT_ENTRY(Alternate_Data_TLB, 0x1000)
@@ -834,7 +840,7 @@ IVT_ENTRY(Alternate_Data_TLB, 0x1000)
;;
rfi
9: mov pr=r18,0x1ffff // restore predicates
- TRAP(4, cr.ifa)
+ CALL(trap, 4, cr.ifa)
IVT_END(Alternate_Data_TLB)
IVT_ENTRY(Data_Nested_TLB, 0x1400)
@@ -915,11 +921,11 @@ IVT_ENTRY(Data_Nested_TLB, 0x1400)
IVT_END(Data_Nested_TLB)
IVT_ENTRY(Instruction_Key_Miss, 0x1800)
- TRAP(6, cr.ifa)
+ CALL(trap, 6, cr.ifa)
IVT_END(Instruction_Key_Miss)
IVT_ENTRY(Data_Key_Miss, 0x1c00)
- TRAP(7, cr.ifa)
+ CALL(trap, 7, cr.ifa)
IVT_END(Data_Key_Miss)
IVT_ENTRY(Dirty_Bit, 0x2000)
@@ -985,7 +991,7 @@ IVT_ENTRY(Dirty_Bit, 0x2000)
br.cond.sptk.few 1b // loop
9: mov pr=r17,0x1ffff // restore predicates
- TRAP(8, cr.ifa) // die horribly
+ CALL(trap, 8, cr.ifa) // die horribly
IVT_END(Dirty_Bit)
IVT_ENTRY(Instruction_Access_Bit, 0x2400)
@@ -1051,7 +1057,7 @@ IVT_ENTRY(Instruction_Access_Bit, 0x2400)
br.cond.sptk.few 1b // loop
9: mov pr=r17,0x1ffff // restore predicates
- TRAP(9, cr.ifa)
+ CALL(trap, 9, cr.ifa)
IVT_END(Instruction_Access_Bit)
IVT_ENTRY(Data_Access_Bit, 0x2800)
@@ -1117,7 +1123,7 @@ IVT_ENTRY(Data_Access_Bit, 0x2800)
br.cond.sptk.few 1b // loop
9: mov pr=r17,0x1ffff // restore predicates
- TRAP(10, cr.ifa)
+ CALL(trap, 10, cr.ifa)
IVT_END(Data_Access_Bit)
IVT_ENTRY(Break_Instruction, 0x2c00)
@@ -1205,221 +1211,221 @@ IVT_ENTRY(External_Interrupt, 0x3000)
IVT_END(External_Interrupt)
IVT_ENTRY(Reserved_3400, 0x3400)
- TRAP(13, cr.ifa)
+ CALL(trap, 13, cr.ifa)
IVT_END(Reserved_3400)
IVT_ENTRY(Reserved_3800, 0x3800)
- TRAP(14, cr.ifa)
+ CALL(trap, 14, cr.ifa)
IVT_END(Reserved_3800)
IVT_ENTRY(Reserved_3c00, 0x3c00)
- TRAP(15, cr.ifa)
+ CALL(trap, 15, cr.ifa)
IVT_END(Reserved_3c00)
IVT_ENTRY(Reserved_4000, 0x4000)
- TRAP(16, cr.ifa)
+ CALL(trap, 16, cr.ifa)
IVT_END(Reserved_4000)
IVT_ENTRY(Reserved_4400, 0x4400)
- TRAP(17, cr.ifa)
+ CALL(trap, 17, cr.ifa)
IVT_END(Reserved_4400)
IVT_ENTRY(Reserved_4800, 0x4800)
- TRAP(18, cr.ifa)
+ CALL(trap, 18, cr.ifa)
IVT_END(Reserved_4800)
IVT_ENTRY(Reserved_4c00, 0x4c00)
- TRAP(19, cr.ifa)
+ CALL(trap, 19, cr.ifa)
IVT_END(Reserved_4c00)
IVT_ENTRY(Page_Not_Present, 0x5000)
- TRAP(20, cr.ifa)
+ CALL(trap, 20, cr.ifa)
IVT_END(Page_Not_Present)
IVT_ENTRY(Key_Permission, 0x5100)
- TRAP(21, cr.ifa)
+ CALL(trap, 21, cr.ifa)
IVT_END(Key_Permission)
IVT_ENTRY(Instruction_Access_Rights, 0x5200)
- TRAP(22, cr.ifa)
+ CALL(trap, 22, cr.ifa)
IVT_END(Instruction_Access_Rights)
IVT_ENTRY(Data_Access_Rights, 0x5300)
- TRAP(23, cr.ifa)
+ CALL(trap, 23, cr.ifa)
IVT_END(Data_Access_Rights)
IVT_ENTRY(General_Exception, 0x5400)
- TRAP(24, cr.ifa)
+ CALL(trap, 24, cr.ifa)
IVT_END(General_Exception)
IVT_ENTRY(Disabled_FP_Register, 0x5500)
- TRAP(25, cr.ifa)
+ CALL(trap, 25, cr.ifa)
IVT_END(Disabled_FP_Register)
IVT_ENTRY(NaT_Consumption, 0x5600)
- TRAP(26, cr.ifa)
+ CALL(trap, 26, cr.ifa)
IVT_END(NaT_Consumption)
IVT_ENTRY(Speculation, 0x5700)
- TRAP(27, cr.iim)
+ CALL(trap, 27, cr.iim)
IVT_END(Speculation)
IVT_ENTRY(Reserved_5800, 0x5800)
- TRAP(28, cr.ifa)
+ CALL(trap, 28, cr.ifa)
IVT_END(Reserved_5800)
IVT_ENTRY(Debug, 0x5900)
- TRAP(29, cr.ifa)
+ CALL(trap, 29, cr.ifa)
IVT_END(Debug)
IVT_ENTRY(Unaligned_Reference, 0x5a00)
- TRAP(30, cr.ifa)
+ CALL(trap, 30, cr.ifa)
IVT_END(Unaligned_Reference)
IVT_ENTRY(Unsupported_Data_Reference, 0x5b00)
- TRAP(31, cr.ifa)
+ CALL(trap, 31, cr.ifa)
IVT_END(Unsupported_Data_Reference)
IVT_ENTRY(Floating_Point_Fault, 0x5c00)
- TRAP(32, cr.ifa)
+ CALL(trap, 32, cr.ifa)
IVT_END(Floating_Point_Fault)
IVT_ENTRY(Floating_Point_Trap, 0x5d00)
- TRAP(33, cr.ifa)
+ CALL(trap, 33, cr.ifa)
IVT_END(Floating_Point_Trap)
IVT_ENTRY(Lower_Privilege_Transfer_Trap, 0x5e00)
- TRAP(34, cr.ifa)
+ CALL(trap, 34, cr.ifa)
IVT_END(Lower_Privilege_Transfer_Trap)
IVT_ENTRY(Taken_Branch_Trap, 0x5f00)
- TRAP(35, cr.ifa)
+ CALL(trap, 35, cr.ifa)
IVT_END(Taken_Branch_Trap)
IVT_ENTRY(Single_Step_Trap, 0x6000)
- TRAP(36, cr.ifa)
+ CALL(trap, 36, cr.ifa)
IVT_END(Single_Step_Trap)
IVT_ENTRY(Reserved_6100, 0x6100)
- TRAP(37, cr.ifa)
+ CALL(trap, 37, cr.ifa)
IVT_END(Reserved_6100)
IVT_ENTRY(Reserved_6200, 0x6200)
- TRAP(38, cr.ifa)
+ CALL(trap, 38, cr.ifa)
IVT_END(Reserved_6200)
IVT_ENTRY(Reserved_6300, 0x6300)
- TRAP(39, cr.ifa)
+ CALL(trap, 39, cr.ifa)
IVT_END(Reserved_6300)
IVT_ENTRY(Reserved_6400, 0x6400)
- TRAP(40, cr.ifa)
+ CALL(trap, 40, cr.ifa)
IVT_END(Reserved_6400)
IVT_ENTRY(Reserved_6500, 0x6500)
- TRAP(41, cr.ifa)
+ CALL(trap, 41, cr.ifa)
IVT_END(Reserved_6500)
IVT_ENTRY(Reserved_6600, 0x6600)
- TRAP(42, cr.ifa)
+ CALL(trap, 42, cr.ifa)
IVT_END(Reserved_6600)
IVT_ENTRY(Reserved_6700, 0x6700)
- TRAP(43, cr.ifa)
+ CALL(trap, 43, cr.ifa)
IVT_END(Reserved_6700)
IVT_ENTRY(Reserved_6800, 0x6800)
- TRAP(44, cr.ifa)
+ CALL(trap, 44, cr.ifa)
IVT_END(Reserved_6800)
IVT_ENTRY(IA_32_Exception, 0x6900)
- TRAP(45, cr.ifa)
+ CALL(IA32_TRAP, 45, cr.ifa)
IVT_END(IA_32_Exception)
IVT_ENTRY(IA_32_Intercept, 0x6a00)
- TRAP(46, cr.iim)
+ CALL(IA32_TRAP, 46, cr.iim)
IVT_END(IA_32_Intercept)
IVT_ENTRY(IA_32_Interrupt, 0x6b00)
- TRAP(47, cr.ifa)
+ CALL(IA32_TRAP, 47, cr.ifa)
IVT_END(IA_32_Interrupt)
IVT_ENTRY(Reserved_6c00, 0x6c00)
- TRAP(48, cr.ifa)
+ CALL(trap, 48, cr.ifa)
IVT_END(Reserved_6c00)
IVT_ENTRY(Reserved_6d00, 0x6d00)
- TRAP(49, cr.ifa)
+ CALL(trap, 49, cr.ifa)
IVT_END(Reserved_6d00)
IVT_ENTRY(Reserved_6e00, 0x6e00)
- TRAP(50, cr.ifa)
+ CALL(trap, 50, cr.ifa)
IVT_END(Reserved_6e00)
IVT_ENTRY(Reserved_6f00, 0x6f00)
- TRAP(51, cr.ifa)
+ CALL(trap, 51, cr.ifa)
IVT_END(Reserved_6f00)
IVT_ENTRY(Reserved_7000, 0x7000)
- TRAP(52, cr.ifa)
+ CALL(trap, 52, cr.ifa)
IVT_END(Reserved_7000)
IVT_ENTRY(Reserved_7100, 0x7100)
- TRAP(53, cr.ifa)
+ CALL(trap, 53, cr.ifa)
IVT_END(Reserved_7100)
IVT_ENTRY(Reserved_7200, 0x7200)
- TRAP(54, cr.ifa)
+ CALL(trap, 54, cr.ifa)
IVT_END(Reserved_7200)
IVT_ENTRY(Reserved_7300, 0x7300)
- TRAP(55, cr.ifa)
+ CALL(trap, 55, cr.ifa)
IVT_END(Reserved_7300)
IVT_ENTRY(Reserved_7400, 0x7400)
- TRAP(56, cr.ifa)
+ CALL(trap, 56, cr.ifa)
IVT_END(Reserved_7400)
IVT_ENTRY(Reserved_7500, 0x7500)
- TRAP(57, cr.ifa)
+ CALL(trap, 57, cr.ifa)
IVT_END(Reserved_7500)
IVT_ENTRY(Reserved_7600, 0x7600)
- TRAP(58, cr.ifa)
+ CALL(trap, 58, cr.ifa)
IVT_END(Reserved_7600)
IVT_ENTRY(Reserved_7700, 0x7700)
- TRAP(59, cr.ifa)
+ CALL(trap, 59, cr.ifa)
IVT_END(Reserved_7700)
IVT_ENTRY(Reserved_7800, 0x7800)
- TRAP(60, cr.ifa)
+ CALL(trap, 60, cr.ifa)
IVT_END(Reserved_7800)
IVT_ENTRY(Reserved_7900, 0x7900)
- TRAP(61, cr.ifa)
+ CALL(trap, 61, cr.ifa)
IVT_END(Reserved_7900)
IVT_ENTRY(Reserved_7a00, 0x7a00)
- TRAP(62, cr.ifa)
+ CALL(trap, 62, cr.ifa)
IVT_END(Reserved_7a00)
IVT_ENTRY(Reserved_7b00, 0x7b00)
- TRAP(63, cr.ifa)
+ CALL(trap, 63, cr.ifa)
IVT_END(Reserved_7b00)
IVT_ENTRY(Reserved_7c00, 0x7c00)
- TRAP(64, cr.ifa)
+ CALL(trap, 64, cr.ifa)
IVT_END(Reserved_7c00)
IVT_ENTRY(Reserved_7d00, 0x7d00)
- TRAP(65, cr.ifa)
+ CALL(trap, 65, cr.ifa)
IVT_END(Reserved_7d00)
IVT_ENTRY(Reserved_7e00, 0x7e00)
- TRAP(66, cr.ifa)
+ CALL(trap, 66, cr.ifa)
IVT_END(Reserved_7e00)
IVT_ENTRY(Reserved_7f00, 0x7f00)
- TRAP(67, cr.ifa)
+ CALL(trap, 67, cr.ifa)
IVT_END(Reserved_7f00)
diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c
index 790058b..c2f377d 100644
--- a/sys/ia64/ia64/genassym.c
+++ b/sys/ia64/ia64/genassym.c
@@ -29,10 +29,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
* $FreeBSD$
*/
+#include "opt_compat.h"
#include "opt_kstack_pages.h"
#include <sys/param.h>
@@ -61,6 +61,10 @@
#include <net/if.h>
#include <netinet/in.h>
+#ifdef COMPAT_IA32
+ASSYM(COMPAT_IA32, COMPAT_IA32);
+#endif
+
ASSYM(DT_NULL, DT_NULL);
ASSYM(DT_RELA, DT_RELA);
ASSYM(DT_RELAENT, DT_RELAENT);
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c
index d2b5c76..2803ae0 100644
--- a/sys/ia64/ia64/trap.c
+++ b/sys/ia64/ia64/trap.c
@@ -81,7 +81,6 @@ SYSCTL_INT(_machdep, OID_AUTO, print_usertrap,
CTLFLAG_RW, &print_usertrap, 0, "");
static void break_syscall(struct trapframe *tf);
-static void ia32_syscall(struct trapframe *tf);
/*
* EFI-Provided FPSWA interface (Floating Point SoftWare Assist)
@@ -286,7 +285,7 @@ printtrap(int vector, struct trapframe *tf, int isfatal, int user)
printf("\n");
}
-static void
+void
trap_panic(int vector, struct trapframe *tf)
{
@@ -803,64 +802,10 @@ trap(int vector, struct trapframe *tf)
break;
case IA64_VEC_IA32_EXCEPTION:
- switch ((tf->tf_special.isr >> 16) & 0xffff) {
- case IA32_EXCEPTION_DIVIDE:
- ucode = FPE_INTDIV;
- sig = SIGFPE;
- break;
- case IA32_EXCEPTION_DEBUG:
- case IA32_EXCEPTION_BREAK:
- sig = SIGTRAP;
- break;
- case IA32_EXCEPTION_OVERFLOW:
- ucode = FPE_INTOVF;
- sig = SIGFPE;
- break;
- case IA32_EXCEPTION_BOUND:
- ucode = FPE_FLTSUB;
- sig = SIGFPE;
- break;
- case IA32_EXCEPTION_DNA:
- ucode = 0;
- sig = SIGFPE;
- break;
- case IA32_EXCEPTION_NOT_PRESENT:
- case IA32_EXCEPTION_STACK_FAULT:
- case IA32_EXCEPTION_GPFAULT:
- ucode = (tf->tf_special.isr & 0xffff) +
- BUS_SEGM_FAULT;
- sig = SIGBUS;
- break;
- case IA32_EXCEPTION_FPERROR:
- ucode = 0; /* XXX */
- sig = SIGFPE;
- break;
- case IA32_EXCEPTION_ALIGNMENT_CHECK:
- ucode = tf->tf_special.ifa; /* VA */
- sig = SIGBUS;
- break;
- case IA32_EXCEPTION_STREAMING_SIMD:
- ucode = 0; /* XXX */
- sig = SIGFPE;
- break;
- default:
- trap_panic(vector, tf);
- break;
- }
- break;
-
case IA64_VEC_IA32_INTERCEPT:
- /* XXX Maybe need to emulate ia32 instruction. */
- trap_panic(vector, tf);
-
case IA64_VEC_IA32_INTERRUPT:
- /* INT n instruction - probably a syscall. */
- if (((tf->tf_special.isr >> 16) & 0xffff) == 0x80) {
- ia32_syscall(tf);
- goto out;
- }
- ucode = (tf->tf_special.isr >> 16) & 0xffff;
- sig = SIGILL;
+ sig = SIGEMT;
+ ucode = tf->tf_special.iip;
break;
default:
@@ -885,7 +830,6 @@ out:
return;
}
-
/*
* Handle break instruction based system calls.
*/
@@ -1055,173 +999,3 @@ syscall(struct trapframe *tf)
return (error);
}
-
-#include <i386/include/psl.h>
-
-static void
-ia32_syscall(struct trapframe *tf)
-{
- caddr_t params;
- int i;
- struct sysent *callp;
- struct thread *td = curthread;
- struct proc *p = td->td_proc;
- register_t orig_eflags;
- u_int sticks;
- int error;
- int narg;
- u_int32_t args[8];
- u_int64_t args64[8];
- u_int code;
-
- /*
- * note: PCPU_LAZY_INC() can only be used if we can afford
- * occassional inaccuracy in the count.
- */
- cnt.v_syscall++;
-
- sticks = td->td_sticks;
- td->td_frame = tf;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
- params = (caddr_t)(tf->tf_special.sp & ((1L<<32)-1))
- + sizeof(u_int32_t);
- code = tf->tf_scratch.gr8; /* eax */
- orig_eflags = ia64_get_eflag();
-
- if (p->p_sysent->sv_prepsyscall) {
- /*
- * The prep code is MP aware.
- */
- (*p->p_sysent->sv_prepsyscall)(tf, args, &code, &params);
- } else {
- /*
- * Need to check if this is a 32 bit or 64 bit syscall.
- * fuword is MP aware.
- */
- if (code == SYS_syscall) {
- /*
- * Code is first argument, followed by actual args.
- */
- code = fuword32(params);
- params += sizeof(int);
- } else if (code == SYS___syscall) {
- /*
- * Like syscall, but code is a quad, so as to maintain
- * quad alignment for the rest of the arguments.
- * We use a 32-bit fetch in case params is not
- * aligned.
- */
- code = fuword32(params);
- params += sizeof(quad_t);
- }
- }
-
- if (p->p_sysent->sv_mask)
- code &= p->p_sysent->sv_mask;
-
- if (code >= p->p_sysent->sv_size)
- callp = &p->p_sysent->sv_table[0];
- else
- callp = &p->p_sysent->sv_table[code];
-
- narg = callp->sy_narg & SYF_ARGMASK;
-
- /*
- * copyin and the ktrsyscall()/ktrsysret() code is MP-aware
- */
- if (params != NULL && narg != 0)
- error = copyin(params, (caddr_t)args,
- (u_int)(narg * sizeof(int)));
- else
- error = 0;
-
- for (i = 0; i < narg; i++)
- args64[i] = args[i];
-
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSCALL))
- ktrsyscall(code, narg, args64);
-#endif
- /*
- * Try to run the syscall without Giant if the syscall
- * is MP safe.
- */
- if ((callp->sy_narg & SYF_MPSAFE) == 0)
- mtx_lock(&Giant);
-
- if (error == 0) {
- td->td_retval[0] = 0;
- td->td_retval[1] = tf->tf_scratch.gr10; /* edx */
-
- STOPEVENT(p, S_SCE, narg);
-
- error = (*callp->sy_call)(td, args64);
- }
-
- switch (error) {
- case 0:
- tf->tf_scratch.gr8 = td->td_retval[0]; /* eax */
- tf->tf_scratch.gr10 = td->td_retval[1]; /* edx */
- ia64_set_eflag(ia64_get_eflag() & ~PSL_C);
- break;
-
- case ERESTART:
- /*
- * Reconstruct pc, assuming lcall $X,y is 7 bytes,
- * int 0x80 is 2 bytes. XXX Assume int 0x80.
- */
- tf->tf_special.iip -= 2;
- break;
-
- case EJUSTRETURN:
- break;
-
- default:
- if (p->p_sysent->sv_errsize) {
- if (error >= p->p_sysent->sv_errsize)
- error = -1; /* XXX */
- else
- error = p->p_sysent->sv_errtbl[error];
- }
- tf->tf_scratch.gr8 = error;
- ia64_set_eflag(ia64_get_eflag() | PSL_C);
- break;
- }
-
- /*
- * Traced syscall.
- */
- if ((orig_eflags & PSL_T) && !(orig_eflags & PSL_VM)) {
- ia64_set_eflag(ia64_get_eflag() & ~PSL_T);
- trapsignal(td, SIGTRAP, 0);
- }
-
- /*
- * Release Giant if we previously set it.
- */
- if ((callp->sy_narg & SYF_MPSAFE) == 0)
- mtx_unlock(&Giant);
-
- /*
- * Handle reschedule and other end-of-syscall issues
- */
- userret(td, tf, sticks);
-
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSRET))
- ktrsysret(code, error, td->td_retval[0]);
-#endif
-
- /*
- * This works because errno is findable through the
- * register set. If we ever support an emulation where this
- * is not the case, this code will need to be revisited.
- */
- STOPEVENT(p, S_SCX, code);
-
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
- mtx_assert(&sched_lock, MA_NOTOWNED);
- mtx_assert(&Giant, MA_NOTOWNED);
-}
diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h
index d1a206e..04f3f5f 100644
--- a/sys/ia64/include/md_var.h
+++ b/sys/ia64/include/md_var.h
@@ -75,6 +75,7 @@ void busdma_swi(void);
int copyout_regstack(struct thread *, uint64_t *, uint64_t *);
void cpu_mp_add(u_int, u_int, u_int);
int do_ast(struct trapframe *);
+void ia32_trap(int, struct trapframe *);
int ia64_count_cpus(void);
void ia64_flush_dirty(struct thread *, struct _special *);
int ia64_highfp_drop(struct thread *);
@@ -89,6 +90,7 @@ void os_mca(void);
void spillfd(void *src, void *dst);
int syscall(struct trapframe *);
void trap(int, struct trapframe *);
+void trap_panic(int, struct trapframe *);
int unaligned_fixup(struct trapframe *, struct thread *);
#endif /* _KERNEL */
OpenPOWER on IntegriCloud