From 93ac68bca5a3332ffacd7bf10e7b9c4cfdab6374 Mon Sep 17 00:00:00 2001 From: bellard Date: Tue, 30 Sep 2003 20:57:29 +0000 Subject: [PATCH] sparc emulation target (thanx to Thomas M. Ogrisegg) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@388 c046a42c-6fe2-441c-8c8c-71466251a162 --- cpu-all.h | 59 +++++++++++++++++++++++++++++++++++++++++++++++ cpu-exec.c | 28 +++++++++++++++------- disas.c | 2 ++ linux-user/main.c | 38 ++++++++++++++++++++++++++---- 4 files changed, 115 insertions(+), 12 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 65304927ee..43c03c96cf 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -188,6 +188,56 @@ static inline void stfq(void *ptr, double v) } #endif +#elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN) + +static inline int lduw(void *ptr) +{ + uint8_t *b = (uint8_t *) ptr; + return (b[0]<<8|b[1]); +} + +static inline int ldsw(void *ptr) +{ + int8_t *b = (int8_t *) ptr; + return (b[0]<<8|b[1]); +} + +static inline int ldl(void *ptr) +{ + uint8_t *b = (uint8_t *) ptr; + return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]); +} + +static inline uint64_t ldq(void *ptr) +{ + uint32_t a,b; + a = ldl (ptr); + b = ldl (ptr+4); + return (((uint64_t)a<<32)|b); +} + +static inline void stw(void *ptr, int v) +{ + uint8_t *d = (uint8_t *) ptr; + d[0] = v >> 8; + d[1] = v; +} + +static inline void stl(void *ptr, int v) +{ + uint8_t *d = (uint8_t *) ptr; + d[0] = v >> 24; + d[1] = v >> 16; + d[2] = v >> 8; + d[3] = v; +} + +static inline void stq(void *ptr, uint64_t v) +{ + stl (ptr, v); + stl (ptr+4, v >> 32); +} + #else static inline int lduw(void *ptr) @@ -297,6 +347,15 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size); #define cpu_interrupt cpu_arm_interrupt #define cpu_signal_handler cpu_arm_signal_handler +#elif defined(TARGET_SPARC) + +#define CPUState CPUSPARCState +#define cpu_init cpu_sparc_init +#define cpu_exec cpu_sparc_exec +#define cpu_gen_code cpu_sparc_gen_code +#define cpu_interrupt cpu_sparc_interrupt +#define cpu_signal_handler cpu_sparc_signal_handler + #else #error unsupported target CPU diff --git a/cpu-exec.c b/cpu-exec.c index 69671df861..035f104145 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -18,19 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" -#ifdef TARGET_I386 -#include "exec-i386.h" -#endif -#ifdef TARGET_ARM -#include "exec-arm.h" -#endif - +#include "exec.h" #include "disas.h" //#define DEBUG_EXEC //#define DEBUG_SIGNAL -#if defined(TARGET_ARM) +#if defined(TARGET_ARM) || defined(TARGET_SPARC) /* XXX: unify with i386 target */ void cpu_loop_exit(void) { @@ -136,6 +130,7 @@ int cpu_exec(CPUState *env1) env->VF = (psr << 3) & 0x80000000; env->cpsr = psr & ~0xf0000000; } +#elif defined(TARGET_SPARC) #else #error unsupported target CPU #endif @@ -229,6 +224,8 @@ int cpu_exec(CPUState *env1) env->cpsr = compute_cpsr(); cpu_arm_dump_state(env, logfile, 0); env->cpsr &= ~0xf0000000; +#elif defined(TARGET_SPARC) + cpu_sparc_dump_state (env, logfile, 0); #else #error unsupported target CPU #endif @@ -246,6 +243,14 @@ int cpu_exec(CPUState *env1) flags = 0; cs_base = 0; pc = (uint8_t *)env->regs[15]; +#elif defined(TARGET_SPARC) + flags = 0; + cs_base = 0; + if (env->npc) { + env->pc = env->npc; + env->npc = 0; + } + pc = (uint8_t *) env->pc; #else #error unsupported CPU #endif @@ -358,6 +363,7 @@ int cpu_exec(CPUState *env1) #endif #elif defined(TARGET_ARM) env->cpsr = compute_cpsr(); +#elif defined(TARGET_SPARC) #else #error unsupported target CPU #endif @@ -488,6 +494,12 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, /* XXX: do more */ return 0; } +#elif defined(TARGET_SPARC) +static inline int handle_cpu_signal(unsigned long pc, unsigned long address, + int is_write, sigset_t *old_set) +{ + return 0; +} #else #error unsupported target CPU #endif diff --git a/disas.c b/disas.c index 8a44e91477..81ba50a964 100644 --- a/disas.c +++ b/disas.c @@ -142,6 +142,8 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags) print_insn = print_insn_i386; #elif defined(TARGET_ARM) print_insn = print_insn_arm; +#elif defined(TARGET_SPARC) + print_insn = print_insn_sparc; #else fprintf(out, "Asm output not supported on this arch\n"); return; diff --git a/linux-user/main.c b/linux-user/main.c index f4c936c5bc..811b8bfba8 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1,5 +1,5 @@ /* - * qemu main + * qemu user main * * Copyright (c) 2003 Fabrice Bellard * @@ -38,7 +38,7 @@ static const char *interp_prefix = CONFIG_QEMU_PREFIX; const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2"; #endif -/* for recent libc, we add these dummies symbol which are not declared +/* for recent libc, we add these dummy symbols which are not declared when generating a linked object (bug in ld ?) */ #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) long __init_array_start[0]; @@ -299,10 +299,37 @@ void cpu_loop(CPUARMState *env) #endif +#ifdef TARGET_SPARC + +void cpu_loop (CPUSPARCState *env) +{ + int trapnr; + + while (1) { + trapnr = cpu_sparc_exec (env); + + switch (trapnr) { + case 0x8: case 0x10: + env->regwptr[0] = do_syscall (env, env->gregs[1], + env->regwptr[0], env->regwptr[1], env->regwptr[2], + env->regwptr[3], env->regwptr[4], env->regwptr[13]); + if (env->regwptr[0] >= 0xffffffe0) + env->psr |= PSR_CARRY; + break; + default: + printf ("Invalid trap: %d\n", trapnr); + exit (1); + } + process_pending_signals (env); + } +} + +#endif + void usage(void) { - printf("qemu version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" - "usage: qemu [-h] [-d] [-L path] [-s size] program [arguments...]\n" + printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" + "usage: qemu-" TARGET_ARCH " [-h] [-d] [-L path] [-s size] program [arguments...]\n" "Linux CPU emulator (compiled for %s emulation)\n" "\n" "-h print this help\n" @@ -497,6 +524,9 @@ int main(int argc, char **argv) } env->cpsr = regs->uregs[16]; } +#elif defined(TARGET_SPARC) + env->pc = regs->u_regs[0]; + env->regwptr[6] = regs->u_regs[1]-0x40; #else #error unsupported target CPU #endif