#define CPUArchState struct CPUOpenRISCState
+/* cpu_openrisc_map_address_* in CPUOpenRISCTLBContext need this decl. */
+struct OpenRISCCPU;
+
#include "config.h"
#include "qemu-common.h"
-#include "cpu-defs.h"
-#include "softfloat.h"
-#include "qemu/cpu.h"
-#include "error.h"
+#include "exec/cpu-defs.h"
+#include "fpu/softfloat.h"
+#include "qom/cpu.h"
#define TYPE_OPENRISC_CPU "or32-cpu"
/**
* OpenRISCCPUClass:
+ * @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A OpenRISC CPU model.
CPUClass parent_class;
/*< public >*/
+ DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
} OpenRISCCPUClass;
#define NB_MMU_MODES 3
+enum {
+ MMU_NOMMU_IDX = 0,
+ MMU_SUPERVISOR_IDX = 1,
+ MMU_USER_IDX = 2,
+};
+
#define TARGET_PAGE_BITS 13
#define TARGET_PHYS_ADDR_SPACE_BITS 32
(reg) |= ((v & 0x1f) << 2);\
} while (0)
+/* Version Register */
+#define SPR_VR 0xFFFF003F
+
/* Internal flags, delay slot flag */
#define D_FLAG 1
-/* Registers */
-enum {
- R0 = 0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10,
- R11, R12, R13, R14, R15, R16, R17, R18, R19, R20,
- R21, R22, R23, R24, R25, R26, R27, R28, R29, R30,
- R31
-};
-
-/* Register aliases */
-enum {
- R_ZERO = R0,
- R_SP = R1,
- R_FP = R2,
- R_LR = R9,
- R_RV = R11,
- R_RVH = R12
-};
+/* Interrupt */
+#define NR_IRQS 32
/* Unit presece register */
enum {
OPENRISC_FEATURE_OV64S = (1 << 9),
};
+/* Tick Timer Mode Register */
+enum {
+ TTMR_TP = (0xfffffff),
+ TTMR_IP = (1 << 28),
+ TTMR_IE = (1 << 29),
+ TTMR_M = (3 << 30),
+};
+
+/* Timer Mode */
+enum {
+ TIMER_NONE = (0 << 30),
+ TIMER_INTR = (1 << 30),
+ TIMER_SHOT = (2 << 30),
+ TIMER_CONT = (3 << 30),
+};
+
+/* TLB size */
+enum {
+ DTLB_WAYS = 1,
+ DTLB_SIZE = 64,
+ DTLB_MASK = (DTLB_SIZE-1),
+ ITLB_WAYS = 1,
+ ITLB_SIZE = 64,
+ ITLB_MASK = (ITLB_SIZE-1),
+};
+
+/* TLB prot */
+enum {
+ URE = (1 << 6),
+ UWE = (1 << 7),
+ SRE = (1 << 8),
+ SWE = (1 << 9),
+
+ SXE = (1 << 6),
+ UXE = (1 << 7),
+};
+
+/* check if tlb available */
+enum {
+ TLBRET_INVALID = -3,
+ TLBRET_NOMATCH = -2,
+ TLBRET_BADADDR = -1,
+ TLBRET_MATCH = 0
+};
+
+typedef struct OpenRISCTLBEntry {
+ uint32_t mr;
+ uint32_t tr;
+} OpenRISCTLBEntry;
+
+#ifndef CONFIG_USER_ONLY
+typedef struct CPUOpenRISCTLBContext {
+ OpenRISCTLBEntry itlb[ITLB_WAYS][ITLB_SIZE];
+ OpenRISCTLBEntry dtlb[DTLB_WAYS][DTLB_SIZE];
+
+ int (*cpu_openrisc_map_address_code)(struct OpenRISCCPU *cpu,
+ hwaddr *physical,
+ int *prot,
+ target_ulong address, int rw);
+ int (*cpu_openrisc_map_address_data)(struct OpenRISCCPU *cpu,
+ hwaddr *physical,
+ int *prot,
+ target_ulong address, int rw);
+} CPUOpenRISCTLBContext;
+#endif
+
typedef struct CPUOpenRISCState {
target_ulong gpr[32]; /* General registers */
target_ulong pc; /* Program counter */
CPU_COMMON
#ifndef CONFIG_USER_ONLY
+ CPUOpenRISCTLBContext * tlb;
+
struct QEMUTimer *timer;
uint32_t ttmr; /* Timer tick mode register */
uint32_t ttcr; /* Timer tick count register */
uint32_t picmr; /* Interrupt mask register */
uint32_t picsr; /* Interrupt contrl register*/
#endif
+ void *irq[32]; /* Interrupt irq input */
} CPUOpenRISCState;
/**
static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
{
- return OPENRISC_CPU(container_of(env, OpenRISCCPU, env));
+ return container_of(env, OpenRISCCPU, env);
}
#define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e))
+#define ENV_OFFSET offsetof(OpenRISCCPU, env)
+
OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
-void openrisc_cpu_realize(Object *obj, Error **errp);
void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
int cpu_openrisc_exec(CPUOpenRISCState *s);
-void do_interrupt(CPUOpenRISCState *env);
+void openrisc_cpu_do_interrupt(CPUState *cpu);
+void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
+ fprintf_function cpu_fprintf, int flags);
+hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void openrisc_translate_init(void);
+int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
+ target_ulong address,
+ int rw, int mmu_idx);
+int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
#define cpu_list cpu_openrisc_list
#define cpu_exec cpu_openrisc_exec
#define cpu_gen_code cpu_openrisc_gen_code
+#define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault
+#define cpu_signal_handler cpu_openrisc_signal_handler
#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_openrisc_cpu;
+
+/* hw/openrisc_pic.c */
+void cpu_openrisc_pic_init(OpenRISCCPU *cpu);
+
+/* hw/openrisc_timer.c */
+void cpu_openrisc_clock_init(OpenRISCCPU *cpu);
+void cpu_openrisc_count_update(OpenRISCCPU *cpu);
+void cpu_openrisc_count_start(OpenRISCCPU *cpu);
+void cpu_openrisc_count_stop(OpenRISCCPU *cpu);
+
void cpu_openrisc_mmu_init(OpenRISCCPU *cpu);
+int cpu_openrisc_get_phys_nommu(OpenRISCCPU *cpu,
+ hwaddr *physical,
+ int *prot, target_ulong address, int rw);
+int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
+ hwaddr *physical,
+ int *prot, target_ulong address, int rw);
+int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
+ hwaddr *physical,
+ int *prot, target_ulong address, int rw);
#endif
static inline CPUOpenRISCState *cpu_init(const char *cpu_model)
return NULL;
}
-#include "cpu-all.h"
+#include "exec/cpu-all.h"
static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
target_ulong *pc,
static inline int cpu_mmu_index(CPUOpenRISCState *env)
{
- return 0;
+ if (!(env->sr & SR_IME)) {
+ return MMU_NOMMU_IDX;
+ }
+ return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
}
-static inline bool cpu_has_work(CPUOpenRISCState *env)
+#define CPU_INTERRUPT_TIMER CPU_INTERRUPT_TGT_INT_0
+static inline bool cpu_has_work(CPUState *cpu)
{
- return true;
+ return cpu->interrupt_request & (CPU_INTERRUPT_HARD |
+ CPU_INTERRUPT_TIMER);
}
-#include "exec-all.h"
+#include "exec/exec-all.h"
static inline target_ulong cpu_get_pc(CPUOpenRISCState *env)
{
return env->pc;
}
-static inline void cpu_pc_from_tb(CPUOpenRISCState *env, TranslationBlock *tb)
-{
- env->pc = tb->pc;
-}
-
#endif /* CPU_OPENRISC_H */