aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorGuan Xuetao <gxt@mprc.pku.edu.cn>2011-04-12 16:27:03 +0800
committerBlue Swirl <blauwirbel@gmail.com>2011-04-12 18:49:05 +0000
commitd2fbca94223ef573a67d4eb2f27509a9bbb85ca1 (patch)
treed664b734daab1020022b6405989f02df28b13987 /linux-user
parent8b5d487d4d35a1a18c3ac48f3dd367fb769592b2 (diff)
unicore32: necessary modifications for other files to support unicore32
Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/elfload.c74
-rw-r--r--linux-user/main.c89
-rw-r--r--linux-user/qemu.h5
-rw-r--r--linux-user/syscall_defs.h10
4 files changed, 173 insertions, 5 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index fe5410e6f9..4c399f8e33 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -339,6 +339,80 @@ enum
#endif
+#ifdef TARGET_UNICORE32
+
+#define ELF_START_MMAP 0x80000000
+
+#define elf_check_arch(x) ((x) == EM_UNICORE32)
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2LSB
+#define ELF_ARCH EM_UNICORE32
+
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
+{
+ abi_long stack = infop->start_stack;
+ memset(regs, 0, sizeof(*regs));
+ regs->UC32_REG_asr = 0x10;
+ regs->UC32_REG_pc = infop->entry & 0xfffffffe;
+ regs->UC32_REG_sp = infop->start_stack;
+ /* FIXME - what to for failure of get_user()? */
+ get_user_ual(regs->UC32_REG_02, stack + 8); /* envp */
+ get_user_ual(regs->UC32_REG_01, stack + 4); /* envp */
+ /* XXX: it seems that r0 is zeroed after ! */
+ regs->UC32_REG_00 = 0;
+}
+
+#define ELF_NREG 34
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
+{
+ (*regs)[0] = env->regs[0];
+ (*regs)[1] = env->regs[1];
+ (*regs)[2] = env->regs[2];
+ (*regs)[3] = env->regs[3];
+ (*regs)[4] = env->regs[4];
+ (*regs)[5] = env->regs[5];
+ (*regs)[6] = env->regs[6];
+ (*regs)[7] = env->regs[7];
+ (*regs)[8] = env->regs[8];
+ (*regs)[9] = env->regs[9];
+ (*regs)[10] = env->regs[10];
+ (*regs)[11] = env->regs[11];
+ (*regs)[12] = env->regs[12];
+ (*regs)[13] = env->regs[13];
+ (*regs)[14] = env->regs[14];
+ (*regs)[15] = env->regs[15];
+ (*regs)[16] = env->regs[16];
+ (*regs)[17] = env->regs[17];
+ (*regs)[18] = env->regs[18];
+ (*regs)[19] = env->regs[19];
+ (*regs)[20] = env->regs[20];
+ (*regs)[21] = env->regs[21];
+ (*regs)[22] = env->regs[22];
+ (*regs)[23] = env->regs[23];
+ (*regs)[24] = env->regs[24];
+ (*regs)[25] = env->regs[25];
+ (*regs)[26] = env->regs[26];
+ (*regs)[27] = env->regs[27];
+ (*regs)[28] = env->regs[28];
+ (*regs)[29] = env->regs[29];
+ (*regs)[30] = env->regs[30];
+ (*regs)[31] = env->regs[31];
+
+ (*regs)[32] = cpu_asr_read((CPUState *)env);
+ (*regs)[33] = env->regs[0]; /* XXX */
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_HWCAP (UC32_HWCAP_CMOV | UC32_HWCAP_UCF64)
+
+#endif
+
#ifdef TARGET_SPARC
#ifdef TARGET_SPARC64
diff --git a/linux-user/main.c b/linux-user/main.c
index 91600877d2..a1e37e4948 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -816,6 +816,83 @@ void cpu_loop(CPUARMState *env)
#endif
+#ifdef TARGET_UNICORE32
+
+void cpu_loop(CPUState *env)
+{
+ int trapnr;
+ unsigned int n, insn;
+ target_siginfo_t info;
+
+ for (;;) {
+ cpu_exec_start(env);
+ trapnr = uc32_cpu_exec(env);
+ cpu_exec_end(env);
+ switch (trapnr) {
+ case UC32_EXCP_PRIV:
+ {
+ /* system call */
+ get_user_u32(insn, env->regs[31] - 4);
+ n = insn & 0xffffff;
+
+ if (n >= UC32_SYSCALL_BASE) {
+ /* linux syscall */
+ n -= UC32_SYSCALL_BASE;
+ if (n == UC32_SYSCALL_NR_set_tls) {
+ cpu_set_tls(env, env->regs[0]);
+ env->regs[0] = 0;
+ } else {
+ env->regs[0] = do_syscall(env,
+ n,
+ env->regs[0],
+ env->regs[1],
+ env->regs[2],
+ env->regs[3],
+ env->regs[4],
+ env->regs[5]);
+ }
+ } else {
+ goto error;
+ }
+ }
+ break;
+ case UC32_EXCP_TRAP:
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ /* XXX: check env->error_code */
+ info.si_code = TARGET_SEGV_MAPERR;
+ info._sifields._sigfault._addr = env->cp0.c4_faultaddr;
+ queue_signal(env, info.si_signo, &info);
+ break;
+ 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;
+ default:
+ goto error;
+ }
+ process_pending_signals(env);
+ }
+
+error:
+ fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
+ cpu_dump_state(env, stderr, fprintf, 0);
+ abort();
+}
+#endif
+
#ifdef TARGET_SPARC
#define SPARC64_STACK_BIAS 2047
@@ -2925,6 +3002,8 @@ int main(int argc, char **argv, char **envp)
#endif
#elif defined(TARGET_ARM)
cpu_model = "any";
+#elif defined(TARGET_UNICORE32)
+ cpu_model = "any";
#elif defined(TARGET_M68K)
cpu_model = "any";
#elif defined(TARGET_SPARC)
@@ -3227,6 +3306,14 @@ int main(int argc, char **argv, char **envp)
env->regs[i] = regs->uregs[i];
}
}
+#elif defined(TARGET_UNICORE32)
+ {
+ int i;
+ cpu_asr_write(env, regs->uregs[32], 0xffffffff);
+ for (i = 0; i < 32; i++) {
+ env->regs[i] = regs->uregs[i];
+ }
+ }
#elif defined(TARGET_SPARC)
{
int i;
@@ -3367,7 +3454,7 @@ int main(int argc, char **argv, char **envp)
#error unsupported target CPU
#endif
-#if defined(TARGET_ARM) || defined(TARGET_M68K)
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
ts->stack_base = info->start_stack;
ts->heap_base = info->brk;
/* This will be filled in on the first SYS_HEAPINFO call. */
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 250814d9f7..f522f5e64a 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -105,6 +105,9 @@ typedef struct TaskState {
FPA11 fpa;
int swi_errno;
#endif
+#ifdef TARGET_UNICORE32
+ int swi_errno;
+#endif
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
abi_ulong target_v86;
struct vm86_saved_state vm86_saved_regs;
@@ -118,7 +121,7 @@ typedef struct TaskState {
#ifdef TARGET_M68K
int sim_syscalls;
#endif
-#if defined(TARGET_ARM) || defined(TARGET_M68K)
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
/* Extra fields for semihosted binaries. */
uint32_t stack_base;
uint32_t heap_base;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 702652cb9e..bde89213de 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -55,7 +55,7 @@
#endif
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
- || defined(TARGET_M68K) || defined(TARGET_CRIS)
+ || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_UNICORE32)
#define TARGET_IOC_SIZEBITS 14
#define TARGET_IOC_DIRBITS 2
@@ -315,7 +315,10 @@ struct target_sigaction;
int do_sigaction(int sig, const struct target_sigaction *act,
struct target_sigaction *oact);
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
+ || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined(TARGET_SH4) \
+ || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
+ || defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32)
#if defined(TARGET_SPARC)
#define TARGET_SA_NOCLDSTOP 8u
@@ -1002,7 +1005,8 @@ struct target_winsize {
#define TARGET_MAP_UNINITIALIZED 0x4000000 /* for anonymous mmap, memory could be uninitialized */
#endif
-#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) || defined(TARGET_CRIS)
+#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) \
+ || defined(TARGET_CRIS) || defined(TARGET_UNICORE32)
struct target_stat {
unsigned short st_dev;
unsigned short __pad1;