Add OpenRISC target machine. Signed-off-by: Jia Liu <pro...@gmail.com> --- target-openrisc/cpu.h | 62 +++++++++++++++++++++++++++++++++++++++++++-- target-openrisc/machine.c | 22 +++++++++++++++- 2 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index b5be770..69c5679 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -44,6 +44,15 @@ struct CPUOpenRISCState; #define TARGET_PHYS_ADDR_SPACE_BITS 32 #define TARGET_VIRT_ADDR_SPACE_BITS 32 +#define SET_FP_CAUSE(reg, v) do {\ + (reg) = ((reg) & ~(0x3f << 12)) | \ + ((v & 0x3f) << 12);\ + } while (0) +#define GET_FP_ENABLE(reg) (((reg) >> 7) & 0x1f) +#define UPDATE_FP_FLAGS(reg, v) do {\ + (reg) |= ((v & 0x1f) << 2);\ + } while (0) + /* Internel flags, delay slot flag */ #define D_FLAG 1 @@ -69,6 +78,25 @@ enum { R_RVH = R12 }; +/* Exceptions indices */ +enum { + EXCP_RESET = 0x1, + EXCP_BUSERR = 0x2, + EXCP_DPF = 0x3, + EXCP_IPF = 0x4, + EXCP_TICK = 0x5, + EXCP_ALIGN = 0x6, + EXCP_ILLEGAL = 0x7, + EXCP_INT = 0x8, + EXCP_DTLBMISS = 0x9, + EXCP_ITLBMISS = 0xa, + EXCP_RANGE = 0xb, + EXCP_SYSCALL = 0xc, + EXCP_FPE = 0xd, + EXCP_TRAP = 0xe, + EXCP_NR, +}; + /* Supervisor register */ enum { SR_SM = 1, @@ -91,6 +119,21 @@ enum { SR_SCE = (1<<17), }; +/* FPCSR register */ +enum { + FPCSR_FPEE = 1, + FPCSR_RM = (3 << 1), + FPCSR_OVF = (1 << 3), + FPCSR_UNF = (1 << 4), + FPCSR_SNF = (1 << 5), + FPCSR_QNF = (1 << 6), + FPCSR_ZF = (1 << 7), + FPCSR_IXF = (1 << 8), + FPCSR_IVF = (1 << 9), + FPCSR_INF = (1 << 10), + FPCSR_DZF = (1 << 11), +}; + /* CPU config reg */ enum { CPUCFGR_NSGF = (15 << 0), @@ -130,8 +173,20 @@ struct CPUOpenRISCState { target_ulong ppc; /* Prev PC */ target_ulong jmp_pc; /* Jump PC */ + target_ulong machi; /* Multiply register MACHI */ + target_ulong maclo; /* Multiply register MACLO */ + + target_ulong fpmaddhi; /* Multiply and add float register FPMADDHI */ + target_ulong fpmaddlo; /* Multiply and add float register FPMADDLO */ + + target_ulong epcr; /* Exception PC register */ + target_ulong eear; /* Exception EA register */ + uint32_t sr; /* Supervisor register */ uint32_t vr; /* Version register */ + uint32_t esr; /* Exception supervisor register */ + uint32_t fpcsr; /* Float register */ + float_status fp_status; uint32_t flags; /* cpu_flags, we only use it for exception in solt so far. */ uint32_t btaken; /* the SR_F bit */ @@ -232,7 +287,8 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env, { *pc = env->pc; *cs_base = 0; - *flags = 0; + /* D_FLAG -- branch insrtuction exception */ + *flags = (env->flags&D_FLAG); } static inline int cpu_mmu_index(CPUOpenRISCState *env) @@ -240,9 +296,11 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env) return 0; } +#define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_INT_0 static inline bool cpu_has_work(CPUOpenRISCState *env) { - return true; + return env->interrupt_request & (CPU_INTERRUPT_HARD | + CPU_INTERRUPT_TIMER); } #include "exec-all.h" diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c index 11bf275..e5d59a7 100644 --- a/target-openrisc/machine.c +++ b/target-openrisc/machine.c @@ -20,11 +20,31 @@ #include "hw/hw.h" #include "hw/boards.h" +static const VMStateDescription vmstate_cpu = { + .name = "cpu", + .version_id = CPU_SAVE_VERSION, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(gpr, CPUOpenRISCState, 32), + VMSTATE_UINT32(sr, CPUOpenRISCState), + VMSTATE_UINT32(epcr, CPUOpenRISCState), + VMSTATE_UINT32(eear, CPUOpenRISCState), + VMSTATE_UINT32(esr, CPUOpenRISCState), + VMSTATE_UINT32(fpcsr, CPUOpenRISCState), + VMSTATE_UINT32(pc, CPUOpenRISCState), + VMSTATE_UINT32(npc, CPUOpenRISCState), + VMSTATE_UINT32(ppc, CPUOpenRISCState), + VMSTATE_END_OF_LIST() + } +}; + void cpu_save(QEMUFile *f, void *opaque) { + vmstate_save_state(f, &vmstate_cpu, opaque); } int cpu_load(QEMUFile *f, void *opaque, int version_id) { - return 0; + return vmstate_load_state(f, &vmstate_cpu, opaque, version_id); } -- 1.7.9.5