helper.c (910e4f24975f53645d308aa6c895f4599dd47c43) | helper.c (761c46425e2d2a7a65cbbd1ee65f0abce769618c) |
---|---|
1/* 2 * ARM generic helpers. 3 * 4 * This code is licensed under the GNU GPL v2 or later. 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 --- 3668 unchanged lines hidden (view full) --- 3677 "PMSAv7 RGNR write >= # supported regions, %" PRIu32 3678 " > %" PRIu32 "\n", (uint32_t)value, nrgs); 3679 return; 3680 } 3681 3682 raw_write(env, ri, value); 3683} 3684 | 1/* 2 * ARM generic helpers. 3 * 4 * This code is licensed under the GNU GPL v2 or later. 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 --- 3668 unchanged lines hidden (view full) --- 3677 "PMSAv7 RGNR write >= # supported regions, %" PRIu32 3678 " > %" PRIu32 "\n", (uint32_t)value, nrgs); 3679 return; 3680 } 3681 3682 raw_write(env, ri, value); 3683} 3684 |
3685static void prbar_write(CPUARMState *env, const ARMCPRegInfo *ri, 3686 uint64_t value) 3687{ 3688 ARMCPU *cpu = env_archcpu(env); 3689 3690 tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ 3691 env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value; 3692} 3693 3694static uint64_t prbar_read(CPUARMState *env, const ARMCPRegInfo *ri) 3695{ 3696 return env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]]; 3697} 3698 3699static void prlar_write(CPUARMState *env, const ARMCPRegInfo *ri, 3700 uint64_t value) 3701{ 3702 ARMCPU *cpu = env_archcpu(env); 3703 3704 tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ 3705 env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value; 3706} 3707 3708static uint64_t prlar_read(CPUARMState *env, const ARMCPRegInfo *ri) 3709{ 3710 return env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]]; 3711} 3712 3713static void prselr_write(CPUARMState *env, const ARMCPRegInfo *ri, 3714 uint64_t value) 3715{ 3716 ARMCPU *cpu = env_archcpu(env); 3717 3718 /* 3719 * Ignore writes that would select not implemented region. 3720 * This is architecturally UNPREDICTABLE. 3721 */ 3722 if (value >= cpu->pmsav7_dregion) { 3723 return; 3724 } 3725 3726 env->pmsav7.rnr[M_REG_NS] = value; 3727} 3728 3729static void hprbar_write(CPUARMState *env, const ARMCPRegInfo *ri, 3730 uint64_t value) 3731{ 3732 ARMCPU *cpu = env_archcpu(env); 3733 3734 tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ 3735 env->pmsav8.hprbar[env->pmsav8.hprselr] = value; 3736} 3737 3738static uint64_t hprbar_read(CPUARMState *env, const ARMCPRegInfo *ri) 3739{ 3740 return env->pmsav8.hprbar[env->pmsav8.hprselr]; 3741} 3742 3743static void hprlar_write(CPUARMState *env, const ARMCPRegInfo *ri, 3744 uint64_t value) 3745{ 3746 ARMCPU *cpu = env_archcpu(env); 3747 3748 tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ 3749 env->pmsav8.hprlar[env->pmsav8.hprselr] = value; 3750} 3751 3752static uint64_t hprlar_read(CPUARMState *env, const ARMCPRegInfo *ri) 3753{ 3754 return env->pmsav8.hprlar[env->pmsav8.hprselr]; 3755} 3756 3757static void hprenr_write(CPUARMState *env, const ARMCPRegInfo *ri, 3758 uint64_t value) 3759{ 3760 uint32_t n; 3761 uint32_t bit; 3762 ARMCPU *cpu = env_archcpu(env); 3763 3764 /* Ignore writes to unimplemented regions */ 3765 int rmax = MIN(cpu->pmsav8r_hdregion, 32); 3766 value &= MAKE_64BIT_MASK(0, rmax); 3767 3768 tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ 3769 3770 /* Register alias is only valid for first 32 indexes */ 3771 for (n = 0; n < rmax; ++n) { 3772 bit = extract32(value, n, 1); 3773 env->pmsav8.hprlar[n] = deposit32( 3774 env->pmsav8.hprlar[n], 0, 1, bit); 3775 } 3776} 3777 3778static uint64_t hprenr_read(CPUARMState *env, const ARMCPRegInfo *ri) 3779{ 3780 uint32_t n; 3781 uint32_t result = 0x0; 3782 ARMCPU *cpu = env_archcpu(env); 3783 3784 /* Register alias is only valid for first 32 indexes */ 3785 for (n = 0; n < MIN(cpu->pmsav8r_hdregion, 32); ++n) { 3786 if (env->pmsav8.hprlar[n] & 0x1) { 3787 result |= (0x1 << n); 3788 } 3789 } 3790 return result; 3791} 3792 3793static void hprselr_write(CPUARMState *env, const ARMCPRegInfo *ri, 3794 uint64_t value) 3795{ 3796 ARMCPU *cpu = env_archcpu(env); 3797 3798 /* 3799 * Ignore writes that would select not implemented region. 3800 * This is architecturally UNPREDICTABLE. 3801 */ 3802 if (value >= cpu->pmsav8r_hdregion) { 3803 return; 3804 } 3805 3806 env->pmsav8.hprselr = value; 3807} 3808 3809static void pmsav8r_regn_write(CPUARMState *env, const ARMCPRegInfo *ri, 3810 uint64_t value) 3811{ 3812 ARMCPU *cpu = env_archcpu(env); 3813 uint8_t index = (extract32(ri->opc0, 0, 1) << 4) | 3814 (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1); 3815 3816 tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ 3817 3818 if (ri->opc1 & 4) { 3819 if (index >= cpu->pmsav8r_hdregion) { 3820 return; 3821 } 3822 if (ri->opc2 & 0x1) { 3823 env->pmsav8.hprlar[index] = value; 3824 } else { 3825 env->pmsav8.hprbar[index] = value; 3826 } 3827 } else { 3828 if (index >= cpu->pmsav7_dregion) { 3829 return; 3830 } 3831 if (ri->opc2 & 0x1) { 3832 env->pmsav8.rlar[M_REG_NS][index] = value; 3833 } else { 3834 env->pmsav8.rbar[M_REG_NS][index] = value; 3835 } 3836 } 3837} 3838 3839static uint64_t pmsav8r_regn_read(CPUARMState *env, const ARMCPRegInfo *ri) 3840{ 3841 ARMCPU *cpu = env_archcpu(env); 3842 uint8_t index = (extract32(ri->opc0, 0, 1) << 4) | 3843 (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1); 3844 3845 if (ri->opc1 & 4) { 3846 if (index >= cpu->pmsav8r_hdregion) { 3847 return 0x0; 3848 } 3849 if (ri->opc2 & 0x1) { 3850 return env->pmsav8.hprlar[index]; 3851 } else { 3852 return env->pmsav8.hprbar[index]; 3853 } 3854 } else { 3855 if (index >= cpu->pmsav7_dregion) { 3856 return 0x0; 3857 } 3858 if (ri->opc2 & 0x1) { 3859 return env->pmsav8.rlar[M_REG_NS][index]; 3860 } else { 3861 return env->pmsav8.rbar[M_REG_NS][index]; 3862 } 3863 } 3864} 3865 3866static const ARMCPRegInfo pmsav8r_cp_reginfo[] = { 3867 { .name = "PRBAR", 3868 .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 0, 3869 .access = PL1_RW, .type = ARM_CP_NO_RAW, 3870 .accessfn = access_tvm_trvm, 3871 .readfn = prbar_read, .writefn = prbar_write }, 3872 { .name = "PRLAR", 3873 .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 1, 3874 .access = PL1_RW, .type = ARM_CP_NO_RAW, 3875 .accessfn = access_tvm_trvm, 3876 .readfn = prlar_read, .writefn = prlar_write }, 3877 { .name = "PRSELR", .resetvalue = 0, 3878 .cp = 15, .opc1 = 0, .crn = 6, .crm = 2, .opc2 = 1, 3879 .access = PL1_RW, .accessfn = access_tvm_trvm, 3880 .writefn = prselr_write, 3881 .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]) }, 3882 { .name = "HPRBAR", .resetvalue = 0, 3883 .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 0, 3884 .access = PL2_RW, .type = ARM_CP_NO_RAW, 3885 .readfn = hprbar_read, .writefn = hprbar_write }, 3886 { .name = "HPRLAR", 3887 .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 1, 3888 .access = PL2_RW, .type = ARM_CP_NO_RAW, 3889 .readfn = hprlar_read, .writefn = hprlar_write }, 3890 { .name = "HPRSELR", .resetvalue = 0, 3891 .cp = 15, .opc1 = 4, .crn = 6, .crm = 2, .opc2 = 1, 3892 .access = PL2_RW, 3893 .writefn = hprselr_write, 3894 .fieldoffset = offsetof(CPUARMState, pmsav8.hprselr) }, 3895 { .name = "HPRENR", 3896 .cp = 15, .opc1 = 4, .crn = 6, .crm = 1, .opc2 = 1, 3897 .access = PL2_RW, .type = ARM_CP_NO_RAW, 3898 .readfn = hprenr_read, .writefn = hprenr_write }, 3899}; 3900 |
|
3685static const ARMCPRegInfo pmsav7_cp_reginfo[] = { 3686 /* Reset for all these registers is handled in arm_cpu_reset(), 3687 * because the PMSAv7 is also used by M-profile CPUs, which do 3688 * not register cpregs but still need the state to be reset. 3689 */ 3690 { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0, 3691 .access = PL1_RW, .type = ARM_CP_NO_RAW, 3692 .fieldoffset = offsetof(CPUARMState, pmsav7.drbar), --- 4509 unchanged lines hidden (view full) --- 8202 }; 8203 /* MPUIR is specific to PMSA V6+ */ 8204 ARMCPRegInfo id_mpuir_reginfo = { 8205 .name = "MPUIR", 8206 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, 8207 .access = PL1_R, .type = ARM_CP_CONST, 8208 .resetvalue = cpu->pmsav7_dregion << 8 8209 }; | 3901static const ARMCPRegInfo pmsav7_cp_reginfo[] = { 3902 /* Reset for all these registers is handled in arm_cpu_reset(), 3903 * because the PMSAv7 is also used by M-profile CPUs, which do 3904 * not register cpregs but still need the state to be reset. 3905 */ 3906 { .name = "DRBAR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 1, .opc2 = 0, 3907 .access = PL1_RW, .type = ARM_CP_NO_RAW, 3908 .fieldoffset = offsetof(CPUARMState, pmsav7.drbar), --- 4509 unchanged lines hidden (view full) --- 8418 }; 8419 /* MPUIR is specific to PMSA V6+ */ 8420 ARMCPRegInfo id_mpuir_reginfo = { 8421 .name = "MPUIR", 8422 .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4, 8423 .access = PL1_R, .type = ARM_CP_CONST, 8424 .resetvalue = cpu->pmsav7_dregion << 8 8425 }; |
8426 /* HMPUIR is specific to PMSA V8 */ 8427 ARMCPRegInfo id_hmpuir_reginfo = { 8428 .name = "HMPUIR", 8429 .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 4, 8430 .access = PL2_R, .type = ARM_CP_CONST, 8431 .resetvalue = cpu->pmsav8r_hdregion 8432 }; |
|
8210 static const ARMCPRegInfo crn0_wi_reginfo = { 8211 .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY, 8212 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, 8213 .type = ARM_CP_NOP | ARM_CP_OVERRIDE 8214 }; 8215#ifdef CONFIG_USER_ONLY 8216 static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = { 8217 { .name = "MIDR_EL1", --- 26 unchanged lines hidden (view full) --- 8244 define_one_arm_cp_reg(cpu, &id_v8_midr_alias_cp_reginfo); 8245 } 8246 } else { 8247 define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo); 8248 } 8249 define_arm_cp_regs(cpu, id_cp_reginfo); 8250 if (!arm_feature(env, ARM_FEATURE_PMSA)) { 8251 define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo); | 8433 static const ARMCPRegInfo crn0_wi_reginfo = { 8434 .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY, 8435 .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W, 8436 .type = ARM_CP_NOP | ARM_CP_OVERRIDE 8437 }; 8438#ifdef CONFIG_USER_ONLY 8439 static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = { 8440 { .name = "MIDR_EL1", --- 26 unchanged lines hidden (view full) --- 8467 define_one_arm_cp_reg(cpu, &id_v8_midr_alias_cp_reginfo); 8468 } 8469 } else { 8470 define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo); 8471 } 8472 define_arm_cp_regs(cpu, id_cp_reginfo); 8473 if (!arm_feature(env, ARM_FEATURE_PMSA)) { 8474 define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo); |
8475 } else if (arm_feature(env, ARM_FEATURE_PMSA) && 8476 arm_feature(env, ARM_FEATURE_V8)) { 8477 uint32_t i = 0; 8478 char *tmp_string; 8479 8480 define_one_arm_cp_reg(cpu, &id_mpuir_reginfo); 8481 define_one_arm_cp_reg(cpu, &id_hmpuir_reginfo); 8482 define_arm_cp_regs(cpu, pmsav8r_cp_reginfo); 8483 8484 /* Register alias is only valid for first 32 indexes */ 8485 for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) { 8486 uint8_t crm = 0b1000 | extract32(i, 1, 3); 8487 uint8_t opc1 = extract32(i, 4, 1); 8488 uint8_t opc2 = extract32(i, 0, 1) << 2; 8489 8490 tmp_string = g_strdup_printf("PRBAR%u", i); 8491 ARMCPRegInfo tmp_prbarn_reginfo = { 8492 .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW, 8493 .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2, 8494 .access = PL1_RW, .resetvalue = 0, 8495 .accessfn = access_tvm_trvm, 8496 .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read 8497 }; 8498 define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo); 8499 g_free(tmp_string); 8500 8501 opc2 = extract32(i, 0, 1) << 2 | 0x1; 8502 tmp_string = g_strdup_printf("PRLAR%u", i); 8503 ARMCPRegInfo tmp_prlarn_reginfo = { 8504 .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW, 8505 .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2, 8506 .access = PL1_RW, .resetvalue = 0, 8507 .accessfn = access_tvm_trvm, 8508 .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read 8509 }; 8510 define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo); 8511 g_free(tmp_string); 8512 } 8513 8514 /* Register alias is only valid for first 32 indexes */ 8515 for (i = 0; i < MIN(cpu->pmsav8r_hdregion, 32); ++i) { 8516 uint8_t crm = 0b1000 | extract32(i, 1, 3); 8517 uint8_t opc1 = 0b100 | extract32(i, 4, 1); 8518 uint8_t opc2 = extract32(i, 0, 1) << 2; 8519 8520 tmp_string = g_strdup_printf("HPRBAR%u", i); 8521 ARMCPRegInfo tmp_hprbarn_reginfo = { 8522 .name = tmp_string, 8523 .type = ARM_CP_NO_RAW, 8524 .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2, 8525 .access = PL2_RW, .resetvalue = 0, 8526 .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read 8527 }; 8528 define_one_arm_cp_reg(cpu, &tmp_hprbarn_reginfo); 8529 g_free(tmp_string); 8530 8531 opc2 = extract32(i, 0, 1) << 2 | 0x1; 8532 tmp_string = g_strdup_printf("HPRLAR%u", i); 8533 ARMCPRegInfo tmp_hprlarn_reginfo = { 8534 .name = tmp_string, 8535 .type = ARM_CP_NO_RAW, 8536 .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2, 8537 .access = PL2_RW, .resetvalue = 0, 8538 .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read 8539 }; 8540 define_one_arm_cp_reg(cpu, &tmp_hprlarn_reginfo); 8541 g_free(tmp_string); 8542 } |
|
8252 } else if (arm_feature(env, ARM_FEATURE_V7)) { 8253 define_one_arm_cp_reg(cpu, &id_mpuir_reginfo); 8254 } 8255 } 8256 8257 if (arm_feature(env, ARM_FEATURE_MPIDR)) { 8258 ARMCPRegInfo mpidr_cp_reginfo[] = { 8259 { .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH, --- 105 unchanged lines hidden (view full) --- 8365 if (arm_feature(env, ARM_FEATURE_XSCALE)) { 8366 /* Normally we would always end the TB on an SCTLR write, but Linux 8367 * arch/arm/mach-pxa/sleep.S expects two instructions following 8368 * an MMU enable to execute from cache. Imitate this behaviour. 8369 */ 8370 sctlr.type |= ARM_CP_SUPPRESS_TB_END; 8371 } 8372 define_one_arm_cp_reg(cpu, &sctlr); | 8543 } else if (arm_feature(env, ARM_FEATURE_V7)) { 8544 define_one_arm_cp_reg(cpu, &id_mpuir_reginfo); 8545 } 8546 } 8547 8548 if (arm_feature(env, ARM_FEATURE_MPIDR)) { 8549 ARMCPRegInfo mpidr_cp_reginfo[] = { 8550 { .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH, --- 105 unchanged lines hidden (view full) --- 8656 if (arm_feature(env, ARM_FEATURE_XSCALE)) { 8657 /* Normally we would always end the TB on an SCTLR write, but Linux 8658 * arch/arm/mach-pxa/sleep.S expects two instructions following 8659 * an MMU enable to execute from cache. Imitate this behaviour. 8660 */ 8661 sctlr.type |= ARM_CP_SUPPRESS_TB_END; 8662 } 8663 define_one_arm_cp_reg(cpu, &sctlr); |
8664 8665 if (arm_feature(env, ARM_FEATURE_PMSA) && 8666 arm_feature(env, ARM_FEATURE_V8)) { 8667 ARMCPRegInfo vsctlr = { 8668 .name = "VSCTLR", .state = ARM_CP_STATE_AA32, 8669 .cp = 15, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0, 8670 .access = PL2_RW, .resetvalue = 0x0, 8671 .fieldoffset = offsetoflow32(CPUARMState, cp15.vsctlr), 8672 }; 8673 define_one_arm_cp_reg(cpu, &vsctlr); 8674 } |
|
8373 } 8374 8375 if (cpu_isar_feature(aa64_lor, cpu)) { 8376 define_arm_cp_regs(cpu, lor_reginfo); 8377 } 8378 if (cpu_isar_feature(aa64_pan, cpu)) { 8379 define_one_arm_cp_reg(cpu, &pan_reginfo); 8380 } --- 3300 unchanged lines hidden --- | 8675 } 8676 8677 if (cpu_isar_feature(aa64_lor, cpu)) { 8678 define_arm_cp_regs(cpu, lor_reginfo); 8679 } 8680 if (cpu_isar_feature(aa64_pan, cpu)) { 8681 define_one_arm_cp_reg(cpu, &pan_reginfo); 8682 } --- 3300 unchanged lines hidden --- |