#include "sysemu/sysemu.h"
#include "sysemu/hw_accel.h"
#include "kvm_arm.h"
+#include "disas/capstone.h"
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
{
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
env->v7m.secure = true;
+ } else {
+ /* This bit resets to 0 if security is supported, but 1 if
+ * it is not. The bit is not present in v7M, but we set it
+ * here so we can avoid having to make checks on it conditional
+ * on ARM_FEATURE_V8 (we don't let the guest see the bit).
+ */
+ env->v7m.aircr = R_V7M_AIRCR_BFHFNMINS_MASK;
}
/* In v7M the reset value of this bit is IMPDEF, but ARM recommends
env->pmsav8.mair1[M_REG_S] = 0;
}
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+ if (cpu->sau_sregion > 0) {
+ memset(env->sau.rbar, 0, sizeof(*env->sau.rbar) * cpu->sau_sregion);
+ memset(env->sau.rlar, 0, sizeof(*env->sau.rlar) * cpu->sau_sregion);
+ }
+ env->sau.rnr = 0;
+ /* SAU_CTRL reset value is IMPDEF; we choose 0, which is what
+ * the Cortex-M33 does.
+ */
+ env->sau.ctrl = 0;
+ }
+
set_flush_to_zero(1, &env->vfp.standard_fp_status);
set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status);
set_default_nan_mode(1, &env->vfp.standard_fp_status);
return print_insn_arm(pc | 1, info);
}
-static int arm_read_memory_func(bfd_vma memaddr, bfd_byte *b,
- int length, struct disassemble_info *info)
-{
- assert(info->read_memory_inner_func);
- assert((info->flags & INSN_ARM_BE32) == 0 || length == 2 || length == 4);
-
- if ((info->flags & INSN_ARM_BE32) != 0 && length == 2) {
- assert(info->endian == BFD_ENDIAN_LITTLE);
- return info->read_memory_inner_func(memaddr ^ 2, (bfd_byte *)b, 2,
- info);
- } else {
- return info->read_memory_inner_func(memaddr, b, length, info);
- }
-}
-
static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
{
ARMCPU *ac = ARM_CPU(cpu);
CPUARMState *env = &ac->env;
+ bool sctlr_b;
if (is_a64(env)) {
/* We might not be compiled with the A64 disassembler
#if defined(CONFIG_ARM_A64_DIS)
info->print_insn = print_insn_arm_a64;
#endif
- } else if (env->thumb) {
- info->print_insn = print_insn_thumb1;
+ info->cap_arch = CS_ARCH_ARM64;
+ info->cap_insn_unit = 4;
+ info->cap_insn_split = 4;
} else {
- info->print_insn = print_insn_arm;
+ int cap_mode;
+ if (env->thumb) {
+ info->print_insn = print_insn_thumb1;
+ info->cap_insn_unit = 2;
+ info->cap_insn_split = 4;
+ cap_mode = CS_MODE_THUMB;
+ } else {
+ info->print_insn = print_insn_arm;
+ info->cap_insn_unit = 4;
+ info->cap_insn_split = 4;
+ cap_mode = CS_MODE_ARM;
+ }
+ if (arm_feature(env, ARM_FEATURE_V8)) {
+ cap_mode |= CS_MODE_V8;
+ }
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ cap_mode |= CS_MODE_MCLASS;
+ }
+ info->cap_arch = CS_ARCH_ARM;
+ info->cap_mode = cap_mode;
}
- if (bswap_code(arm_sctlr_b(env))) {
+
+ sctlr_b = arm_sctlr_b(env);
+ if (bswap_code(sctlr_b)) {
#ifdef TARGET_WORDS_BIGENDIAN
info->endian = BFD_ENDIAN_LITTLE;
#else
info->endian = BFD_ENDIAN_BIG;
#endif
}
- if (info->read_memory_inner_func == NULL) {
- info->read_memory_inner_func = info->read_memory_func;
- info->read_memory_func = arm_read_memory_func;
- }
info->flags &= ~INSN_ARM_BE32;
- if (arm_sctlr_b(env)) {
+#ifndef CONFIG_USER_ONLY
+ if (sctlr_b) {
info->flags |= INSN_ARM_BE32;
}
+#endif
}
uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
{
CPUState *cs = CPU(obj);
ARMCPU *cpu = ARM_CPU(obj);
- static bool inited;
cs->env_ptr = &cpu->env;
cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
if (tcg_enabled()) {
cpu->psci_version = 2; /* TCG implements PSCI 0.2 */
- if (!inited) {
- inited = true;
- arm_translate_init();
- }
}
}
}
}
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+ uint32_t nr = cpu->sau_sregion;
+
+ if (nr > 0xff) {
+ error_setg(errp, "v8M SAU #regions invalid %" PRIu32, nr);
+ return;
+ }
+
+ if (nr) {
+ env->sau.rbar = g_new0(uint32_t, nr);
+ env->sau.rlar = g_new0(uint32_t, nr);
+ }
+ }
+
if (arm_feature(env, ARM_FEATURE_EL3)) {
set_feature(env, ARM_FEATURE_VBAR);
}
#ifndef CONFIG_USER_ONLY
if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) {
- AddressSpace *as;
-
cs->num_ases = 2;
if (!cpu->secure_memory) {
cpu->secure_memory = cs->memory;
}
- as = address_space_init_shareable(cpu->secure_memory,
- "cpu-secure-memory");
- cpu_address_space_init(cs, as, ARMASIdx_S);
+ cpu_address_space_init(cs, ARMASIdx_S, "cpu-secure-memory",
+ cpu->secure_memory);
} else {
cs->num_ases = 1;
}
-
- cpu_address_space_init(cs,
- address_space_init_shareable(cs->memory,
- "cpu-memory"),
- ARMASIdx_NS);
+ cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory);
#endif
qemu_init_vcpu(cs);
char *typename;
char **cpuname;
- if (!cpu_model) {
- return NULL;
- }
-
cpuname = g_strsplit(cpu_model, ",", 1);
- typename = g_strdup_printf("%s-" TYPE_ARM_CPU, cpuname[0]);
+ typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpuname[0]);
oc = object_class_by_name(typename);
g_strfreev(cpuname);
g_free(typename);
cpu->midr = 0x410fc240; /* r0p0 */
cpu->pmsav7_dregion = 8;
}
+
static void arm_v7m_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
};
#ifdef CONFIG_USER_ONLY
-static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
- int mmu_idx)
+static int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size,
+ int rw, int mmu_idx)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
#endif
cc->disas_set_info = arm_disas_set_info;
+#ifdef CONFIG_TCG
+ cc->tcg_initialize = arm_translate_init;
+#endif
}
static void cpu_register(const ARMCPUInfo *info)