diff options
author | marcel <marcel@FreeBSD.org> | 2004-09-25 04:27:44 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2004-09-25 04:27:44 +0000 |
commit | 883da4df6b30c6a6a1889e38615386b37af594de (patch) | |
tree | 8de6820f7af882f731e1d689d5d242fb96cc1bc7 /sys/ia64 | |
parent | 954ae57b986db4b14140e76aebb189c88e5634d8 (diff) | |
download | FreeBSD-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.c | 288 | ||||
-rw-r--r-- | sys/ia64/ia64/exception.S | 144 | ||||
-rw-r--r-- | sys/ia64/ia64/genassym.c | 6 | ||||
-rw-r--r-- | sys/ia64/ia64/trap.c | 232 | ||||
-rw-r--r-- | sys/ia64/include/md_var.h | 2 |
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, ¶ms); + + 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, ¶ms); - } 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 */ |