aboutsummaryrefslogtreecommitdiff
path: root/target/microblaze/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'target/microblaze/cpu.h')
-rw-r--r--target/microblaze/cpu.h257
1 files changed, 151 insertions, 106 deletions
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 3c4e0ba80a..c0c7574dbd 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -6,7 +6,7 @@
* 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.
+ * version 2.1 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
@@ -20,24 +20,21 @@
#ifndef MICROBLAZE_CPU_H
#define MICROBLAZE_CPU_H
-#include "qemu-common.h"
#include "cpu-qom.h"
+#include "exec/cpu-defs.h"
+#include "qemu/cpu-float.h"
-#define TARGET_LONG_BITS 64
-
-#define CPUArchState struct CPUMBState
+/* MicroBlaze is always in-order. */
+#define TCG_GUEST_DEFAULT_MO TCG_MO_ALL
-#include "exec/cpu-defs.h"
-#include "fpu/softfloat-types.h"
-struct CPUMBState;
-typedef struct CPUMBState CPUMBState;
+typedef struct CPUArchState CPUMBState;
#if !defined(CONFIG_USER_ONLY)
#include "mmu.h"
#endif
#define EXCP_MMU 1
#define EXCP_IRQ 2
-#define EXCP_BREAK 3
+#define EXCP_SYSCALL 3 /* user-only */
#define EXCP_HW_BREAK 4
#define EXCP_HW_EXCP 5
@@ -85,10 +82,13 @@ typedef struct CPUMBState CPUMBState;
/* Exception State Register (ESR) Fields */
#define ESR_DIZ (1<<11) /* Zone Protection */
+#define ESR_W (1<<11) /* Unaligned word access */
#define ESR_S (1<<10) /* Store instruction */
#define ESR_ESS_FSL_OFFSET 5
+#define ESR_ESS_MASK (0x7f << 5)
+
#define ESR_EC_FSL 0
#define ESR_EC_UNALIGNED_DATA 1
#define ESR_EC_ILLEGAL_OP 2
@@ -205,7 +205,7 @@ typedef struct CPUMBState CPUMBState;
#define PVR10_TARGET_FAMILY_MASK 0xFF000000
#define PVR10_ASIZE_SHIFT 18
-/* MMU descrtiption */
+/* MMU description */
#define PVR11_USE_MMU 0xC0000000
#define PVR11_MMU_ITLB_SIZE 0x38000000
#define PVR11_MMU_DTLB_SIZE 0x07000000
@@ -228,23 +228,34 @@ typedef struct CPUMBState CPUMBState;
#define CC_NE 1
#define CC_EQ 0
-#define NB_MMU_MODES 3
-
#define STREAM_EXCEPTION (1 << 0)
#define STREAM_ATOMIC (1 << 1)
#define STREAM_TEST (1 << 2)
#define STREAM_CONTROL (1 << 3)
#define STREAM_NONBLOCK (1 << 4)
-struct CPUMBState {
- uint32_t debug;
- uint32_t btaken;
- uint64_t btarget;
- uint32_t bimm;
+#define TARGET_INSN_START_EXTRA_WORDS 1
+
+/* use-non-secure property masks */
+#define USE_NON_SECURE_M_AXI_DP_MASK 0x1
+#define USE_NON_SECURE_M_AXI_IP_MASK 0x2
+#define USE_NON_SECURE_M_AXI_DC_MASK 0x4
+#define USE_NON_SECURE_M_AXI_IC_MASK 0x8
+
+struct CPUArchState {
+ uint32_t bvalue; /* TCG temporary, only valid during a TB */
+ uint32_t btarget; /* Full resolved branch destination */
uint32_t imm;
uint32_t regs[32];
- uint64_t sregs[14];
+ uint32_t pc;
+ uint32_t msr; /* All bits of MSR except MSR[C] and MSR[CC] */
+ uint32_t msr_c; /* MSR[C], in low bit; other bits must be 0 */
+ target_ulong ear;
+ uint32_t esr;
+ uint32_t fsr;
+ uint32_t btr;
+ uint32_t edr;
float_status fp_status;
/* Stack protectors. Yes, it's a hw feature. */
uint32_t slr, shr;
@@ -255,142 +266,176 @@ struct CPUMBState {
uint32_t res_val;
/* Internal flags. */
-#define IMM_FLAG 4
-#define MSR_EE_FLAG (1 << 8)
+#define IMM_FLAG (1 << 0)
+#define BIMM_FLAG (1 << 1)
+#define ESR_ESS_FLAG (1 << 2) /* indicates ESR_ESS_MASK is present */
+/* MSR_EE (1 << 8) -- these 3 are not in iflags but tb_flags */
+/* MSR_UM (1 << 11) */
+/* MSR_VM (1 << 13) */
+/* ESR_ESS_MASK [11:5] -- unwind into iflags for unaligned excp */
+#define D_FLAG (1 << 12) /* Bit in ESR. */
#define DRTI_FLAG (1 << 16)
#define DRTE_FLAG (1 << 17)
#define DRTB_FLAG (1 << 18)
-#define D_FLAG (1 << 19) /* Bit in ESR. */
+
/* TB dependent CPUMBState. */
-#define IFLAGS_TB_MASK (D_FLAG | IMM_FLAG | DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)
+#define IFLAGS_TB_MASK (D_FLAG | BIMM_FLAG | IMM_FLAG | \
+ DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)
+#define MSR_TB_MASK (MSR_UM | MSR_VM | MSR_EE)
+
uint32_t iflags;
#if !defined(CONFIG_USER_ONLY)
/* Unified MMU. */
- struct microblaze_mmu mmu;
+ MicroBlazeMMU mmu;
#endif
/* Fields up to this point are cleared by a CPU reset */
struct {} end_reset_fields;
- CPU_COMMON
-
/* These fields are preserved on reset. */
-
- struct {
- uint32_t regs[13];
- } pvr;
};
+/*
+ * Microblaze Configuration Settings
+ *
+ * Note that the structure is sorted by type and size to minimize holes.
+ */
+typedef struct {
+ char *version;
+
+ uint64_t addr_mask;
+
+ uint32_t base_vectors;
+ uint32_t pvr_user2;
+ uint32_t pvr_regs[13];
+
+ uint8_t addr_size;
+ uint8_t use_fpu;
+ uint8_t use_hw_mul;
+ uint8_t pvr_user1;
+ uint8_t pvr;
+ uint8_t mmu;
+ uint8_t mmu_tlb_access;
+ uint8_t mmu_zones;
+
+ bool stackprot;
+ bool use_barrel;
+ bool use_div;
+ bool use_msr_instr;
+ bool use_pcmp_instr;
+ bool use_mmu;
+ uint8_t use_non_secure;
+ bool dcache_writeback;
+ bool endi;
+ bool dopb_bus_exception;
+ bool iopb_bus_exception;
+ bool illegal_opcode_exception;
+ bool opcode_0_illegal;
+ bool div_zero_exception;
+ bool unaligned_exceptions;
+} MicroBlazeCPUConfig;
+
/**
* MicroBlazeCPU:
* @env: #CPUMBState
*
* A MicroBlaze CPU.
*/
-struct MicroBlazeCPU {
- /*< private >*/
+struct ArchCPU {
CPUState parent_obj;
- /*< public >*/
-
- /* Microblaze Configuration Settings */
- struct {
- bool stackprot;
- uint32_t base_vectors;
- uint8_t addr_size;
- uint8_t use_fpu;
- uint8_t use_hw_mul;
- bool use_barrel;
- bool use_div;
- bool use_msr_instr;
- bool use_pcmp_instr;
- bool use_mmu;
- bool dcache_writeback;
- bool endi;
- char *version;
- uint8_t pvr;
- } cfg;
-
CPUMBState env;
-};
-static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
-{
- return container_of(env, MicroBlazeCPU, env);
-}
+ bool ns_axi_dp;
+ bool ns_axi_ip;
+ bool ns_axi_dc;
+ bool ns_axi_ic;
-#define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
+ MicroBlazeCPUConfig cfg;
+};
-#define ENV_OFFSET offsetof(MicroBlazeCPU, env)
+/**
+ * MicroBlazeCPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_phases: The parent class' reset phase handlers.
+ *
+ * A MicroBlaze CPU model.
+ */
+struct MicroBlazeCPUClass {
+ CPUClass parent_class;
+ DeviceRealize parent_realize;
+ ResettablePhases parent_phases;
+};
+
+#ifndef CONFIG_USER_ONLY
void mb_cpu_do_interrupt(CPUState *cs);
bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
-void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
- int flags);
-hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int mb_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
+ MemTxAttrs *attrs);
+#endif /* !CONFIG_USER_ONLY */
+G_NORETURN void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
+ MMUAccessType access_type,
+ int mmu_idx, uintptr_t retaddr);
+void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
+int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+int mb_cpu_gdb_read_stack_protect(CPUState *cs, GByteArray *buf, int reg);
+int mb_cpu_gdb_write_stack_protect(CPUState *cs, uint8_t *buf, int reg);
-void mb_tcg_init(void);
-/* 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_mb_signal_handler(int host_signum, void *pinfo,
- void *puc);
+static inline uint32_t mb_cpu_read_msr(const CPUMBState *env)
+{
+ /* Replicate MSR[C] to MSR[CC]. */
+ return env->msr | (env->msr_c * (MSR_C | MSR_CC));
+}
-/* FIXME: MB uses variable pages down to 1K but linux only uses 4k. */
-#define TARGET_PAGE_BITS 12
+static inline void mb_cpu_write_msr(CPUMBState *env, uint32_t val)
+{
+ env->msr_c = (val >> 2) & 1;
+ /*
+ * Clear both MSR[C] and MSR[CC] from the saved copy.
+ * MSR_PVR is not writable and is always clear.
+ */
+ env->msr = val & ~(MSR_C | MSR_CC | MSR_PVR);
+}
-#define TARGET_PHYS_ADDR_SPACE_BITS 64
-#define TARGET_VIRT_ADDR_SPACE_BITS 64
+void mb_tcg_init(void);
#define CPU_RESOLVING_TYPE TYPE_MICROBLAZE_CPU
-#define cpu_signal_handler cpu_mb_signal_handler
-
/* MMU modes definitions */
-#define MMU_MODE0_SUFFIX _nommu
-#define MMU_MODE1_SUFFIX _kernel
-#define MMU_MODE2_SUFFIX _user
#define MMU_NOMMU_IDX 0
#define MMU_KERNEL_IDX 1
#define MMU_USER_IDX 2
-/* See NB_MMU_MODES further up the file. */
-
-static inline int cpu_mmu_index (CPUMBState *env, bool ifetch)
-{
- MicroBlazeCPU *cpu = mb_env_get_cpu(env);
-
- /* Are we in nommu mode?. */
- if (!(env->sregs[SR_MSR] & MSR_VM) || !cpu->cfg.use_mmu) {
- return MMU_NOMMU_IDX;
- }
-
- if (env->sregs[SR_MSR] & MSR_UM) {
- return MMU_USER_IDX;
- }
- return MMU_KERNEL_IDX;
-}
-
-int mb_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size, int rw,
- int mmu_idx);
+/* See NB_MMU_MODES in cpu-defs.h. */
#include "exec/cpu-all.h"
-static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
+/* Ensure there is no overlap between the two masks. */
+QEMU_BUILD_BUG_ON(MSR_TB_MASK & IFLAGS_TB_MASK);
+
+static inline void cpu_get_tb_cpu_state(CPUMBState *env, vaddr *pc,
+ uint64_t *cs_base, uint32_t *flags)
{
- *pc = env->sregs[SR_PC];
- *cs_base = 0;
- *flags = (env->iflags & IFLAGS_TB_MASK) |
- (env->sregs[SR_MSR] & (MSR_UM | MSR_VM | MSR_EE));
+ *pc = env->pc;
+ *flags = (env->iflags & IFLAGS_TB_MASK) | (env->msr & MSR_TB_MASK);
+ *cs_base = (*flags & IMM_FLAG ? env->imm : 0);
}
#if !defined(CONFIG_USER_ONLY)
-void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
- bool is_write, bool is_exec, int is_asi,
- unsigned size);
+bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
+
+void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
+ unsigned size, MMUAccessType access_type,
+ int mmu_idx, MemTxAttrs attrs,
+ MemTxResult response, uintptr_t retaddr);
+#endif
+
+#ifndef CONFIG_USER_ONLY
+extern const VMStateDescription vmstate_mb_cpu;
#endif
#endif