mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-18 14:23:55 +00:00
Partial support for branch long emulation. This only emulates the
branch long jump and not the branch long call. Support for that is forthcoming.
This commit is contained in:
parent
2e4db89cfc
commit
559adb10ad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=160040
|
@ -93,6 +93,7 @@ ia64/ia64/db_machdep.c optional ddb
|
|||
ia64/ia64/dump_machdep.c standard
|
||||
ia64/ia64/efi.c standard
|
||||
ia64/ia64/elf_machdep.c standard
|
||||
ia64/ia64/emulate.c standard
|
||||
ia64/ia64/exception.S standard
|
||||
ia64/ia64/gdb_machdep.c optional gdb
|
||||
ia64/ia64/in_cksum.c optional inet
|
||||
|
|
89
sys/ia64/ia64/emulate.c
Normal file
89
sys/ia64/ia64/emulate.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*-
|
||||
* Copyright (c) 2006 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/proc.h>
|
||||
|
||||
#include <machine/frame.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#include <ia64/disasm/disasm.h>
|
||||
|
||||
int
|
||||
ia64_emulate(struct trapframe *tf, struct thread *td)
|
||||
{
|
||||
struct asm_bundle bundle;
|
||||
struct asm_inst *i;
|
||||
int slot;
|
||||
|
||||
if (!asm_decode(tf->tf_special.iip, &bundle))
|
||||
return (SIGILL);
|
||||
|
||||
slot = ((tf->tf_special.psr & IA64_PSR_RI) == IA64_PSR_RI_0) ? 0 :
|
||||
((tf->tf_special.psr & IA64_PSR_RI) == IA64_PSR_RI_1) ? 1 : 2;
|
||||
if (slot == 1 && bundle.b_templ[slot] == 'L')
|
||||
slot++;
|
||||
|
||||
i = bundle.b_inst + slot;
|
||||
switch (i->i_op) {
|
||||
case ASM_OP_BRL:
|
||||
/*
|
||||
* We get the fault even if the predicate is false, so we
|
||||
* need to check the predicate first and simply advance to
|
||||
* the next bundle in that case.
|
||||
*/
|
||||
if (!(tf->tf_special.pr & (1UL << i->i_oper[0].o_value))) {
|
||||
tf->tf_special.psr &= ~IA64_PSR_RI;
|
||||
tf->tf_special.iip += 16;
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* The brl.cond is the simplest form. We only have to set
|
||||
* the IP to the address in the instruction and return.
|
||||
*/
|
||||
if (i->i_cmpltr[0].c_type == ASM_CT_COND) {
|
||||
tf->tf_special.psr &= ~IA64_PSR_RI;
|
||||
tf->tf_special.iip += i->i_oper[1].o_value;
|
||||
return (0);
|
||||
}
|
||||
/* Sanity check... */
|
||||
if (i->i_cmpltr[0].c_type != ASM_CT_CALL)
|
||||
break;
|
||||
/*
|
||||
* The brl.call is more difficult as we need to set-up the
|
||||
* call properly.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (SIGILL);
|
||||
}
|
|
@ -608,7 +608,27 @@ trap(int vector, struct trapframe *tf)
|
|||
break;
|
||||
}
|
||||
|
||||
case IA64_VEC_GENERAL_EXCEPTION:
|
||||
case IA64_VEC_GENERAL_EXCEPTION: {
|
||||
int code;
|
||||
|
||||
if (!user)
|
||||
trap_panic(vector, tf);
|
||||
|
||||
code = tf->tf_special.isr & (IA64_ISR_CODE & 0xf0ull);
|
||||
switch (code) {
|
||||
case 0x0: /* Illegal Operation Fault. */
|
||||
sig = ia64_emulate(tf, td);
|
||||
break;
|
||||
default:
|
||||
sig = SIGILL;
|
||||
break;
|
||||
}
|
||||
if (sig == 0)
|
||||
goto out;
|
||||
ucode = vector;
|
||||
break;
|
||||
}
|
||||
|
||||
case IA64_VEC_NAT_CONSUMPTION:
|
||||
case IA64_VEC_SPECULATION:
|
||||
case IA64_VEC_UNSUPP_DATA_REFERENCE:
|
||||
|
|
|
@ -77,6 +77,7 @@ 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);
|
||||
int ia64_emulate(struct trapframe *, struct thread *);
|
||||
int ia64_flush_dirty(struct thread *, struct _special *);
|
||||
uint64_t ia64_get_hcdp(void);
|
||||
int ia64_highfp_drop(struct thread *);
|
||||
|
|
Loading…
Reference in a new issue