Commit 23ce84b1 authored by Andrzej Zaborowski's avatar Andrzej Zaborowski
Browse files

Merge branch 'target-arm.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm

parents 9423a2e8 db8336cd
Loading
Loading
Loading
Loading
+42 −53
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
    env->cp15.c0_cpuid = id;
    switch (id) {
    case ARM_CPUID_ARM926:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_VFP);
        env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
@@ -61,14 +60,12 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
        env->cp15.c1_sys = 0x00090078;
        break;
    case ARM_CPUID_ARM946:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_MPU);
        env->cp15.c0_cachetype = 0x0f004006;
        env->cp15.c1_sys = 0x00000078;
        break;
    case ARM_CPUID_ARM1026:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_VFP);
        set_feature(env, ARM_FEATURE_AUXCR);
@@ -85,11 +82,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
         * older core than plain "arm1136". In particular this does not
         * have the v6K features.
         */
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_V6);
        set_feature(env, ARM_FEATURE_VFP);
        set_feature(env, ARM_FEATURE_AUXCR);
        /* These ID register values are correct for 1136 but may be wrong
         * for 1136_r2 (in particular r0p2 does not actually implement most
         * of the ID registers).
@@ -103,12 +97,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
        env->cp15.c1_sys = 0x00050078;
        break;
    case ARM_CPUID_ARM1176:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_V6);
        set_feature(env, ARM_FEATURE_V6K);
        set_feature(env, ARM_FEATURE_VFP);
        set_feature(env, ARM_FEATURE_AUXCR);
        set_feature(env, ARM_FEATURE_VAPA);
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b5;
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
@@ -119,12 +109,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
        env->cp15.c1_sys = 0x00050078;
        break;
    case ARM_CPUID_ARM11MPCORE:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_V6);
        set_feature(env, ARM_FEATURE_V6K);
        set_feature(env, ARM_FEATURE_VFP);
        set_feature(env, ARM_FEATURE_AUXCR);
        set_feature(env, ARM_FEATURE_VAPA);
        env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
        env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
@@ -134,14 +120,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
        env->cp15.c0_cachetype = 0x1dd20d2;
        break;
    case ARM_CPUID_CORTEXA8:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_V6);
        set_feature(env, ARM_FEATURE_V6K);
        set_feature(env, ARM_FEATURE_V7);
        set_feature(env, ARM_FEATURE_AUXCR);
        set_feature(env, ARM_FEATURE_THUMB2);
        set_feature(env, ARM_FEATURE_VFP);
        set_feature(env, ARM_FEATURE_VFP3);
        set_feature(env, ARM_FEATURE_NEON);
        set_feature(env, ARM_FEATURE_THUMB2EE);
@@ -158,14 +137,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
        env->cp15.c1_sys = 0x00c50078;
        break;
    case ARM_CPUID_CORTEXA9:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_V6);
        set_feature(env, ARM_FEATURE_V6K);
        set_feature(env, ARM_FEATURE_V7);
        set_feature(env, ARM_FEATURE_AUXCR);
        set_feature(env, ARM_FEATURE_THUMB2);
        set_feature(env, ARM_FEATURE_VFP);
        set_feature(env, ARM_FEATURE_VFP3);
        set_feature(env, ARM_FEATURE_VFP_FP16);
        set_feature(env, ARM_FEATURE_NEON);
@@ -187,23 +159,11 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
        env->cp15.c1_sys = 0x00c50078;
        break;
    case ARM_CPUID_CORTEXM3:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_V6);
        set_feature(env, ARM_FEATURE_THUMB2);
        set_feature(env, ARM_FEATURE_V7);
        set_feature(env, ARM_FEATURE_M);
        set_feature(env, ARM_FEATURE_THUMB_DIV);
        break;
    case ARM_CPUID_ANY: /* For userspace emulation.  */
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_V6);
        set_feature(env, ARM_FEATURE_V6K);
        set_feature(env, ARM_FEATURE_V7);
        set_feature(env, ARM_FEATURE_THUMB2);
        set_feature(env, ARM_FEATURE_VFP);
        set_feature(env, ARM_FEATURE_VFP3);
        set_feature(env, ARM_FEATURE_VFP4);
        set_feature(env, ARM_FEATURE_VFP_FP16);
        set_feature(env, ARM_FEATURE_NEON);
@@ -226,7 +186,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
    case ARM_CPUID_PXA260:
    case ARM_CPUID_PXA261:
    case ARM_CPUID_PXA262:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_XSCALE);
        /* JTAG_ID is ((id << 28) | 0x09265013) */
