#include "cpu.h"
-#include "gdbstub.h"
+#include "exec/gdbstub.h"
#include "helper.h"
-#include "host-utils.h"
-#include "sysemu.h"
-#include "bitops.h"
+#include "qemu/host-utils.h"
+#include "sysemu/sysemu.h"
+#include "qemu/bitops.h"
#ifndef CONFIG_USER_ONLY
static inline int get_phys_addr(CPUARMState *env, uint32_t address,
int access_type, int is_user,
- target_phys_addr_t *phys_ptr, int *prot,
+ hwaddr *phys_ptr, int *prot,
target_ulong *page_size);
#endif
static int ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
- target_phys_addr_t phys_addr;
+ hwaddr phys_addr;
target_ulong page_size;
int prot;
int ret, is_user = ri->opc2 & 2;
uint64_t value)
{
/* Wait-for-interrupt (deprecated) */
- cpu_interrupt(env, CPU_INTERRUPT_HALT);
+ cpu_interrupt(CPU(arm_env_get_cpu(env)), CPU_INTERRUPT_HALT);
return 0;
}
static int mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t *value)
{
- uint32_t mpidr = env->cpu_index;
+ CPUState *cs = CPU(arm_env_get_cpu(env));
+ uint32_t mpidr = cs->cpu_index;
/* We don't support setting cluster ID ([8..11])
* so these bits always RAZ.
*/
{
ARMCPU *cpu;
CPUARMState *env;
- static int inited = 0;
+ ObjectClass *oc;
- if (!object_class_by_name(cpu_model)) {
+ oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model);
+ if (!oc) {
return NULL;
}
- cpu = ARM_CPU(object_new(cpu_model));
+ cpu = ARM_CPU(object_new(object_class_get_name(oc)));
env = &cpu->env;
env->cpu_model_str = cpu_model;
- arm_cpu_realize(cpu);
- if (tcg_enabled() && !inited) {
- inited = 1;
- arm_translate_init();
- }
+ /* TODO this should be set centrally, once possible */
+ object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
+
+ return cpu;
+}
+
+void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
+{
+ CPUARMState *env = &cpu->env;
- cpu_reset(CPU(cpu));
if (arm_feature(env, ARM_FEATURE_NEON)) {
gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
51, "arm-neon.xml", 0);
gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
19, "arm-vfp.xml", 0);
}
- qemu_init_vcpu(env);
- return cpu;
}
-typedef struct ARMCPUListState {
- fprintf_function cpu_fprintf;
- FILE *file;
-} ARMCPUListState;
-
/* Sort alphabetically by type name, except for "any". */
static gint arm_cpu_list_compare(gconstpointer a, gconstpointer b)
{
name_a = object_class_get_name(class_a);
name_b = object_class_get_name(class_b);
- if (strcmp(name_a, "any") == 0) {
+ if (strcmp(name_a, "any-" TYPE_ARM_CPU) == 0) {
return 1;
- } else if (strcmp(name_b, "any") == 0) {
+ } else if (strcmp(name_b, "any-" TYPE_ARM_CPU) == 0) {
return -1;
} else {
return strcmp(name_a, name_b);
static void arm_cpu_list_entry(gpointer data, gpointer user_data)
{
ObjectClass *oc = data;
- ARMCPUListState *s = user_data;
+ CPUListState *s = user_data;
+ const char *typename;
+ char *name;
+ typename = object_class_get_name(oc);
+ name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_ARM_CPU));
(*s->cpu_fprintf)(s->file, " %s\n",
- object_class_get_name(oc));
+ name);
+ g_free(name);
}
void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
{
- ARMCPUListState s = {
+ CPUListState s = {
.file = f,
.cpu_fprintf = cpu_fprintf,
};
return x;
}
-uint32_t HELPER(abs)(uint32_t x)
-{
- return ((int32_t)x < 0) ? -x : x;
-}
-
#if defined(CONFIG_USER_ONLY)
-void do_interrupt (CPUARMState *env)
+void arm_cpu_do_interrupt(CPUState *cs)
{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+
env->exception_index = -1;
}
#else
/* Map CPU modes onto saved register banks. */
-static inline int bank_number(CPUARMState *env, int mode)
+int bank_number(int mode)
{
switch (mode) {
case ARM_CPU_MODE_USR:
case ARM_CPU_MODE_FIQ:
return 5;
}
- cpu_abort(env, "Bad mode %x\n", mode);
- return -1;
+ hw_error("bank number requested for bad CPSR mode value 0x%x\n", mode);
}
void switch_mode(CPUARMState *env, int mode)
memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
}
- i = bank_number(env, old_mode);
+ i = bank_number(old_mode);
env->banked_r13[i] = env->regs[13];
env->banked_r14[i] = env->regs[14];
env->banked_spsr[i] = env->spsr;
- i = bank_number(env, mode);
+ i = bank_number(mode);
env->regs[13] = env->banked_r13[i];
env->regs[14] = env->banked_r14[i];
env->spsr = env->banked_spsr[i];
pointer. */
}
-static void do_interrupt_v7m(CPUARMState *env)
+void arm_v7m_cpu_do_interrupt(CPUState *cs)
{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
uint32_t xpsr = xpsr_read(env);
uint32_t lr;
uint32_t addr;
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
return;
case EXCP_SWI:
- env->regs[15] += 2;
+ /* The PC already points to the next instruction. */
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
return;
case EXCP_PREFETCH_ABORT:
}
/* Handle a CPU exception. */
-void do_interrupt(CPUARMState *env)
+void arm_cpu_do_interrupt(CPUState *cs)
{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
uint32_t addr;
uint32_t mask;
int new_mode;
uint32_t offset;
- if (IS_M(env)) {
- do_interrupt_v7m(env);
- return;
- }
+ assert(!IS_M(env));
+
/* TODO: Vectored interrupt controller. */
switch (env->exception_index) {
case EXCP_UDEF:
}
env->regs[14] = env->regs[15] + offset;
env->regs[15] = addr;
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
/* Check section/page access permissions.
}
static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
- int is_user, target_phys_addr_t *phys_ptr,
+ int is_user, hwaddr *phys_ptr,
int *prot, target_ulong *page_size)
{
int code;
int ap;
int domain;
int domain_prot;
- target_phys_addr_t phys_addr;
+ hwaddr phys_addr;
/* Pagetable walk. */
/* Lookup l1 descriptor. */
}
static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
- int is_user, target_phys_addr_t *phys_ptr,
+ int is_user, hwaddr *phys_ptr,
int *prot, target_ulong *page_size)
{
int code;
int ap;
int domain = 0;
int domain_prot;
- target_phys_addr_t phys_addr;
+ hwaddr phys_addr;
/* Pagetable walk. */
/* Lookup l1 descriptor. */
static int get_phys_addr_lpae(CPUARMState *env, uint32_t address,
int access_type, int is_user,
- target_phys_addr_t *phys_ptr, int *prot,
+ hwaddr *phys_ptr, int *prot,
target_ulong *page_size_ptr)
{
/* Read an LPAE long-descriptor translation table. */
uint64_t ttbr;
int ttbr_select;
int n;
- target_phys_addr_t descaddr;
+ hwaddr descaddr;
uint32_t tableattrs;
target_ulong page_size;
uint32_t attrs;
static int get_phys_addr_mpu(CPUARMState *env, uint32_t address,
int access_type, int is_user,
- target_phys_addr_t *phys_ptr, int *prot)
+ hwaddr *phys_ptr, int *prot)
{
int n;
uint32_t mask;
*/
static inline int get_phys_addr(CPUARMState *env, uint32_t address,
int access_type, int is_user,
- target_phys_addr_t *phys_ptr, int *prot,
+ hwaddr *phys_ptr, int *prot,
target_ulong *page_size)
{
/* Fast Context Switch Extension. */
int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
int access_type, int mmu_idx)
{
- target_phys_addr_t phys_addr;
+ hwaddr phys_addr;
target_ulong page_size;
int prot;
int ret, is_user;
&page_size);
if (ret == 0) {
/* Map a single [sub]page. */
- phys_addr &= ~(target_phys_addr_t)0x3ff;
+ phys_addr &= ~(hwaddr)0x3ff;
address &= ~(uint32_t)0x3ff;
tlb_set_page (env, address, phys_addr, prot, mmu_idx, page_size);
return 0;
return 1;
}
-target_phys_addr_t cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr)
+hwaddr cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr)
{
- target_phys_addr_t phys_addr;
+ hwaddr phys_addr;
target_ulong page_size;
int prot;
int ret;
if ((env->uncached_cpsr & CPSR_M) == mode) {
env->regs[13] = val;
} else {
- env->banked_r13[bank_number(env, mode)] = val;
+ env->banked_r13[bank_number(mode)] = val;
}
}
if ((env->uncached_cpsr & CPSR_M) == mode) {
return env->regs[13];
} else {
- return env->banked_r13[bank_number(env, mode)];
+ return env->banked_r13[bank_number(mode)];
}
}
return (a & mask) | (b & ~mask);
}
-uint32_t HELPER(logicq_cc)(uint64_t val)
-{
- return (val >> 32) | (val != 0);
-}
-
/* VFP support. We follow the convention used for VFP instructions:
Single precision routines have a "s" suffix, double precision a
"d" suffix. */