aboutsummaryrefslogtreecommitdiff
path: root/bsd-user
diff options
context:
space:
mode:
Diffstat (limited to 'bsd-user')
-rw-r--r--bsd-user/arm/signal.c196
-rw-r--r--bsd-user/arm/target_arch.h28
-rw-r--r--bsd-user/arm/target_arch_cpu.c39
-rw-r--r--bsd-user/arm/target_arch_cpu.h211
-rw-r--r--bsd-user/arm/target_arch_elf.h128
-rw-r--r--bsd-user/arm/target_arch_reg.h60
-rw-r--r--bsd-user/arm/target_arch_signal.h88
-rw-r--r--bsd-user/arm/target_arch_sigtramp.h49
-rw-r--r--bsd-user/arm/target_arch_sysarch.h6
-rw-r--r--bsd-user/arm/target_arch_thread.h82
-rw-r--r--bsd-user/arm/target_arch_vmparam.h48
-rw-r--r--bsd-user/arm/target_syscall.h27
-rw-r--r--bsd-user/freebsd/target_os_signal.h3
-rw-r--r--bsd-user/freebsd/target_os_ucontext.h44
-rw-r--r--bsd-user/i386/signal.c55
-rw-r--r--bsd-user/i386/target_arch_signal.h95
-rw-r--r--bsd-user/mips/target_arch_sysarch.h69
-rw-r--r--bsd-user/mips/target_syscall.h52
-rw-r--r--bsd-user/mips64/target_arch_sysarch.h69
-rw-r--r--bsd-user/mips64/target_syscall.h53
-rw-r--r--bsd-user/x86_64/signal.c55
-rw-r--r--bsd-user/x86_64/target_arch_signal.h103
22 files changed, 1211 insertions, 349 deletions
diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
new file mode 100644
index 0000000..1478f00
--- /dev/null
+++ b/bsd-user/arm/signal.c
@@ -0,0 +1,196 @@
+/*
+ * arm signal functions
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu.h"
+
+/*
+ * Compare to arm/arm/machdep.c sendsig()
+ * Assumes that target stack frame memory is locked.
+ */
+abi_long set_sigtramp_args(CPUARMState *env, int sig,
+ struct target_sigframe *frame,
+ abi_ulong frame_addr,
+ struct target_sigaction *ka)
+{
+ /*
+ * Arguments to signal handler:
+ * r0 = signal number
+ * r1 = siginfo pointer
+ * r2 = ucontext pointer
+ * r5 = ucontext pointer
+ * pc = signal handler pointer
+ * sp = sigframe struct pointer
+ * lr = sigtramp at base of user stack
+ */
+
+ env->regs[0] = sig;
+ env->regs[1] = frame_addr +
+ offsetof(struct target_sigframe, sf_si);
+ env->regs[2] = frame_addr +
+ offsetof(struct target_sigframe, sf_uc);
+
+ /* the trampoline uses r5 as the uc address */
+ env->regs[5] = frame_addr +
+ offsetof(struct target_sigframe, sf_uc);
+ env->regs[TARGET_REG_PC] = ka->_sa_handler & ~1;
+ env->regs[TARGET_REG_SP] = frame_addr;
+ env->regs[TARGET_REG_LR] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
+ /*
+ * Low bit indicates whether or not we're entering thumb mode.
+ */
+ cpsr_write(env, (ka->_sa_handler & 1) * CPSR_T, CPSR_T, CPSRWriteByInstr);
+
+ return 0;
+}
+
+/*
+ * Compare to arm/arm/machdep.c get_mcontext()
+ * Assumes that the memory is locked if mcp points to user memory.
+ */
+abi_long get_mcontext(CPUARMState *env, target_mcontext_t *mcp, int flags)
+{
+ int err = 0;
+ uint32_t *gr = mcp->__gregs;
+
+ if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size != sizeof(target_mcontext_vfp_t)) {
+ return -TARGET_EINVAL;
+ }
+
+ gr[TARGET_REG_CPSR] = tswap32(cpsr_read(env));
+ if (flags & TARGET_MC_GET_CLEAR_RET) {
+ gr[TARGET_REG_R0] = 0;
+ gr[TARGET_REG_CPSR] &= ~CPSR_C;
+ } else {
+ gr[TARGET_REG_R0] = tswap32(env->regs[0]);
+ }
+
+ gr[TARGET_REG_R1] = tswap32(env->regs[1]);
+ gr[TARGET_REG_R2] = tswap32(env->regs[2]);
+ gr[TARGET_REG_R3] = tswap32(env->regs[3]);
+ gr[TARGET_REG_R4] = tswap32(env->regs[4]);
+ gr[TARGET_REG_R5] = tswap32(env->regs[5]);
+ gr[TARGET_REG_R6] = tswap32(env->regs[6]);
+ gr[TARGET_REG_R7] = tswap32(env->regs[7]);
+ gr[TARGET_REG_R8] = tswap32(env->regs[8]);
+ gr[TARGET_REG_R9] = tswap32(env->regs[9]);
+ gr[TARGET_REG_R10] = tswap32(env->regs[10]);
+ gr[TARGET_REG_R11] = tswap32(env->regs[11]);
+ gr[TARGET_REG_R12] = tswap32(env->regs[12]);
+
+ gr[TARGET_REG_SP] = tswap32(env->regs[13]);
+ gr[TARGET_REG_LR] = tswap32(env->regs[14]);
+ gr[TARGET_REG_PC] = tswap32(env->regs[15]);
+
+ if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_ptr != 0) {
+ /* see get_vfpcontext in sys/arm/arm/exec_machdep.c */
+ target_mcontext_vfp_t *vfp;
+ vfp = lock_user(VERIFY_WRITE, mcp->mc_vfp_ptr, sizeof(*vfp), 0);
+ for (int i = 0; i < 32; i++) {
+ vfp->mcv_reg[i] = tswap64(*aa32_vfp_dreg(env, i));
+ }
+ vfp->mcv_fpscr = tswap32(vfp_get_fpscr(env));
+ unlock_user(vfp, mcp->mc_vfp_ptr, sizeof(*vfp));
+ }
+ return err;
+}
+
+/* Compare to arm/arm/exec_machdep.c set_mcontext() */
+abi_long set_mcontext(CPUARMState *env, target_mcontext_t *mcp, int srflag)
+{
+ int err = 0;
+ const uint32_t *gr = mcp->__gregs;
+ uint32_t cpsr, ccpsr = cpsr_read(env);
+ uint32_t fpscr, mask;
+
+ cpsr = tswap32(gr[TARGET_REG_CPSR]);
+ /*
+ * Only allow certain bits to change, reject attempted changes to non-user
+ * bits. In addition, make sure we're headed for user mode and none of the
+ * interrupt bits are set.
+ */
+ if ((ccpsr & ~CPSR_USER) != (cpsr & ~CPSR_USER)) {
+ return -TARGET_EINVAL;
+ }
+ if ((cpsr & CPSR_M) != ARM_CPU_MODE_USR ||
+ (cpsr & (CPSR_I | CPSR_F)) != 0) {
+ return -TARGET_EINVAL;
+ }
+
+ /*
+ * The movs pc,lr instruction that implements the return to userland masks
+ * these bits out.
+ */
+ mask = cpsr & CPSR_T ? 0x1 : 0x3;
+
+ /*
+ * Make sure that we either have no vfp, or it's the correct size.
+ * FreeBSD just ignores it, though, so maybe we'll need to adjust
+ * things below instead.
+ */
+ if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size != sizeof(target_mcontext_vfp_t)) {
+ return -TARGET_EINVAL;
+ }
+
+ env->regs[0] = tswap32(gr[TARGET_REG_R0]);
+ env->regs[1] = tswap32(gr[TARGET_REG_R1]);
+ env->regs[2] = tswap32(gr[TARGET_REG_R2]);
+ env->regs[3] = tswap32(gr[TARGET_REG_R3]);
+ env->regs[4] = tswap32(gr[TARGET_REG_R4]);
+ env->regs[5] = tswap32(gr[TARGET_REG_R5]);
+ env->regs[6] = tswap32(gr[TARGET_REG_R6]);
+ env->regs[7] = tswap32(gr[TARGET_REG_R7]);
+ env->regs[8] = tswap32(gr[TARGET_REG_R8]);
+ env->regs[9] = tswap32(gr[TARGET_REG_R9]);
+ env->regs[10] = tswap32(gr[TARGET_REG_R10]);
+ env->regs[11] = tswap32(gr[TARGET_REG_R11]);
+ env->regs[12] = tswap32(gr[TARGET_REG_R12]);
+
+ env->regs[13] = tswap32(gr[TARGET_REG_SP]);
+ env->regs[14] = tswap32(gr[TARGET_REG_LR]);
+ env->regs[15] = tswap32(gr[TARGET_REG_PC] & ~mask);
+ if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_ptr != 0) {
+ /* see set_vfpcontext in sys/arm/arm/exec_machdep.c */
+ target_mcontext_vfp_t *vfp;
+
+ vfp = lock_user(VERIFY_READ, mcp->mc_vfp_ptr, sizeof(*vfp), 1);
+ for (int i = 0; i < 32; i++) {
+ __get_user(*aa32_vfp_dreg(env, i), &vfp->mcv_reg[i]);
+ }
+ __get_user(fpscr, &vfp->mcv_fpscr);
+ vfp_set_fpscr(env, fpscr);
+ unlock_user(vfp, mcp->mc_vfp_ptr, sizeof(target_ucontext_t));
+
+ /*
+ * linux-user sets fpexc, fpinst and fpinst2, but these aren't in
+ * FreeBSD's mcontext, what to do?
+ */
+ }
+ cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
+
+ return err;
+}
+
+/* Compare to arm/arm/machdep.c sys_sigreturn() */
+abi_long get_ucontext_sigreturn(CPUARMState *env, abi_ulong target_sf,
+ abi_ulong *target_uc)
+{
+ *target_uc = target_sf;
+
+ return 0;
+}
diff --git a/bsd-user/arm/target_arch.h b/bsd-user/arm/target_arch.h
new file mode 100644
index 0000000..93cfaea
--- /dev/null
+++ b/bsd-user/arm/target_arch.h
@@ -0,0 +1,28 @@
+/*
+ * ARM 32-bit specific prototypes for bsd-user
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TARGET_ARCH_H_
+#define _TARGET_ARCH_H_
+
+#include "qemu.h"
+
+void target_cpu_set_tls(CPUARMState *env, target_ulong newtls);
+target_ulong target_cpu_get_tls(CPUARMState *env);
+
+#endif /* !_TARGET_ARCH_H_ */
diff --git a/bsd-user/arm/target_arch_cpu.c b/bsd-user/arm/target_arch_cpu.c
new file mode 100644
index 0000000..02bf914
--- /dev/null
+++ b/bsd-user/arm/target_arch_cpu.c
@@ -0,0 +1,39 @@
+/*
+ * arm cpu related code
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "target_arch.h"
+
+void target_cpu_set_tls(CPUARMState *env, target_ulong newtls)
+{
+ if (access_secure_reg(env)) {
+ env->cp15.tpidrurw_s = newtls;
+ env->cp15.tpidruro_s = newtls;
+ return;
+ }
+
+ env->cp15.tpidr_el[0] = newtls;
+ env->cp15.tpidrro_el[0] = newtls;
+}
+
+target_ulong target_cpu_get_tls(CPUARMState *env)
+{
+ if (access_secure_reg(env)) {
+ return env->cp15.tpidruro_s;
+ }
+ return env->cp15.tpidrro_el[0];
+}
diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h
new file mode 100644
index 0000000..c675419
--- /dev/null
+++ b/bsd-user/arm/target_arch_cpu.h
@@ -0,0 +1,211 @@
+/*
+ * arm cpu init and loop
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TARGET_ARCH_CPU_H_
+#define _TARGET_ARCH_CPU_H_
+
+#include "target_arch.h"
+
+#define TARGET_DEFAULT_CPU_MODEL "any"
+
+static inline void target_cpu_init(CPUARMState *env,
+ struct target_pt_regs *regs)
+{
+ int i;
+
+ cpsr_write(env, regs->uregs[16], CPSR_USER | CPSR_EXEC,
+ CPSRWriteByInstr);
+ for (i = 0; i < 16; i++) {
+ env->regs[i] = regs->uregs[i];
+ }
+}
+
+static inline void target_cpu_loop(CPUARMState *env)
+{
+ int trapnr;
+ target_siginfo_t info;
+ unsigned int n;
+ CPUState *cs = env_cpu(env);
+
+ for (;;) {
+ cpu_exec_start(cs);
+ trapnr = cpu_exec(cs);
+ cpu_exec_end(cs);
+ process_queued_cpu_work(cs);
+ switch (trapnr) {
+ case EXCP_UDEF:
+ {
+ /* See arm/arm/undefined.c undefinedinstruction(); */
+ info.si_addr = env->regs[15];
+
+ /* illegal instruction */
+ info.si_signo = TARGET_SIGILL;
+ info.si_errno = 0;
+ info.si_code = TARGET_ILL_ILLOPC;
+ queue_signal(env, info.si_signo, &info);
+
+ /* TODO: What about instruction emulation? */
+ }
+ break;
+ case EXCP_SWI:
+ case EXCP_BKPT:
+ {
+ /*
+ * system call
+ * See arm/arm/trap.c cpu_fetch_syscall_args()
+ */
+ if (trapnr == EXCP_BKPT) {
+ if (env->thumb) {
+ env->regs[15] += 2;
+ } else {
+ env->regs[15] += 4;
+ }
+ }
+ n = env->regs[7];
+ if (bsd_type == target_freebsd) {
+ int ret;
+ abi_ulong params = get_sp_from_cpustate(env);
+ int32_t syscall_nr = n;
+ int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
+
+ /* See arm/arm/trap.c cpu_fetch_syscall_args() */
+ if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
+ syscall_nr = env->regs[0];
+ arg1 = env->regs[1];
+ arg2 = env->regs[2];
+ arg3 = env->regs[3];
+ get_user_s32(arg4, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg5, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg6, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg7, params);
+ arg8 = 0;
+ } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
+ syscall_nr = env->regs[0];
+ arg1 = env->regs[2];
+ arg2 = env->regs[3];
+ get_user_s32(arg3, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg4, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg5, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg6, params);
+ arg7 = 0;
+ arg8 = 0;
+ } else {
+ arg1 = env->regs[0];
+ arg2 = env->regs[1];
+ arg3 = env->regs[2];
+ arg4 = env->regs[3];
+ get_user_s32(arg5, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg6, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg7, params);
+ params += sizeof(int32_t);
+ get_user_s32(arg8, params);
+ }
+ ret = do_freebsd_syscall(env, syscall_nr, arg1, arg2, arg3,
+ arg4, arg5, arg6, arg7, arg8);
+ /*
+ * Compare to arm/arm/vm_machdep.c
+ * cpu_set_syscall_retval()
+ */
+ if (-TARGET_EJUSTRETURN == ret) {
+ /*
+ * Returning from a successful sigreturn syscall.
+ * Avoid clobbering register state.
+ */
+ break;
+ }
+ if (-TARGET_ERESTART == ret) {
+ env->regs[15] -= env->thumb ? 2 : 4;
+ break;
+ }
+ if ((unsigned int)ret >= (unsigned int)(-515)) {
+ ret = -ret;
+ cpsr_write(env, CPSR_C, CPSR_C, CPSRWriteByInstr);
+ env->regs[0] = ret;
+ } else {
+ cpsr_write(env, 0, CPSR_C, CPSRWriteByInstr);
+ env->regs[0] = ret; /* XXX need to handle lseek()? */
+ /* env->regs[1] = 0; */
+ }
+ } else {
+ fprintf(stderr, "qemu: bsd_type (= %d) syscall "
+ "not supported\n", bsd_type);
+ }
+ }
+ break;
+ case EXCP_INTERRUPT:
+ /* just indicate that signals should be handled asap */
+ break;
+ case EXCP_PREFETCH_ABORT:
+ /* See arm/arm/trap.c prefetch_abort_handler() */
+ case EXCP_DATA_ABORT:
+ /* See arm/arm/trap.c data_abort_handler() */
+ info.si_signo = TARGET_SIGSEGV;
+ info.si_errno = 0;
+ /* XXX: check env->error_code */
+ info.si_code = 0;
+ info.si_addr = env->exception.vaddress;
+ queue_signal(env, info.si_signo, &info);
+ break;
+ case EXCP_DEBUG:
+ {
+
+ info.si_signo = TARGET_SIGTRAP;
+ info.si_errno = 0;
+ info.si_code = TARGET_TRAP_BRKPT;
+ info.si_addr = env->exception.vaddress;
+ queue_signal(env, info.si_signo, &info);
+ }
+ break;
+ case EXCP_ATOMIC:
+ cpu_exec_step_atomic(cs);
+ break;
+ case EXCP_YIELD:
+ /* nothing to do here for user-mode, just resume guest code */
+ break;
+ default:
+ fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
+ trapnr);
+ cpu_dump_state(cs, stderr, 0);
+ abort();
+ } /* switch() */
+ process_pending_signals(env);
+ } /* for (;;) */
+}
+
+static inline void target_cpu_clone_regs(CPUARMState *env, target_ulong newsp)
+{
+ if (newsp) {
+ env->regs[13] = newsp;
+ }
+ env->regs[0] = 0;
+}
+
+static inline void target_cpu_reset(CPUArchState *cpu)
+{
+}
+
+#endif /* !_TARGET_ARCH_CPU_H */
diff --git a/bsd-user/arm/target_arch_elf.h b/bsd-user/arm/target_arch_elf.h
new file mode 100644
index 0000000..4a0215d
--- /dev/null
+++ b/bsd-user/arm/target_arch_elf.h
@@ -0,0 +1,128 @@
+/*
+ * arm ELF definitions
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _TARGET_ARCH_ELF_H_
+#define _TARGET_ARCH_ELF_H_
+
+#define ELF_START_MMAP 0x80000000
+#define ELF_ET_DYN_LOAD_ADDR 0x500000
+
+#define elf_check_arch(x) ((x) == EM_ARM)
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_ARM
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_HWCAP get_elf_hwcap()
+#define ELF_HWCAP2 get_elf_hwcap2()
+
+#define GET_FEATURE(feat, hwcap) \
+ do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+
+#define GET_FEATURE_ID(feat, hwcap) \
+ do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
+
+enum {
+ ARM_HWCAP_ARM_SWP = 1 << 0,
+ ARM_HWCAP_ARM_HALF = 1 << 1,
+ ARM_HWCAP_ARM_THUMB = 1 << 2,
+ ARM_HWCAP_ARM_26BIT = 1 << 3,
+ ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
+ ARM_HWCAP_ARM_FPA = 1 << 5,
+ ARM_HWCAP_ARM_VFP = 1 << 6,
+ ARM_HWCAP_ARM_EDSP = 1 << 7,
+ ARM_HWCAP_ARM_JAVA = 1 << 8,
+ ARM_HWCAP_ARM_IWMMXT = 1 << 9,
+ ARM_HWCAP_ARM_CRUNCH = 1 << 10,
+ ARM_HWCAP_ARM_THUMBEE = 1 << 11,
+ ARM_HWCAP_ARM_NEON = 1 << 12,
+ ARM_HWCAP_ARM_VFPv3 = 1 << 13,
+ ARM_HWCAP_ARM_VFPv3D16 = 1 << 14,
+ ARM_HWCAP_ARM_TLS = 1 << 15,
+ ARM_HWCAP_ARM_VFPv4 = 1 << 16,
+ ARM_HWCAP_ARM_IDIVA = 1 << 17,
+ ARM_HWCAP_ARM_IDIVT = 1 << 18,
+ ARM_HWCAP_ARM_VFPD32 = 1 << 19,
+ ARM_HWCAP_ARM_LPAE = 1 << 20,
+ ARM_HWCAP_ARM_EVTSTRM = 1 << 21,
+};
+
+enum {
+ ARM_HWCAP2_ARM_AES = 1 << 0,
+ ARM_HWCAP2_ARM_PMULL = 1 << 1,
+ ARM_HWCAP2_ARM_SHA1 = 1 << 2,
+ ARM_HWCAP2_ARM_SHA2 = 1 << 3,
+ ARM_HWCAP2_ARM_CRC32 = 1 << 4,
+};
+
+static uint32_t get_elf_hwcap(void)
+{
+ ARMCPU *cpu = ARM_CPU(thread_cpu);
+ uint32_t hwcaps = 0;
+
+ hwcaps |= ARM_HWCAP_ARM_SWP;
+ hwcaps |= ARM_HWCAP_ARM_HALF;
+ hwcaps |= ARM_HWCAP_ARM_THUMB;
+ hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
+
+ /* probe for the extra features */
+ /* EDSP is in v5TE and above */
+ GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
+ GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
+ GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
+ GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
+ GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
+ GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
+ GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
+ GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
+ GET_FEATURE_ID(aa32_vfp, ARM_HWCAP_ARM_VFP);
+
+ if (cpu_isar_feature(aa32_fpsp_v3, cpu) ||
+ cpu_isar_feature(aa32_fpdp_v3, cpu)) {
+ hwcaps |= ARM_HWCAP_ARM_VFPv3;
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
+ hwcaps |= ARM_HWCAP_ARM_VFPD32;
+ } else {
+ hwcaps |= ARM_HWCAP_ARM_VFPv3D16;
+ }
+ }
+ GET_FEATURE_ID(aa32_simdfmac, ARM_HWCAP_ARM_VFPv4);
+
+ return hwcaps;
+}
+
+static uint32_t get_elf_hwcap2(void)
+{
+ ARMCPU *cpu = ARM_CPU(thread_cpu);
+ uint32_t hwcaps = 0;
+
+ GET_FEATURE_ID(aa32_aes, ARM_HWCAP2_ARM_AES);
+ GET_FEATURE_ID(aa32_pmull, ARM_HWCAP2_ARM_PMULL);
+ GET_FEATURE_ID(aa32_sha1, ARM_HWCAP2_ARM_SHA1);
+ GET_FEATURE_ID(aa32_sha2, ARM_HWCAP2_ARM_SHA2);
+ GET_FEATURE_ID(aa32_crc32, ARM_HWCAP2_ARM_CRC32);
+ return hwcaps;
+}
+
+#undef GET_FEATURE
+#undef GET_FEATURE_ID
+
+#endif /* _TARGET_ARCH_ELF_H_ */
diff --git a/bsd-user/arm/target_arch_reg.h b/bsd-user/arm/target_arch_reg.h
new file mode 100644
index 0000000..ef5ed51
--- /dev/null
+++ b/bsd-user/arm/target_arch_reg.h
@@ -0,0 +1,60 @@
+/*
+ * FreeBSD arm register structures
+ *
+ * Copyright (c) 2015 Stacey Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TARGET_ARCH_REG_H_
+#define _TARGET_ARCH_REG_H_
+
+/* See sys/arm/include/reg.h */
+typedef struct target_reg {
+ uint32_t r[13];
+ uint32_t r_sp;
+ uint32_t r_lr;
+ uint32_t r_pc;
+ uint32_t r_cpsr;
+} target_reg_t;
+
+typedef struct target_fp_reg {
+ uint32_t fp_exponent;
+ uint32_t fp_mantissa_hi;
+ u_int32_t fp_mantissa_lo;
+} target_fp_reg_t;
+
+typedef struct target_fpreg {
+ uint32_t fpr_fpsr;
+ target_fp_reg_t fpr[8];
+} target_fpreg_t;
+
+#define tswapreg(ptr) tswapal(ptr)
+
+static inline void target_copy_regs(target_reg_t *regs, const CPUARMState *env)
+{
+ int i;
+
+ for (i = 0; i < 13; i++) {
+ regs->r[i] = tswapreg(env->regs[i + 1]);
+ }
+ regs->r_sp = tswapreg(env->regs[13]);
+ regs->r_lr = tswapreg(env->regs[14]);
+ regs->r_pc = tswapreg(env->regs[15]);
+ regs->r_cpsr = tswapreg(cpsr_read((CPUARMState *)env));
+}
+
+#undef tswapreg
+
+#endif /* !_TARGET_ARCH_REG_H_ */
diff --git a/bsd-user/arm/target_arch_signal.h b/bsd-user/arm/target_arch_signal.h
new file mode 100644
index 0000000..f1844db
--- /dev/null
+++ b/bsd-user/arm/target_arch_signal.h
@@ -0,0 +1,88 @@
+/*
+ * arm signal definitions
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _TARGET_ARCH_SIGNAL_H_
+#define _TARGET_ARCH_SIGNAL_H_
+
+#include "cpu.h"
+
+#define TARGET_REG_R0 0
+#define TARGET_REG_R1 1
+#define TARGET_REG_R2 2
+#define TARGET_REG_R3 3
+#define TARGET_REG_R4 4
+#define TARGET_REG_R5 5
+#define TARGET_REG_R6 6
+#define TARGET_REG_R7 7
+#define TARGET_REG_R8 8
+#define TARGET_REG_R9 9
+#define TARGET_REG_R10 10
+#define TARGET_REG_R11 11
+#define TARGET_REG_R12 12
+#define TARGET_REG_R13 13
+#define TARGET_REG_R14 14
+#define TARGET_REG_R15 15
+#define TARGET_REG_CPSR 16
+#define TARGET__NGREG 17
+/* Convenience synonyms */
+#define TARGET_REG_FP TARGET_REG_R11
+#define TARGET_REG_SP TARGET_REG_R13
+#define TARGET_REG_LR TARGET_REG_R14
+#define TARGET_REG_PC TARGET_REG_R15
+
+#define TARGET_INSN_SIZE 4 /* arm instruction size */
+
+/* Size of the signal trampolin code. See _sigtramp(). */
+#define TARGET_SZSIGCODE ((abi_ulong)(9 * TARGET_INSN_SIZE))
+
+/* compare to arm/include/_limits.h */
+#define TARGET_MINSIGSTKSZ (1024 * 4) /* min sig stack size */
+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) /* recommended size */
+
+/*
+ * Floating point register state
+ */
+typedef struct target_mcontext_vfp {
+ abi_ullong mcv_reg[32];
+ abi_ulong mcv_fpscr;
+} target_mcontext_vfp_t;
+
+typedef struct target_mcontext {
+ abi_uint __gregs[TARGET__NGREG];
+
+ /*
+ * Originally, rest of this structure was named __fpu, 35 * 4 bytes
+ * long, never accessed from kernel.
+ */
+ abi_ulong mc_vfp_size;
+ abi_ptr mc_vfp_ptr;
+ abi_int mc_spare[33];
+} target_mcontext_t;
+
+#define TARGET_MCONTEXT_SIZE 208
+#define TARGET_UCONTEXT_SIZE 260
+
+#include "target_os_ucontext.h"
+
+struct target_sigframe {
+ target_siginfo_t sf_si; /* saved siginfo */
+ target_ucontext_t sf_uc; /* saved ucontext */
+ target_mcontext_vfp_t sf_vfp; /* actual saved VFP context */
+};
+
+#endif /* !_TARGET_ARCH_SIGNAL_H_ */
diff --git a/bsd-user/arm/target_arch_sigtramp.h b/bsd-user/arm/target_arch_sigtramp.h
new file mode 100644
index 0000000..5d434a9
--- /dev/null
+++ b/bsd-user/arm/target_arch_sigtramp.h
@@ -0,0 +1,49 @@
+/*
+ * arm sysarch() system call emulation
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+/* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+ unsigned sys_sigreturn)
+{
+ int i;
+ uint32_t sys_exit = TARGET_FREEBSD_NR_exit;
+ uint32_t sigtramp_code[] = {
+ /* 1 */ 0xE1A0000D, /* mov r0, sp */
+ /* 2 */ 0xE2800000 + sigf_uc, /* add r0, r0, #SIGF_UC */
+ /* 3 */ 0xE59F700C, /* ldr r7, [pc, #12] */
+ /* 4 */ 0xEF000000 + sys_sigreturn, /* swi (SYS_sigreturn) */
+ /* 5 */ 0xE59F7008, /* ldr r7, [pc, #8] */
+ /* 6 */ 0xEF000000 + sys_exit, /* swi (SYS_exit)*/
+ /* 7 */ 0xEAFFFFFA, /* b . -16 */
+ /* 8 */ sys_sigreturn,
+ /* 9 */ sys_exit
+ };
+
+ G_STATIC_ASSERT(sizeof(sigtramp_code) == TARGET_SZSIGCODE);
+
+ for (i = 0; i < 9; i++) {
+ tswap32s(&sigtramp_code[i]);
+ }
+
+ return memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE);
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
diff --git a/bsd-user/arm/target_arch_sysarch.h b/bsd-user/arm/target_arch_sysarch.h
index 632a5cd..8cc6bff 100644
--- a/bsd-user/arm/target_arch_sysarch.h
+++ b/bsd-user/arm/target_arch_sysarch.h
@@ -17,8 +17,8 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BSD_USER_ARCH_SYSARCH_H_
-#define BSD_USER_ARCH_SYSARCH_H_
+#ifndef _TARGET_ARCH_SYSARCH_H_
+#define _TARGET_ARCH_SYSARCH_H_
#include "target_syscall.h"
#include "target_arch.h"
@@ -75,4 +75,4 @@ static inline void do_freebsd_arch_print_sysarch(
}
}
-#endif /*!BSD_USER_ARCH_SYSARCH_H_ */
+#endif /*!_TARGET_ARCH_SYSARCH_H_ */
diff --git a/bsd-user/arm/target_arch_thread.h b/bsd-user/arm/target_arch_thread.h
new file mode 100644
index 0000000..11c7f76
--- /dev/null
+++ b/bsd-user/arm/target_arch_thread.h
@@ -0,0 +1,82 @@
+/*
+ * arm thread support
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _TARGET_ARCH_THREAD_H_
+#define _TARGET_ARCH_THREAD_H_
+
+/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
+static inline void target_thread_set_upcall(CPUARMState *env, abi_ulong entry,
+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size)
+{
+ abi_ulong sp;
+
+ /*
+ * Make sure the stack is properly aligned.
+ * arm/include/param.h (STACKLIGN() macro)
+ */
+ sp = (u_int)(stack_base + stack_size) & ~0x7;
+
+ /* sp = stack base */
+ env->regs[13] = sp;
+ /* pc = start function entry */
+ env->regs[15] = entry & 0xfffffffe;
+ /* r0 = arg */
+ env->regs[0] = arg;
+ env->spsr = ARM_CPU_MODE_USR;
+ /*
+ * Thumb mode is encoded by the low bit in the entry point (since ARM can't
+ * execute at odd addresses). When it's set, set the Thumb bit (T) in the
+ * CPSR.
+ */
+ cpsr_write(env, (entry & 1) * CPSR_T, CPSR_T, CPSRWriteByInstr);
+}
+
+static inline void target_thread_init(struct target_pt_regs *regs,
+ struct image_info *infop)
+{
+ abi_long stack = infop->start_stack;
+ memset(regs, 0, sizeof(*regs));
+ regs->ARM_cpsr = ARM_CPU_MODE_USR;
+ /*
+ * Thumb mode is encoded by the low bit in the entry point (since ARM can't
+ * execute at odd addresses). When it's set, set the Thumb bit (T) in the
+ * CPSR.
+ */
+ if (infop->entry & 1) {
+ regs->ARM_cpsr |= CPSR_T;
+ }
+ regs->ARM_pc = infop->entry & 0xfffffffe;
+ regs->ARM_sp = stack;
+ if (bsd_type == target_freebsd) {
+ regs->ARM_lr = infop->entry & 0xfffffffe;
+ }
+ /*
+ * FreeBSD kernel passes the ps_strings pointer in r0. This is used by some
+ * programs to set status messages that we see in ps. bsd-user doesn't
+ * support that functionality, so it's ignored. When set to 0, FreeBSD's csu
+ * code ignores it. For the static case, r1 and r2 are effectively ignored
+ * by the csu __startup() routine. For the dynamic case, rtld saves r0 but
+ * generates r1 and r2 and passes them into the csu _startup.
+ *
+ * r0 ps_strings 0 passed since ps arg setting not supported
+ * r1 obj_main ignored by _start(), so 0 passed
+ * r2 cleanup generated by rtld or ignored by _start(), so 0 passed
+ */
+}
+
+#endif /* !_TARGET_ARCH_THREAD_H_ */
diff --git a/bsd-user/arm/target_arch_vmparam.h b/bsd-user/arm/target_arch_vmparam.h
new file mode 100644
index 0000000..4bbc04d
--- /dev/null
+++ b/bsd-user/arm/target_arch_vmparam.h
@@ -0,0 +1,48 @@
+/*
+ * arm VM parameters definitions
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _TARGET_ARCH_VMPARAM_H_
+#define _TARGET_ARCH_VMPARAM_H_
+
+#include "cpu.h"
+
+/* compare to sys/arm/include/vmparam.h */
+#define TARGET_MAXTSIZ (64 * MiB) /* max text size */
+#define TARGET_DFLDSIZ (128 * MiB) /* initial data size limit */
+#define TARGET_MAXDSIZ (512 * MiB) /* max data size */
+#define TARGET_DFLSSIZ (4 * MiB) /* initial stack size limit */
+#define TARGET_MAXSSIZ (64 * MiB) /* max stack size */
+#define TARGET_SGROWSIZ (128 * KiB) /* amount to grow stack */
+
+#define TARGET_RESERVED_VA 0xf7000000
+
+ /* KERNBASE - 512 MB */
+#define TARGET_VM_MAXUSER_ADDRESS (0xc0000000 - (512 * MiB))
+#define TARGET_USRSTACK TARGET_VM_MAXUSER_ADDRESS
+
+static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
+{
+ return state->regs[13]; /* sp */
+}
+
+static inline void set_second_rval(CPUARMState *state, abi_ulong retval2)
+{
+ state->regs[1] = retval2;
+}
+
+#endif /* ! _TARGET_ARCH_VMPARAM_H_ */
diff --git a/bsd-user/arm/target_syscall.h b/bsd-user/arm/target_syscall.h
index ef4b37f..a5f2bb4 100644
--- a/bsd-user/arm/target_syscall.h
+++ b/bsd-user/arm/target_syscall.h
@@ -1,5 +1,24 @@
-#ifndef BSD_USER_ARCH_SYSCALL_H_
-#define BSD_USER_ARCH_SYSCALL_H_
+/*
+ * arm cpu system call stubs
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TARGET_ARCH_SYSCALL_H_
+#define _TARGET_ARCH_SYSCALL_H_
struct target_pt_regs {
abi_long uregs[17];
@@ -31,6 +50,6 @@ struct target_pt_regs {
#define TARGET_FREEBSD_ARM_GET_TP 3
#define TARGET_HW_MACHINE "arm"
-#define TARGET_HW_MACHINE_ARCH "armv6"
+#define TARGET_HW_MACHINE_ARCH "armv7"
-#endif /* !BSD_USER_ARCH_SYSCALL_H_ */
+#endif /* !_TARGET_ARCH_SYSCALL_H_ */
diff --git a/bsd-user/freebsd/target_os_signal.h b/bsd-user/freebsd/target_os_signal.h
index 1a4c5fa..3ed454e 100644
--- a/bsd-user/freebsd/target_os_signal.h
+++ b/bsd-user/freebsd/target_os_signal.h
@@ -1,9 +1,6 @@
#ifndef _TARGET_OS_SIGNAL_H_
#define _TARGET_OS_SIGNAL_H_
-/* FreeBSD's sys/ucontext.h defines this */
-#define TARGET_MC_GET_CLEAR_RET 0x0001
-
#include "target_os_siginfo.h"
#include "target_arch_signal.h"
diff --git a/bsd-user/freebsd/target_os_ucontext.h b/bsd-user/freebsd/target_os_ucontext.h
new file mode 100644
index 0000000..41b28b2
--- /dev/null
+++ b/bsd-user/freebsd/target_os_ucontext.h
@@ -0,0 +1,44 @@
+/*
+ * FreeBSD has a common ucontext definition for all architectures.
+ *
+ * Copyright 2021 Warner Losh <imp@bsdimp.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
+ */
+#ifndef TARGET_OS_UCONTEXT_H
+#define TARGET_OS_UCONTEXT_H
+
+/*
+ * Defines the common bits for all of FreeBSD's architectures. Has to be
+ * included AFTER the MD target_mcontext_t is defined, however, so can't
+ * be in the grab-bag that is target_os_signal.h.
+ */
+
+/* See FreeBSD's sys/ucontext.h */
+#define TARGET_MC_GET_CLEAR_RET 0x0001
+
+/* FreeBSD's sys/_ucontext.h structures */
+typedef struct target_ucontext {
+ target_sigset_t uc_sigmask;
+ target_mcontext_t uc_mcontext;
+ abi_ulong uc_link;
+ target_stack_t uc_stack;
+ int32_t uc_flags;
+ int32_t __spare__[4];
+} target_ucontext_t;
+
+G_STATIC_ASSERT(TARGET_MCONTEXT_SIZE == sizeof(target_mcontext_t));
+G_STATIC_ASSERT(TARGET_UCONTEXT_SIZE == sizeof(target_ucontext_t));
+
+struct target_sigframe;
+
+abi_long set_sigtramp_args(CPUArchState *env, int sig,
+ struct target_sigframe *frame,
+ abi_ulong frame_addr,
+ struct target_sigaction *ka);
+abi_long get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags);
+abi_long set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int srflag);
+abi_long get_ucontext_sigreturn(CPUArchState *regs, abi_ulong target_sf,
+ abi_ulong *target_uc);
+
+#endif /* TARGET_OS_UCONTEXT_H */
diff --git a/bsd-user/i386/signal.c b/bsd-user/i386/signal.c
new file mode 100644
index 0000000..2939d32
--- /dev/null
+++ b/bsd-user/i386/signal.c
@@ -0,0 +1,55 @@
+/*
+ * i386 dependent signal definitions
+ *
+ * Copyright (c) 2013 Stacey D. Son
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu.h"
+
+/*
+ * Compare to i386/i386/machdep.c sendsig()
+ * Assumes that target stack frame memory is locked.
+ */
+abi_long set_sigtramp_args(CPUX86State *env, int sig,
+ struct target_sigframe *frame,
+ abi_ulong frame_addr,
+ struct target_sigaction *ka)
+{
+ /* XXX return -TARGET_EOPNOTSUPP; */
+ return 0;
+}
+
+/* Compare to i386/i386/machdep.c get_mcontext() */
+abi_long get_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int flags)
+{
+ /* XXX */
+ return -TARGET_EOPNOTSUPP;
+}
+
+/* Compare to i386/i386/machdep.c set_mcontext() */
+abi_long set_mcontext(CPUX86State *regs, target_mcontext_t *mcp, int srflag)
+{
+ /* XXX */
+ return -TARGET_EOPNOTSUPP;
+}
+
+abi_long get_ucontext_sigreturn(CPUX86State *regs, abi_ulong target_sf,
+ abi_ulong *target_uc)
+{
+ /* XXX */
+ *target_uc = 0;
+ return -TARGET_EOPNOTSUPP;
+}
diff --git a/bsd-user/i386/target_arch_signal.h b/bsd-user/i386/target_arch_signal.h
index a90750d..279dadc 100644
--- a/bsd-user/i386/target_arch_signal.h
+++ b/bsd-user/i386/target_arch_signal.h
@@ -27,21 +27,56 @@
#define TARGET_MINSIGSTKSZ (512 * 4) /* min sig stack size */
#define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended size */
-struct target_sigcontext {
- /* to be added */
-};
-
typedef struct target_mcontext {
+ abi_ulong mc_onstack; /* XXX - sigcontext compat. */
+ abi_ulong mc_gs; /* machine state (struct trapframe) */
+ abi_ulong mc_fs;
+ abi_ulong mc_es;
+ abi_ulong mc_ds;
+ abi_ulong mc_edi;
+ abi_ulong mc_esi;
+ abi_ulong mc_ebp;
+ abi_ulong mc_isp;
+ abi_ulong mc_ebx;
+ abi_ulong mc_edx;
+ abi_ulong mc_ecx;
+ abi_ulong mc_eax;
+ abi_ulong mc_trapno;
+ abi_ulong mc_err;
+ abi_ulong mc_eip;
+ abi_ulong mc_cs;
+ abi_ulong mc_eflags;
+ abi_ulong mc_esp;
+ abi_ulong mc_ss;
+
+ int32_t mc_len; /* sizeof(mcontext_t) */
+#define _MC_FPFMT_NODEV 0x10000 /* device not present or configured */
+#define _MC_FPFMT_387 0x10001
+#define _MC_FPFMT_XMM 0x10002
+ int32_t mc_fpformat;
+#define _MC_FPOWNED_NONE 0x20000 /* FP state not used */
+#define _MC_FPOWNED_FPU 0x20001 /* FP state came from FPU */
+#define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */
+ int32_t mc_ownedfp;
+ abi_ulong mc_flags;
+ /*
+ * See <machine/npx.h> for the internals of mc_fpstate[].
+ */
+ int32_t mc_fpstate[128] __aligned(16);
+
+ abi_ulong mc_fsbase;
+ abi_ulong mc_gsbase;
+
+ abi_ulong mc_xfpustate;
+ abi_ulong mc_xfpustate_len;
+
+ int32_t mc_spare2[4];
} target_mcontext_t;
-typedef struct target_ucontext {
- target_sigset_t uc_sigmask;
- target_mcontext_t uc_mcontext;
- abi_ulong uc_link;
- target_stack_t uc_stack;
- int32_t uc_flags;
- int32_t __spare__[4];
-} target_ucontext_t;
+#define TARGET_MCONTEXT_SIZE 640
+#define TARGET_UCONTEXT_SIZE 704
+
+#include "target_os_ucontext.h"
struct target_sigframe {
abi_ulong sf_signum;
@@ -53,40 +88,4 @@ struct target_sigframe {
uint32_t __spare__[2];
};
-/*
- * Compare to i386/i386/machdep.c sendsig()
- * Assumes that target stack frame memory is locked.
- */
-static inline abi_long set_sigtramp_args(CPUX86State *regs,
- int sig, struct target_sigframe *frame, abi_ulong frame_addr,
- struct target_sigaction *ka)
-{
- /* XXX return -TARGET_EOPNOTSUPP; */
- return 0;
-}
-
-/* Compare to i386/i386/machdep.c get_mcontext() */
-static inline abi_long get_mcontext(CPUX86State *regs,
- target_mcontext_t *mcp, int flags)
-{
- /* XXX */
- return -TARGET_EOPNOTSUPP;
-}
-
-/* Compare to i386/i386/machdep.c set_mcontext() */
-static inline abi_long set_mcontext(CPUX86State *regs,
- target_mcontext_t *mcp, int srflag)
-{
- /* XXX */
- return -TARGET_EOPNOTSUPP;
-}
-
-static inline abi_long get_ucontext_sigreturn(CPUX86State *regs,
- abi_ulong target_sf, abi_ulong *target_uc)
-{
- /* XXX */
- *target_uc = 0;
- return -TARGET_EOPNOTSUPP;
-}
-
#endif /* TARGET_ARCH_SIGNAL_H */
diff --git a/bsd-user/mips/target_arch_sysarch.h b/bsd-user/mips/target_arch_sysarch.h
deleted file mode 100644
index 6da803a..0000000
--- a/bsd-user/mips/target_arch_sysarch.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * mips sysarch() system call emulation
- *
- * Copyright (c) 2013 Stacey D. Son
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef BSD_USER_ARCH_SYSARCH_H_
-#define BSD_USER_ARCH_SYSARCH_H_
-
-#include "target_syscall.h"
-#include "target_arch.h"
-
-static inline abi_long do_freebsd_arch_sysarch(CPUMIPSState *env, int op,
- abi_ulong parms)
-{
- int ret = 0;
-
- switch (op) {
- case TARGET_MIPS_SET_TLS:
- target_cpu_set_tls(env, parms);
- break;
-
- case TARGET_MIPS_GET_TLS:
- if (put_user(target_cpu_get_tls(env), parms, abi_ulong)) {
- ret = -TARGET_EFAULT;
- }
- break;
-
- default:
- ret = -TARGET_EINVAL;
- break;
- }
-
- return ret;
-}
-
-static inline void do_freebsd_arch_print_sysarch(
- const struct syscallname *name, abi_long arg1, abi_long arg2,
- abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
-{
-
- switch (arg1) {
- case TARGET_MIPS_SET_TLS:
- gemu_log("%s(SET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
- break;
-
- case TARGET_MIPS_GET_TLS:
- gemu_log("%s(GET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
- break;
-
- default:
- gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", (int)arg1, arg2);
- }
-}
-
-#endif /*!BSD_USER_ARCH_SYSARCH_H_ */
diff --git a/bsd-user/mips/target_syscall.h b/bsd-user/mips/target_syscall.h
deleted file mode 100644
index aacc6dd..0000000
--- a/bsd-user/mips/target_syscall.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * mips system call definitions
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _MIPS_SYSCALL_H_
-#define _MIPS_SYSCALL_H_
-
-/*
- * struct target_pt_regs defines the way the registers are stored on the stack
- * during a system call.
- */
-
-struct target_pt_regs {
- /* Saved main processor registers. */
- abi_ulong regs[32];
-
- /* Saved special registers. */
- abi_ulong cp0_status;
- abi_ulong lo;
- abi_ulong hi;
- abi_ulong cp0_badvaddr;
- abi_ulong cp0_cause;
- abi_ulong cp0_epc;
-};
-
-#if defined(TARGET_WORDS_BIGENDIAN)
-#define UNAME_MACHINE "mips"
-#else
-#define UNAME_MACHINE "mipsel"
-#endif
-
-#define TARGET_HW_MACHINE "mips"
-#define TARGET_HW_MACHINE_ARCH UNAME_MACHINE
-
-/* sysarch() commands */
-#define TARGET_MIPS_SET_TLS 1
-#define TARGET_MIPS_GET_TLS 2
-
-#endif /* !_MIPS_SYSCALL_H_ */
diff --git a/bsd-user/mips64/target_arch_sysarch.h b/bsd-user/mips64/target_arch_sysarch.h
deleted file mode 100644
index e6f9c00..0000000
--- a/bsd-user/mips64/target_arch_sysarch.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * mips64 sysarch() system call emulation
- *
- * Copyright (c) 2013 Stacey D. Son
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef BSD_USER_ARCH_SYSARCH_H_
-#define BSD_USER_ARCH_SYSARCH_H_
-
-#include "target_syscall.h"
-#include "target_arch.h"
-
-static inline abi_long do_freebsd_arch_sysarch(CPUMIPSState *env, int op,
- abi_ulong parms)
-{
- int ret = 0;
-
- switch (op) {
- case TARGET_MIPS_SET_TLS:
- target_cpu_set_tls(env, parms);
- break;
-
- case TARGET_MIPS_GET_TLS:
- if (put_user(target_cpu_get_tls(env), parms, abi_ulong)) {
- ret = -TARGET_EFAULT;
- }
- break;
-
- default:
- ret = -TARGET_EINVAL;
- break;
- }
-
- return ret;
-}
-
-static inline void do_freebsd_arch_print_sysarch(
- const struct syscallname *name, abi_long arg1, abi_long arg2,
- abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
-{
-
- switch (arg1) {
- case TARGET_MIPS_SET_TLS:
- gemu_log("%s(SET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
- break;
-
- case TARGET_MIPS_GET_TLS:
- gemu_log("%s(GET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
- break;
-
- default:
- gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", (int)arg1, arg2);
- }
-}
-
-#endif /*!BSD_USER_ARCH_SYSARCH_H_ */
diff --git a/bsd-user/mips64/target_syscall.h b/bsd-user/mips64/target_syscall.h
deleted file mode 100644
index bf4c598..0000000
--- a/bsd-user/mips64/target_syscall.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * mips64 system call definitions
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef _MIPS64_SYSCALL_H_
-#define _MIPS64_SYSCALL_H_
-
-/*
- * struct target_pt_regs defines the way the registers are stored on the stack
- * during a system call.
- */
-
-struct target_pt_regs {
- /* Saved main processor registers. */
- abi_ulong regs[32];
-
- /* Saved special registers. */
- abi_ulong cp0_status;
- abi_ulong lo;
- abi_ulong hi;
- abi_ulong cp0_badvaddr;
- abi_ulong cp0_cause;
- abi_ulong cp0_epc;
-};
-
-
-#if defined(TARGET_WORDS_BIGENDIAN)
-#define UNAME_MACHINE "mips64"
-#else
-#define UNAME_MACHINE "mips64el"
-#endif
-
-#define TARGET_HW_MACHINE "mips"
-#define TARGET_HW_MACHINE_ARCH UNAME_MACHINE
-
-/* sysarch() commands */
-#define TARGET_MIPS_SET_TLS 1
-#define TARGET_MIPS_GET_TLS 2
-
-#endif /* !_MIPS64_SYSCALL_H_ */
diff --git a/bsd-user/x86_64/signal.c b/bsd-user/x86_64/signal.c
new file mode 100644
index 0000000..8885152
--- /dev/null
+++ b/bsd-user/x86_64/signal.c
@@ -0,0 +1,55 @@
+/*
+ * x86_64 signal definitions
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu.h"
+
+/*
+ * Compare to amd64/amd64/machdep.c sendsig()
+ * Assumes that target stack frame memory is locked.
+ */
+abi_long set_sigtramp_args(CPUX86State *regs,
+ int sig, struct target_sigframe *frame, abi_ulong frame_addr,
+ struct target_sigaction *ka)
+{
+ /* XXX return -TARGET_EOPNOTSUPP; */
+ return 0;
+}
+
+/* Compare to amd64/amd64/machdep.c get_mcontext() */
+abi_long get_mcontext(CPUX86State *regs,
+ target_mcontext_t *mcp, int flags)
+{
+ /* XXX */
+ return -TARGET_EOPNOTSUPP;
+}
+
+/* Compare to amd64/amd64/machdep.c set_mcontext() */
+abi_long set_mcontext(CPUX86State *regs,
+ target_mcontext_t *mcp, int srflag)
+{
+ /* XXX */
+ return -TARGET_EOPNOTSUPP;
+}
+
+abi_long get_ucontext_sigreturn(CPUX86State *regs,
+ abi_ulong target_sf, abi_ulong *target_uc)
+{
+ /* XXX */
+ *target_uc = 0;
+ return -TARGET_EOPNOTSUPP;
+}
diff --git a/bsd-user/x86_64/target_arch_signal.h b/bsd-user/x86_64/target_arch_signal.h
index 4bb753b..b4a0ebf 100644
--- a/bsd-user/x86_64/target_arch_signal.h
+++ b/bsd-user/x86_64/target_arch_signal.h
@@ -27,21 +27,64 @@
#define TARGET_MINSIGSTKSZ (512 * 4) /* min sig stack size */
#define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended size */
-struct target_sigcontext {
- /* to be added */
-};
-
typedef struct target_mcontext {
+ abi_ulong mc_onstack; /* XXX - sigcontext compat. */
+ abi_ulong mc_rdi; /* machine state (struct trapframe) */
+ abi_ulong mc_rsi;
+ abi_ulong mc_rdx;
+ abi_ulong mc_rcx;
+ abi_ulong mc_r8;
+ abi_ulong mc_r9;
+ abi_ulong mc_rax;
+ abi_ulong mc_rbx;
+ abi_ulong mc_rbp;
+ abi_ulong mc_r10;
+ abi_ulong mc_r11;
+ abi_ulong mc_r12;
+ abi_ulong mc_r13;
+ abi_ulong mc_r14;
+ abi_ulong mc_r15;
+ uint32_t mc_trapno;
+ uint16_t mc_fs;
+ uint16_t mc_gs;
+ abi_ulong mc_addr;
+ uint32_t mc_flags;
+ uint16_t mc_es;
+ uint16_t mc_ds;
+ abi_ulong mc_err;
+ abi_ulong mc_rip;
+ abi_ulong mc_cs;
+ abi_ulong mc_rflags;
+ abi_ulong mc_rsp;
+ abi_ulong mc_ss;
+
+ abi_long mc_len; /* sizeof(mcontext_t) */
+
+#define _MC_FPFMT_NODEV 0x10000 /* device not present or configured */
+#define _MC_FPFMT_XMM 0x10002
+ abi_long mc_fpformat;
+#define _MC_FPOWNED_NONE 0x20000 /* FP state not used */
+#define _MC_FPOWNED_FPU 0x20001 /* FP state came from FPU */
+#define _MC_FPOWNED_PCB 0x20002 /* FP state came from PCB */
+ abi_long mc_ownedfp;
+ /*
+ * See <machine/fpu.h> for the internals of mc_fpstate[].
+ */
+ abi_long mc_fpstate[64] __aligned(16);
+
+ abi_ulong mc_fsbase;
+ abi_ulong mc_gsbase;
+
+ abi_ulong mc_xfpustate;
+ abi_ulong mc_xfpustate_len;
+
+ abi_long mc_spare[4];
} target_mcontext_t;
-typedef struct target_ucontext {
- target_sigset_t uc_sigmask;
- target_mcontext_t uc_mcontext;
- abi_ulong uc_link;
- target_stack_t uc_stack;
- int32_t uc_flags;
- int32_t __spare__[4];
-} target_ucontext_t;
+#define TARGET_MCONTEXT_SIZE 800
+#define TARGET_UCONTEXT_SIZE 880
+
+#include "target_os_ucontext.h"
struct target_sigframe {
abi_ulong sf_signum;
@@ -53,40 +96,4 @@ struct target_sigframe {
uint32_t __spare__[2];
};
-/*
- * Compare to amd64/amd64/machdep.c sendsig()
- * Assumes that target stack frame memory is locked.
- */
-static inline abi_long set_sigtramp_args(CPUX86State *regs,
- int sig, struct target_sigframe *frame, abi_ulong frame_addr,
- struct target_sigaction *ka)
-{
- /* XXX return -TARGET_EOPNOTSUPP; */
- return 0;
-}
-
-/* Compare to amd64/amd64/machdep.c get_mcontext() */
-static inline abi_long get_mcontext(CPUX86State *regs,
- target_mcontext_t *mcp, int flags)
-{
- /* XXX */
- return -TARGET_EOPNOTSUPP;
-}
-
-/* Compare to amd64/amd64/machdep.c set_mcontext() */
-static inline abi_long set_mcontext(CPUX86State *regs,
- target_mcontext_t *mcp, int srflag)
-{
- /* XXX */
- return -TARGET_EOPNOTSUPP;
-}
-
-static inline abi_long get_ucontext_sigreturn(CPUX86State *regs,
- abi_ulong target_sf, abi_ulong *target_uc)
-{
- /* XXX */
- *target_uc = 0;
- return -TARGET_EOPNOTSUPP;
-}
-
#endif /* !TARGET_ARCH_SIGNAL_H_ */