Permalink
Browse files

s390x: s390x-linux-user support

This patch adds support for running s390x binaries in the linux-user emulation
code.

Signed-off-by: Ulrich Hecht <uli@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
  • Loading branch information...
1 parent 7a86d29 commit a4c075f178a3a2c976667389f19ce7dbabaf9712 Ulrich Hecht committed with agraf Jul 24, 2009
View
@@ -867,6 +867,25 @@ static inline void init_thread(struct target_pt_regs *regs,
#endif /* TARGET_ALPHA */
+#ifdef TARGET_S390X
+
+#define ELF_START_MMAP (0x20000000000ULL)
+
+#define elf_check_arch(x) ( (x) == ELF_ARCH )
+
+#define ELF_CLASS ELFCLASS64
+#define ELF_DATA ELFDATA2MSB
+#define ELF_ARCH EM_S390
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
+{
+ regs->psw.addr = infop->entry;
+ regs->psw.mask = PSW_MASK_64 | PSW_MASK_32;
+ regs->gprs[15] = infop->start_stack;
+}
+
+#endif /* TARGET_S390X */
+
#ifndef ELF_PLATFORM
#define ELF_PLATFORM (NULL)
#endif
View
@@ -2701,6 +2701,80 @@ void cpu_loop (CPUState *env)
}
#endif /* TARGET_ALPHA */
+#ifdef TARGET_S390X
+void cpu_loop(CPUS390XState *env)
+{
+ int trapnr;
+ target_siginfo_t info;
+
+ while (1) {
+ trapnr = cpu_s390x_exec (env);
+
+ switch (trapnr) {
+ case EXCP_INTERRUPT:
+ /* just indicate that signals should be handled asap */
+ break;
+ case EXCP_DEBUG:
+ {
+ int sig;
+
+ sig = gdb_handlesig (env, TARGET_SIGTRAP);
+ if (sig) {
+ info.si_signo = sig;
+ info.si_errno = 0;
+ info.si_code = TARGET_TRAP_BRKPT;
+ queue_signal(env, info.si_signo, &info);
+ }
+ }
+ break;
+ case EXCP_SVC:
+ {
+ int n = env->int_svc_code;
+ if (!n) {
+ /* syscalls > 255 */
+ n = env->regs[1];
+ }
+ env->psw.addr += env->int_svc_ilc;
+ env->regs[2] = do_syscall(env, n,
+ env->regs[2],
+ env->regs[3],
+ env->regs[4],
+ env->regs[5],
+ env->regs[6],
+ env->regs[7]);
+ }
+ break;
+ case EXCP_ADDR:
+ {
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ /* XXX: check env->error_code */
+ info.si_code = TARGET_SEGV_MAPERR;
+ info._sifields._sigfault._addr = env->__excp_addr;
+ queue_signal(env, info.si_signo, &info);
+ }
+ break;
+ case EXCP_SPEC:
+ {
+ fprintf(stderr,"specification exception insn 0x%08x%04x\n", ldl(env->psw.addr), lduw(env->psw.addr + 4));
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = TARGET_ILL_ILLOPC;
+ info._sifields._sigfault._addr = env->__excp_addr;
+ queue_signal(env, info.si_signo, &info);
+ }
+ break;
+ default:
+ printf ("Unhandled trap: 0x%x\n", trapnr);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ exit (1);
+ }
+ process_pending_signals (env);
+ }
+}
+
+#endif /* TARGET_S390X */
+
static void version(void)
{
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION
@@ -3450,6 +3524,15 @@ int main(int argc, char **argv, char **envp)
env->regs[15] = regs->acr;
env->pc = regs->erp;
}
+#elif defined(TARGET_S390X)
+ {
+ int i;
+ for (i = 0; i < 16; i++) {
+ env->regs[i] = regs->gprs[i];
+ }
+ env->psw.mask = regs->psw.mask;
+ env->psw.addr = regs->psw.addr;
+ }
#else
#error unsupported target CPU
#endif
View
@@ -0,0 +1,23 @@
+/* this typedef defines how a Program Status Word looks like */
+typedef struct {
+ abi_ulong mask;
+ abi_ulong addr;
+} __attribute__ ((aligned(8))) target_psw_t;
+
+/*
+ * The pt_regs struct defines the way the registers are stored on
+ * the stack during a system call.
+ */
+
+#define TARGET_NUM_GPRS 16
+
+struct target_pt_regs {
+ abi_ulong args[1];
+ target_psw_t psw;
+ abi_ulong gprs[TARGET_NUM_GPRS];
+ abi_ulong orig_gpr2;
+ unsigned short ilc;
+ unsigned short trap;
+};
+
+#define UNAME_MACHINE "s390x"
Oops, something went wrong.

0 comments on commit a4c075f

Please sign in to comment.