-#ifndef CPU_SPARC_H
-#define CPU_SPARC_H
+#ifndef SPARC_CPU_H
+#define SPARC_CPU_H
-#include "config.h"
#include "qemu-common.h"
#include "qemu/bswap.h"
+#include "cpu-qom.h"
+
+#define ALIGNED_ONLY
#if !defined(TARGET_SPARC64)
#define TARGET_LONG_BITS 32
#include "fpu/softfloat.h"
-#define TARGET_HAS_ICE 1
-
-#if !defined(TARGET_SPARC64)
-#define ELF_MACHINE EM_SPARC
-#else
-#define ELF_MACHINE EM_SPARCV9
-#endif
-
/*#define EXCP_INTERRUPT 0x100*/
/* trap definitions */
#define CC_DST (env->cc_dst)
#define CC_OP (env->cc_op)
+/* Even though lazy evaluation of CPU condition codes tends to be less
+ * important on RISC systems where condition codes are only updated
+ * when explicitly requested, SPARC uses it to update 32-bit and 64-bit
+ * condition codes.
+ */
enum {
CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
CC_OP_FLAGS, /* all cc are back in status register */
uint32_t tt;
} trap_state;
#endif
+#define TARGET_INSN_START_EXTRA_WORDS 1
typedef struct sparc_def_t {
const char *name;
uint32_t frequency;
uint32_t disabled;
uint64_t disabled_mask;
+ uint32_t npt;
+ uint64_t npt_mask;
int64_t clock_offset;
QEMUTimer *qtimer;
};
typedef struct CPUTimer CPUTimer;
-struct QEMUFile;
-void cpu_put_timer(struct QEMUFile *f, CPUTimer *s);
-void cpu_get_timer(struct QEMUFile *f, CPUTimer *s);
-
typedef struct CPUSPARCState CPUSPARCState;
struct CPUSPARCState {
CPU_COMMON
+ /* Fields from here on are preserved across CPU reset. */
target_ulong version;
uint32_t nwindows;
uint32_t cache_control;
};
-#include "cpu-qom.h"
+/**
+ * SPARCCPU:
+ * @env: #CPUSPARCState
+ *
+ * A SPARC CPU.
+ */
+struct SPARCCPU {
+ /*< private >*/
+ CPUState parent_obj;
+ /*< public >*/
+
+ CPUSPARCState env;
+};
+
+static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
+{
+ return container_of(env, SPARCCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(SPARCCPU, env)
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_sparc_cpu;
+#endif
+
+void sparc_cpu_do_interrupt(CPUState *cpu);
+void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
+ fprintf_function cpu_fprintf, int flags);
+hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int sparc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int sparc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
+ MMUAccessType access_type,
+ int mmu_idx,
+ uintptr_t retaddr);
#ifndef NO_CPU_IO_DEFS
/* cpu_init.c */
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf);
/* mmu_helper.c */
-int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
+int sparc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
int mmu_idx);
-#define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault
target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env);
void gen_intermediate_code_init(CPUSPARCState *env);
/* cpu-exec.c */
-int cpu_sparc_exec(CPUSPARCState *s);
/* win_helper.c */
target_ulong cpu_get_psr(CPUSPARCState *env1);
void cpu_put_psr(CPUSPARCState *env1, target_ulong val);
+void cpu_put_psr_raw(CPUSPARCState *env1, target_ulong val);
#ifdef TARGET_SPARC64
target_ulong cpu_get_ccr(CPUSPARCState *env1);
void cpu_put_ccr(CPUSPARCState *env1, target_ulong val);
int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
#ifndef NO_CPU_IO_DEFS
-static inline CPUSPARCState *cpu_init(const char *cpu_model)
-{
- SPARCCPU *cpu = cpu_sparc_init(cpu_model);
- if (cpu == NULL) {
- return NULL;
- }
- return &cpu->env;
-}
+#define cpu_init(cpu_model) CPU(cpu_sparc_init(cpu_model))
#endif
-#define cpu_exec cpu_sparc_exec
-#define cpu_gen_code cpu_sparc_gen_code
#define cpu_signal_handler cpu_sparc_signal_handler
#define cpu_list sparc_cpu_list
-#define CPU_SAVE_VERSION 7
-
/* MMU modes definitions */
#if defined (TARGET_SPARC64)
#define MMU_USER_IDX 0
}
#endif
-static inline int cpu_mmu_index(CPUSPARCState *env1)
+static inline int cpu_mmu_index(CPUSPARCState *env1, bool ifetch)
{
#if defined(CONFIG_USER_ONLY)
return MMU_USER_IDX;
trap_state* cpu_tsptr(CPUSPARCState* env);
#endif
-#define TB_FLAG_FPU_ENABLED (1 << 4)
-#define TB_FLAG_AM_ENABLED (1 << 5)
+#define TB_FLAG_MMU_MASK 7
+#define TB_FLAG_FPU_ENABLED (1 << 4)
+#define TB_FLAG_AM_ENABLED (1 << 5)
+#define TB_FLAG_ASI_SHIFT 24
static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
- target_ulong *cs_base, int *flags)
+ target_ulong *cs_base, uint32_t *pflags)
{
+ uint32_t flags;
*pc = env->pc;
*cs_base = env->npc;
+ flags = cpu_mmu_index(env, false);
#ifdef TARGET_SPARC64
- // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
- *flags = (env->pstate & PS_PRIV) /* 2 */
- | ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */
- | ((env->tl & 0xff) << 8)
- | (env->dmmu.mmu_primary_context << 16); /* 16... */
if (env->pstate & PS_AM) {
- *flags |= TB_FLAG_AM_ENABLED;
+ flags |= TB_FLAG_AM_ENABLED;
}
- if ((env->def->features & CPU_FEATURE_FLOAT) && (env->pstate & PS_PEF)
+ if ((env->def->features & CPU_FEATURE_FLOAT)
+ && (env->pstate & PS_PEF)
&& (env->fprs & FPRS_FEF)) {
- *flags |= TB_FLAG_FPU_ENABLED;
+ flags |= TB_FLAG_FPU_ENABLED;
}
+ flags |= env->asi << TB_FLAG_ASI_SHIFT;
#else
- // FPU enable . Supervisor
- *flags = env->psrs;
if ((env->def->features & CPU_FEATURE_FLOAT) && env->psref) {
- *flags |= TB_FLAG_FPU_ENABLED;
+ flags |= TB_FLAG_FPU_ENABLED;
}
#endif
+ *pflags = flags;
}
static inline bool tb_fpu_enabled(int tb_flags)
#endif
}
-static inline bool cpu_has_work(CPUState *cpu)
-{
- SPARCCPU *sparc_cpu = SPARC_CPU(cpu);
- CPUSPARCState *env1 = &sparc_cpu->env;
-
- return (cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
- cpu_interrupts_enabled(env1);
-}
-
-#include "exec/exec-all.h"
-
#endif