qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] CRIS target-cris/*


From: Edgar E. Iglesias
Subject: [Qemu-devel] [PATCH] CRIS target-cris/*
Date: Tue, 2 Oct 2007 23:13:43 +0200
User-agent: Mutt/1.5.16 (2007-06-09)

This are the remaining files of the target-cris/ subdir.

-- 
Edgar E. Iglesias
Axis Communications AB

 target-cris/cpu.h         |  252 +++++++++++++++++++++++++++++++++++++++++++++
 target-cris/exec.h        |   68 ++++++++++++
 target-cris/helper.c      |  173 +++++++++++++++++++++++++++++++
 target-cris/op_helper.c   |   81 +++++++++++++++
 target-cris/op_mem.c      |   59 +++++++++++
 target-cris/op_template.h |   48 +++++++++
 6 files changed, 681 insertions(+), 0 deletions(-)

diff --git a/target-cris/cpu.h b/target-cris/cpu.h
new file mode 100644
index 0000000..94c460e
--- /dev/null
+++ b/target-cris/cpu.h
@@ -0,0 +1,252 @@
+/*
+ *  CRIS virtual CPU header
+ * 
+ *  Copyright (c) 2007 AXIS Communications AB
+ *  Written by Edgar E. Iglesias
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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 Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef CPU_CRIS_H
+#define CPU_CRIS_H
+
+#define TARGET_LONG_BITS 32
+
+#include "cpu-defs.h"
+
+#include "softfloat.h"
+
+#define TARGET_HAS_ICE 1
+
+#define ELF_MACHINE    EM_CRIS
+
+#define EXCP_MMU_EXEC    0
+#define EXCP_MMU_READ    1
+#define EXCP_MMU_WRITE   2
+#define EXCP_MMU_FLUSH   3
+#define EXCP_MMU_MISS    4
+#define EXCP_BREAK      16 /* trap.  */
+
+/* CPU flags.  */
+#define S_FLAG 0x200
+#define R_FLAG 0x100
+#define P_FLAG 0x80
+#define U_FLAG 0x40
+#define P_FLAG 0x80
+#define U_FLAG 0x40
+#define I_FLAG 0x20
+#define X_FLAG 0x10
+#define N_FLAG 0x08
+#define Z_FLAG 0x04
+#define V_FLAG 0x02
+#define C_FLAG 0x01
+#define ALU_FLAGS 0x1F
+
+/* Condition codes.  */
+#define CC_CC   0
+#define CC_CS   1
+#define CC_NE   2
+#define CC_EQ   3
+#define CC_VC   4
+#define CC_VS   5
+#define CC_PL   6
+#define CC_MI   7
+#define CC_LS   8
+#define CC_HI   9
+#define CC_GE  10
+#define CC_LT  11
+#define CC_GT  12
+#define CC_LE  13
+#define CC_A   14
+#define CC_P   15
+
+/* Internal flags for the implementation.  */
+#define F_DELAYSLOT 1
+
+typedef struct CPUCRISState {
+       uint32_t debug1;
+       uint32_t debug2;
+       uint32_t debug3;
+
+       /*
+        * We just store the stores to the tlbset here for later evaluation
+        * when the hw needs access to them.
+        *
+        * One for I and another for D.
+        */
+       struct
+       {
+               uint32_t hi;
+               uint32_t lo;
+       } tlbsets[2][4][16];
+
+       uint32_t sregs[256][16]; /* grrr why so many??  */
+       uint32_t regs[16];
+       uint32_t pregs[16];
+       uint32_t pc;
+       uint32_t sr;
+       uint32_t flag_mask; /* Per insn mask of affected flags.  */
+
+       /* SSP and USP.  */
+       int current_sp;
+       uint32_t sp[2];
+
+       /* These are setup up by the guest code just before transfering the
+          control back to the host.  */
+       int jmp;
+       uint32_t btarget;
+       int btaken;
+
+       /* for traps.  */
+       int trapnr;
+
+       /* Condition flag tracking.  */
+       uint32_t cc_op;
+       uint32_t cc_mask;
+       uint32_t cc_dest;
+       uint32_t cc_src;
+       uint32_t cc_result;
+
+       /* size of the operation, 1 = byte, 2 = word, 4 = dword.  */
+       int cc_size; 
+
+       /* extended arithmetics.  */
+       int cc_x_live;
+       int cc_x;
+
+       int features;
+
+        uint64_t pending_interrupts;
+       int interrupt_request;
+       int exception_index;
+       int user_mode_only;
+       int halted;
+
+       struct
+       {
+               int exec_insns;
+               int exec_loads;
+               int exec_stores;
+       } stats;
+
+
+       jmp_buf jmp_env;
+       CPU_COMMON
+} CPUCRISState;
+
+CPUCRISState *cpu_cris_init(void);
+int cpu_cris_exec(CPUCRISState *s);
+void cpu_cris_close(CPUCRISState *s);
+void do_interrupt(CPUCRISState *env);
+/* you can call this signal handler from your SIGBUS and SIGSEGV
+   signal handlers to inform the virtual CPU of exceptions. non zero
+   is returned if the signal was handled by the virtual CPU.  */
+int cpu_cris_signal_handler(int host_signum, void *pinfo, 
+                           void *puc);
+void cpu_cris_flush_flags(CPUCRISState *, int);
+
+enum {
+    CC_OP_DYNAMIC, /* Use env->cc_op  */
+    CC_OP_FLAGS,
+    CC_OP_LOGIC,
+    CC_OP_CMP,
+    CC_OP_MOVE,
+    CC_OP_MOVE_PD,
+    CC_OP_MOVE_SD,
+    CC_OP_ADD,
+    CC_OP_ADDC,
+    CC_OP_MCP,
+    CC_OP_ADDU,
+    CC_OP_SUB,
+    CC_OP_SUBU,
+    CC_OP_NEG,
+    CC_OP_BTST,
+    CC_OP_MULS,
+    CC_OP_MULU,
+    CC_OP_DSTEP,
+    CC_OP_BOUND,
+
+    CC_OP_OR,
+    CC_OP_AND,
+    CC_OP_XOR,
+    CC_OP_LSL,
+    CC_OP_LSR,
+    CC_OP_ASR,
+    CC_OP_LZ
+};
+
+#define CCF_C 0x01
+#define CCF_V 0x02
+#define CCF_Z 0x04
+#define CCF_N 0x08
+#define CCF_X 0x10
+
+#define CRIS_SSP    0
+#define CRIS_USP    1
+
+typedef struct cris_def_t cris_def_t;
+
+int cpu_cris_set_model(CPUCRISState *env, const char * name);
+
+void cris_set_irq_level(CPUCRISState *env, int level, uint8_t vector);
+void cris_set_macsr(CPUCRISState *env, uint32_t val);
+void cris_switch_sp(CPUCRISState *env);
+
+void do_cris_semihosting(CPUCRISState *env, int nr);
+
+enum cris_features {
+    CRIS_FEATURE_CF_ISA_MUL,
+};
+
+static inline int cris_feature(CPUCRISState *env, int feature)
+{
+    return (env->features & (1u << feature)) != 0;
+}
+
+void register_cris_insns (CPUCRISState *env);
+
+/* CRIS uses 8k pages.  */
+#define TARGET_PAGE_BITS 13
+
+#define CPUState CPUCRISState
+#define cpu_init cpu_cris_init
+#define cpu_exec cpu_cris_exec
+#define cpu_gen_code cpu_cris_gen_code
+#define cpu_signal_handler cpu_cris_signal_handler
+
+#include "cpu-all.h"
+
+/* Register aliases.  */
+#define REG_SP  14
+#define REG_ACR 15
+#define REG_MOF 7
+
+/* Support regs.  */
+#define SR_PID 2
+#define SR_SRS 3
+#define SR_EBP 9
+#define SR_ERP 10
+#define SR_CCS 13
+
+/* Support func regs.  */
+#define SFR_RW_GC_CFG      0][0
+#define SFR_RW_MM_CFG      1][0
+#define SFR_RW_MM_KBASE_LO 1][1
+#define SFR_RW_MM_KBASE_HI 1][2
+#define SFR_R_MM_CAUSE     1][3
+#define SFR_RW_MM_TLB_SEL  1][4
+#define SFR_RW_MM_TLB_LO   1][5
+#define SFR_RW_MM_TLB_HI   1][6
+
+#endif
diff --git a/target-cris/exec.h b/target-cris/exec.h
new file mode 100644
index 0000000..e7c41c6
--- /dev/null
+++ b/target-cris/exec.h
@@ -0,0 +1,68 @@
+/*
+ *  CRIS execution defines
+ * 
+ *  Copyright (c) 2007 AXIS Communications AB
+ *  Written by Edgar E. Iglesias
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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 Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "dyngen-exec.h"
+
+#if 1
+register struct CPUCRISState *env asm(AREG0);
+/* This is only used for tb lookup.  */
+register uint32_t T0 asm(AREG1);
+register uint32_t T1 asm(AREG2);
+#else
+struct CPUCRISState *env;
+/* This is only used for tb lookup.  */
+uint32_t T0;
+uint32_t T1;
+#endif
+#include "cpu.h"
+#include "exec-all.h"
+
+#define RETURN() __asm__ __volatile__("" : : : "memory");
+
+static inline void env_to_regs(void)
+{
+}
+
+static inline void regs_to_env(void)
+{
+}
+
+int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
+                              int is_user, int is_softmmu);
+void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr);
+
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+#endif
+
+void cpu_cris_flush_flags(CPUCRISState *env, int cc_op);
+void helper_movec(CPUCRISState *env, int reg, uint32_t val);
+
+void cpu_loop_exit(void);
+
+static inline int cpu_halted(CPUState *env) {
+       if (!env->halted)
+               return 0;
+       if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+               env->halted = 0;
+               return 0;
+       }
+       return EXCP_HALTED;
+}
diff --git a/target-cris/helper.c b/target-cris/helper.c
new file mode 100644
index 0000000..bbc675b
--- /dev/null
+++ b/target-cris/helper.c
@@ -0,0 +1,173 @@
+/*
+ *  CRIS helper routines.
+ * 
+ *  Copyright (c) 2007 AXIS Communications AB
+ *  Written by Edgar E. Iglesias.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+#include "cpu.h"
+#include "mmu.h"
+#include "exec-all.h"
+
+#if defined(CONFIG_USER_ONLY)
+
+void do_interrupt (CPUState *env)
+{
+  env->exception_index = -1;
+}
+
+int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
+                             int is_user, int is_softmmu)
+{
+    env->exception_index = 0xaa;
+    env->debug1 = address;
+    cpu_dump_state(env, stderr, fprintf, 0);
+    printf("%s addr=%x env->pc=%x\n", __func__, address, env->pc);
+    return 1;
+}
+
+target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
+{
+    return addr;
+}
+
+#else /* !CONFIG_USER_ONLY */
+
+int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
+                               int is_user, int is_softmmu)
+{
+       struct cris_mmu_result_t res;
+       int prot, miss;
+       target_ulong phy;
+
+       address &= TARGET_PAGE_MASK;
+       prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+//     printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, 
is_softmmu);
+       miss = cris_mmu_translate(&res, env, address, rw, is_user);
+       if (miss)
+       {
+               /* handle the miss.  */
+               phy = 0;
+               env->exception_index = EXCP_MMU_MISS;
+       }
+       else
+       {
+               phy = res.phy;
+       }
+//     printf ("a=%x phy=%x\n", address, phy);
+       return tlb_set_page(env, address, phy, prot, is_user, is_softmmu);
+}
+
+
+static void cris_shift_ccs(CPUState *env)
+{
+       uint32_t ccs;
+       /* Apply the ccs shift.  */
+       ccs = env->pregs[SR_CCS];
+       ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
+//     printf ("ccs=%x %x\n", env->pregs[SR_CCS], ccs);
+       env->pregs[SR_CCS] = ccs;
+}
+
+void do_interrupt(CPUState *env)
+{
+       uint32_t ebp, isr;
+       int irqnum;
+
+       fflush(NULL);
+
+#if 0
+       printf ("exception index=%d interrupt_req=%d\n", 
+               env->exception_index, 
+               env->interrupt_request);
+#endif
+
+       switch (env->exception_index)
+       {
+               case EXCP_BREAK:
+//                     printf ("BREAK! %d\n", env->trapnr);
+                       irqnum = env->trapnr;
+                       ebp = env->pregs[SR_EBP];
+                       isr = ldl_code(ebp + irqnum * 4);
+                       env->pregs[SR_ERP] = env->pc + 2;
+                       env->pc = isr;
+
+                       cris_shift_ccs(env);
+
+                       break;
+               case EXCP_MMU_MISS:
+//                     printf ("MMU miss\n");
+                       irqnum = 4;
+                       ebp = env->pregs[SR_EBP];
+                       isr = ldl_code(ebp + irqnum * 4);
+                       env->pregs[SR_ERP] = env->pc;
+                       env->pc = isr;
+                       cris_shift_ccs(env);
+                       break;
+
+               default:                
+               {
+                       /* Maybe the irq was acked by sw before we got a 
+                          change to take it.  */
+                       if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+                               if (!env->pending_interrupts)
+                                       return;
+                               if (!(env->pregs[SR_CCS] & I_FLAG)) {
+                                       return;
+                               }
+                               
+                               irqnum = 31 -
+                                       __builtin_clz(env->pending_interrupts);
+                               irqnum += 0x30;
+                               ebp = env->pregs[SR_EBP];
+                               isr = ldl_code(ebp + irqnum * 4);
+                               env->pregs[SR_ERP] = env->pc;
+                               env->pc = isr;
+                               
+                               cris_shift_ccs(env);
+#if 0
+                               printf ("%s ebp=%x %x isr=%x %d"
+                                       " ir=%x pending=%x\n", 
+                                       __func__, 
+                                       ebp, ebp + irqnum * 4,
+                                       isr, env->exception_index,
+                                       env->interrupt_request,
+                                       env->pending_interrupts);
+#endif
+                       }
+                                               
+               }
+               break;
+       }
+}
+
+target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
+{
+//     printf ("%s\n", __func__);
+       uint32_t phy = addr;
+       struct cris_mmu_result_t res;
+       int prot, miss;
+       miss = cris_mmu_translate(&res, env, addr, 0, 0);
+       if (!miss)
+               phy = res.phy;
+       return phy;
+}
+#endif
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
new file mode 100644
index 0000000..c8b0630
--- /dev/null
+++ b/target-cris/op_helper.c
@@ -0,0 +1,81 @@
+/*
+ *  CRIS helper routines
+ * 
+ *  Copyright (c) 2007 AXIS Communications
+ *  Written by Edgar E. Iglesias
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+#include "exec.h"
+
+#define MMUSUFFIX _mmu
+#define GETPC() (__builtin_return_address(0))
+
+#define SHIFT 0
+#include "softmmu_template.h"
+
+#define SHIFT 1
+#include "softmmu_template.h"
+
+#define SHIFT 2
+#include "softmmu_template.h"
+
+#define SHIFT 3
+#include "softmmu_template.h"
+
+/* Try to fill the TLB and return an exception if error. If retaddr is
+   NULL, it means that the function was called in C code (i.e. not
+   from generated code or from helper.c) */
+/* XXX: fix it to restore all registers */
+void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
+{
+    TranslationBlock *tb;
+    CPUState *saved_env;
+    target_phys_addr_t pc;
+    int ret;
+
+    /* XXX: hack to restore env in all cases, even if not called from
+       generated code */
+    saved_env = env;
+    env = cpu_single_env;
+    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, is_user, 1);
+    if (__builtin_expect(ret, 0)) {
+        if (retaddr) {
+            /* now we have a real cpu fault */
+            pc = (target_phys_addr_t)retaddr;
+            tb = tb_find_pc(pc);
+            if (tb) {
+                /* the PC is inside the translated code. It means that we have
+                   a virtual CPU fault */
+                cpu_restore_state(tb, env, pc, NULL);
+            }
+        }
+        cpu_loop_exit();
+    }
+    env = saved_env;
+}
+
+static void do_rte(void)
+{
+       printf ("%s\n", __func__);
+}
+
+void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
+                          int is_asi)
+{
+
+}
diff --git a/target-cris/op_mem.c b/target-cris/op_mem.c
new file mode 100644
index 0000000..ad91098
--- /dev/null
+++ b/target-cris/op_mem.c
@@ -0,0 +1,59 @@
+/*
+ *  CRIS memory access (load and store) micro operations.
+ * 
+ *  Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+void glue(op_ldb_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(ldsb, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_ldub_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(ldub, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_stb_T0_T1, MEMSUFFIX) (void) {
+    glue(stb, MEMSUFFIX) (T0, T1);
+    RETURN();
+}
+
+void glue(op_ldw_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(ldsw, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_lduw_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(lduw, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_stw_T0_T1, MEMSUFFIX) (void) {
+    glue(stw, MEMSUFFIX) (T0, T1);
+    RETURN();
+}
+
+void glue(op_ldl_T0_T0, MEMSUFFIX) (void) {
+    T0 = glue(ldl, MEMSUFFIX) (T0);
+    RETURN();
+}
+
+void glue(op_stl_T0_T1, MEMSUFFIX) (void) {
+    glue(stl, MEMSUFFIX) (T0, T1);
+    RETURN();
+}
diff --git a/target-cris/op_template.h b/target-cris/op_template.h
new file mode 100644
index 0000000..daf3240
--- /dev/null
+++ b/target-cris/op_template.h
@@ -0,0 +1,48 @@
+/*
+ *  CRIS micro operations (templates for various register related
+ *  operations)
+ *
+ *  Copyright (c) 2003 Fabrice Bellard 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef SET_REG
+#define SET_REG(x) REG = x
+#endif
+
+void OPPROTO glue(op_movl_T0_, REGNAME)(void)
+{
+    T0 = REG;
+}
+
+void OPPROTO glue(op_movl_T1_, REGNAME)(void)
+{
+    T1 = REG;
+}
+
+void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)
+{
+    SET_REG (T0);
+}
+
+void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)
+{
+    SET_REG (T1);
+}
+
+#undef REG
+#undef REGNAME
+#undef SET_REG




reply via email to

[Prev in Thread] Current Thread [Next in Thread]