Merge branch 'target-arm.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm
* 'target-arm.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm: Add Cortex-A15 CPU definition Add dummy implementation of generic timer cp15 registers arm: store the config_base_register during cpu_reset target-arm/helper.c: Don't assume softfloat int32 is 32 bits only target-arm: Fix implementation of TLB invalidate operations
This commit is contained in:
commit
9ec032d2ac
@ -382,6 +382,7 @@ enum arm_features {
|
||||
ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
|
||||
ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
|
||||
ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
|
||||
ARM_FEATURE_GENERIC_TIMER,
|
||||
};
|
||||
|
||||
static inline int arm_feature(CPUARMState *env, int feature)
|
||||
@ -432,6 +433,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
|
||||
#define ARM_CPUID_ARM11MPCORE 0x410fb022
|
||||
#define ARM_CPUID_CORTEXA8 0x410fc080
|
||||
#define ARM_CPUID_CORTEXA9 0x410fc090
|
||||
#define ARM_CPUID_CORTEXA15 0x412fc0f1
|
||||
#define ARM_CPUID_CORTEXM3 0x410fc231
|
||||
#define ARM_CPUID_ANY 0xffffffff
|
||||
|
||||
|
@ -10,6 +10,16 @@
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#include "hw/loader.h"
|
||||
#endif
|
||||
#include "sysemu.h"
|
||||
|
||||
static uint32_t cortexa15_cp15_c0_c1[8] = {
|
||||
0x00001131, 0x00011011, 0x02010555, 0x00000000,
|
||||
0x10201105, 0x20000000, 0x01240000, 0x02102211
|
||||
};
|
||||
|
||||
static uint32_t cortexa15_cp15_c0_c2[8] = {
|
||||
0x02101110, 0x13112111, 0x21232041, 0x11112131, 0x10011142, 0, 0, 0
|
||||
};
|
||||
|
||||
static uint32_t cortexa9_cp15_c0_c1[8] =
|
||||
{ 0x1031, 0x11, 0x000, 0, 0x00100103, 0x20000000, 0x01230000, 0x00002111 };
|
||||
@ -158,6 +168,27 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */
|
||||
env->cp15.c1_sys = 0x00c50078;
|
||||
break;
|
||||
case ARM_CPUID_CORTEXA15:
|
||||
set_feature(env, ARM_FEATURE_V7);
|
||||
set_feature(env, ARM_FEATURE_VFP4);
|
||||
set_feature(env, ARM_FEATURE_VFP_FP16);
|
||||
set_feature(env, ARM_FEATURE_NEON);
|
||||
set_feature(env, ARM_FEATURE_THUMB2EE);
|
||||
set_feature(env, ARM_FEATURE_ARM_DIV);
|
||||
set_feature(env, ARM_FEATURE_V7MP);
|
||||
set_feature(env, ARM_FEATURE_GENERIC_TIMER);
|
||||
env->vfp.xregs[ARM_VFP_FPSID] = 0x410430f0;
|
||||
env->vfp.xregs[ARM_VFP_MVFR0] = 0x10110222;
|
||||
env->vfp.xregs[ARM_VFP_MVFR1] = 0x11111111;
|
||||
memcpy(env->cp15.c0_c1, cortexa15_cp15_c0_c1, 8 * sizeof(uint32_t));
|
||||
memcpy(env->cp15.c0_c2, cortexa15_cp15_c0_c2, 8 * sizeof(uint32_t));
|
||||
env->cp15.c0_cachetype = 0x8444c004;
|
||||
env->cp15.c0_clid = 0x0a200023;
|
||||
env->cp15.c0_ccsid[0] = 0x701fe00a; /* 32K L1 dcache */
|
||||
env->cp15.c0_ccsid[1] = 0x201fe00a; /* 32K L1 icache */
|
||||
env->cp15.c0_ccsid[2] = 0x711fe07a; /* 4096K L2 unified cache */
|
||||
env->cp15.c1_sys = 0x00c50078;
|
||||
break;
|
||||
case ARM_CPUID_CORTEXM3:
|
||||
set_feature(env, ARM_FEATURE_V7);
|
||||
set_feature(env, ARM_FEATURE_M);
|
||||
@ -255,6 +286,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
void cpu_reset(CPUARMState *env)
|
||||
{
|
||||
uint32_t id;
|
||||
uint32_t tmp = 0;
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
||||
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
||||
@ -262,9 +294,11 @@ void cpu_reset(CPUARMState *env)
|
||||
}
|
||||
|
||||
id = env->cp15.c0_cpuid;
|
||||
tmp = env->cp15.c15_config_base_address;
|
||||
memset(env, 0, offsetof(CPUARMState, breakpoints));
|
||||
if (id)
|
||||
cpu_reset_model_id(env, id);
|
||||
env->cp15.c15_config_base_address = tmp;
|
||||
#if defined (CONFIG_USER_ONLY)
|
||||
env->uncached_cpsr = ARM_CPU_MODE_USR;
|
||||
/* For user mode we must enable access to coprocessors */
|
||||
@ -413,6 +447,7 @@ static const struct arm_cpu_t arm_cpu_names[] = {
|
||||
{ ARM_CPUID_CORTEXM3, "cortex-m3"},
|
||||
{ ARM_CPUID_CORTEXA8, "cortex-a8"},
|
||||
{ ARM_CPUID_CORTEXA9, "cortex-a9"},
|
||||
{ ARM_CPUID_CORTEXA15, "cortex-a15" },
|
||||
{ ARM_CPUID_TI925T, "ti925t" },
|
||||
{ ARM_CPUID_PXA250, "pxa250" },
|
||||
{ ARM_CPUID_SA1100, "sa1100" },
|
||||
@ -667,8 +702,6 @@ uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)
|
||||
|
||||
#else
|
||||
|
||||
extern int semihosting_enabled;
|
||||
|
||||
/* Map CPU modes onto saved register banks. */
|
||||
static inline int bank_number(CPUState *env, int mode)
|
||||
{
|
||||
@ -1610,18 +1643,17 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
|
||||
break;
|
||||
case 8: /* MMU TLB control. */
|
||||
switch (op2) {
|
||||
case 0: /* Invalidate all. */
|
||||
tlb_flush(env, 0);
|
||||
case 0: /* Invalidate all (TLBIALL) */
|
||||
tlb_flush(env, 1);
|
||||
break;
|
||||
case 1: /* Invalidate single TLB entry. */
|
||||
case 1: /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
|
||||
tlb_flush_page(env, val & TARGET_PAGE_MASK);
|
||||
break;
|
||||
case 2: /* Invalidate on ASID. */
|
||||
case 2: /* Invalidate by ASID (TLBIASID) */
|
||||
tlb_flush(env, val == 0);
|
||||
break;
|
||||
case 3: /* Invalidate single entry on MVA. */
|
||||
/* ??? This is like case 1, but ignores ASID. */
|
||||
tlb_flush(env, 1);
|
||||
case 3: /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
|
||||
tlb_flush_page(env, val & TARGET_PAGE_MASK);
|
||||
break;
|
||||
default:
|
||||
goto bad_reg;
|
||||
@ -1762,7 +1794,11 @@ void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)
|
||||
goto bad_reg;
|
||||
}
|
||||
break;
|
||||
case 14: /* Reserved. */
|
||||
case 14: /* Generic timer */
|
||||
if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
|
||||
/* Dummy implementation: RAZ/WI for all */
|
||||
break;
|
||||
}
|
||||
goto bad_reg;
|
||||
case 15: /* Implementation specific. */
|
||||
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
|
||||
@ -1939,6 +1975,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
|
||||
case ARM_CPUID_CORTEXA8:
|
||||
return 2;
|
||||
case ARM_CPUID_CORTEXA9:
|
||||
case ARM_CPUID_CORTEXA15:
|
||||
return 0;
|
||||
default:
|
||||
goto bad_reg;
|
||||
@ -2059,11 +2096,26 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
|
||||
goto bad_reg;
|
||||
}
|
||||
case 1: /* L2 cache */
|
||||
if (crm != 0) {
|
||||
/* L2 Lockdown and Auxiliary control. */
|
||||
switch (op2) {
|
||||
case 0:
|
||||
/* L2 cache lockdown (A8 only) */
|
||||
return 0;
|
||||
case 2:
|
||||
/* L2 cache auxiliary control (A8) or control (A15) */
|
||||
if (ARM_CPUID(env) == ARM_CPUID_CORTEXA15) {
|
||||
/* Linux wants the number of processors from here.
|
||||
* Might as well set the interrupt-controller bit too.
|
||||
*/
|
||||
return ((smp_cpus - 1) << 24) | (1 << 23);
|
||||
}
|
||||
return 0;
|
||||
case 3:
|
||||
/* L2 cache extended control (A15) */
|
||||
return 0;
|
||||
default:
|
||||
goto bad_reg;
|
||||
}
|
||||
/* L2 Lockdown and Auxiliary control. */
|
||||
return 0;
|
||||
default:
|
||||
goto bad_reg;
|
||||
}
|
||||
@ -2132,7 +2184,11 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
|
||||
default:
|
||||
goto bad_reg;
|
||||
}
|
||||
case 14: /* Reserved. */
|
||||
case 14: /* Generic timer */
|
||||
if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
|
||||
/* Dummy implementation: RAZ/WI for all */
|
||||
return 0;
|
||||
}
|
||||
goto bad_reg;
|
||||
case 15: /* Implementation specific. */
|
||||
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
|
||||
@ -2786,7 +2842,7 @@ DO_VFP_cmp(d, float64)
|
||||
float##fsz HELPER(name)(uint32_t x, void *fpstp) \
|
||||
{ \
|
||||
float_status *fpst = fpstp; \
|
||||
return sign##int32_to_##float##fsz(x, fpst); \
|
||||
return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
|
||||
}
|
||||
|
||||
#define CONV_FTOI(name, fsz, sign, round) \
|
||||
|
Loading…
Reference in New Issue
Block a user