@@ -239,7 +198,6 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
    case ARM_CPUID_PXA270_B1:
    case ARM_CPUID_PXA270_C0:
    case ARM_CPUID_PXA270_C5:
        set_feature(env, ARM_FEATURE_V4T);
        set_feature(env, ARM_FEATURE_V5);
        set_feature(env, ARM_FEATURE_XSCALE);
        /* JTAG_ID is ((id << 28) | 0x09265013) */
@@ -261,10 +219,37 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
    /* Some features automatically imply others: */
    if (arm_feature(env, ARM_FEATURE_V7)) {
        set_feature(env, ARM_FEATURE_VAPA);
        set_feature(env, ARM_FEATURE_THUMB2);
        if (!arm_feature(env, ARM_FEATURE_M)) {
            set_feature(env, ARM_FEATURE_V6K);
        } else {
            set_feature(env, ARM_FEATURE_V6);
        }
    }
    if (arm_feature(env, ARM_FEATURE_V6K)) {
        set_feature(env, ARM_FEATURE_V6);
    }
    if (arm_feature(env, ARM_FEATURE_V6)) {
        set_feature(env, ARM_FEATURE_V5);
        if (!arm_feature(env, ARM_FEATURE_M)) {
            set_feature(env, ARM_FEATURE_AUXCR);
        }
    }
    if (arm_feature(env, ARM_FEATURE_V5)) {
        set_feature(env, ARM_FEATURE_V4T);
    }
    if (arm_feature(env, ARM_FEATURE_M)) {
        set_feature(env, ARM_FEATURE_THUMB_DIV);
    }
    if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {
        set_feature(env, ARM_FEATURE_THUMB_DIV);
    }
    if (arm_feature(env, ARM_FEATURE_VFP4)) {
        set_feature(env, ARM_FEATURE_VFP3);
    }
    if (arm_feature(env, ARM_FEATURE_VFP3)) {
        set_feature(env, ARM_FEATURE_VFP);
    }
}

void cpu_reset(CPUARMState *env)
@@ -951,13 +936,14 @@ void do_interrupt(CPUARMState *env)
/* Check section/page access permissions.
   Returns the page protection flags, or zero if the access is not
   permitted.  */
static inline int check_ap(CPUState *env, int ap, int domain, int access_type,
                           int is_user)
static inline int check_ap(CPUState *env, int ap, int domain_prot,
                           int access_type, int is_user)
{
  int prot_ro;

  if (domain == 3)
  if (domain_prot == 3) {
    return PAGE_READ | PAGE_WRITE;
  }

  if (access_type == 1)
      prot_ro = 0;
@@ -1023,6 +1009,7 @@ static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
    int type;
    int ap;
    int domain;
    int domain_prot;
    uint32_t phys_addr;

    /* Pagetable walk.  */
@@ -1030,13 +1017,14 @@ static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
    table = get_level1_table_address(env, address);
    desc = ldl_phys(table);
    type = (desc & 3);
    domain = (env->cp15.c3 >> ((desc >> 4) & 0x1e)) & 3;
    domain = (desc >> 5) & 0x0f;
    domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
    if (type == 0) {
        /* Section translation fault.  */
        code = 5;
        goto do_fault;
    }
    if (domain == 0 || domain == 2) {
    if (domain_prot == 0 || domain_prot == 2) {
        if (type == 2)
            code = 9; /* Section domain fault.  */
        else
@@ -1094,7 +1082,7 @@ static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
        }
        code = 15;
    }
    *prot = check_ap(env, ap, domain, access_type, is_user);
    *prot = check_ap(env, ap, domain_prot, access_type, is_user);
    if (!*prot) {
        /* Access permission fault.  */
        goto do_fault;
@@ -1117,6 +1105,7 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
    int type;
    int ap;
    int domain;
    int domain_prot;
    uint32_t phys_addr;

    /* Pagetable walk.  */
@@ -1134,10 +1123,10 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
        domain = 0;
    } else {
        /* Section or page.  */
        domain = (desc >> 4) & 0x1e;
        domain = (desc >> 5) & 0x0f;
    }
    domain = (env->cp15.c3 >> domain) & 3;
    if (domain == 0 || domain == 2) {
    domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
    if (domain_prot == 0 || domain_prot == 2) {
        if (type == 2)
            code = 9; /* Section domain fault.  */
        else
@@ -1182,7 +1171,7 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
        }
        code = 15;
    }
    if (domain == 3) {
    if (domain_prot == 3) {
        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
    } else {
        if (xn && access_type == 2)
@@ -1194,7 +1183,7 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
            code = (code == 15) ? 6 : 3;
            goto do_fault;
        }
        *prot = check_ap(env, ap, domain, access_type, is_user);
        *prot = check_ap(env, ap, domain_prot, access_type, is_user);
        if (!*prot) {
            /* Access permission fault.  */
            goto do_fault;