static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,

                                 MMUAccessType access_type, ARMMMUIdx mmu_idx,

                                 hwaddr *phys_ptr, int *prot,

                                 ARMMMUFaultInfo *fi)

{

    ARMCPU *cpu = arm_env_get_cpu(env);

    int n;

    bool is_user = regime_is_user(env, mmu_idx);



    *phys_ptr = address;

    *prot = 0;



    if (regime_translation_disabled(env, mmu_idx) ||

        m_is_ppb_region(env, address)) {

        /* MPU disabled or M profile PPB access: use default memory map.

         * The other case which uses the default memory map in the

         * v7M ARM ARM pseudocode is exception vector reads from the vector

         * table. In QEMU those accesses are done in arm_v7m_load_vector(),

         * which always does a direct read using address_space_ldl(), rather

         * than going via this function, so we don't need to check that here.

         */

        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);

    } else { /* MPU enabled */

        for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {

            /* region search */

            uint32_t base = env->pmsav7.drbar[n];

            uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5);

            uint32_t rmask;

            bool srdis = false;



            if (!(env->pmsav7.drsr[n] & 0x1)) {

                continue;




            if (!rsize) {

                qemu_log_mask(LOG_GUEST_ERROR,

                              "DRSR[%d]: Rsize field cannot be 0\n", n);

                continue;


            rsize++;

            rmask = (1ull << rsize) - 1;



            if (base & rmask) {

                qemu_log_mask(LOG_GUEST_ERROR,

                              "DRBAR[%d]: 0x%" PRIx32 " misaligned "

                              "to DRSR region size, mask = 0x%" PRIx32 "\n",

                              n, base, rmask);

                continue;




            if (address < base || address > base + rmask) {

                continue;




            /* Region matched */



            if (rsize >= 8) { /* no subregions for regions < 256 bytes */

                int i, snd;

                uint32_t srdis_mask;



                rsize -= 3; /* sub region size (power of 2) */

                snd = ((address - base) >> rsize) & 0x7;

                srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1);



                srdis_mask = srdis ? 0x3 : 0x0;

                for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) {

                    /* This will check in groups of 2, 4 and then 8, whether

                     * the subregion bits are consistent. rsize is incremented

                     * back up to give the region size, considering consistent

                     * adjacent subregions as one region. Stop testing if rsize

                     * is already big enough for an entire QEMU page.

                     */

                    int snd_rounded = snd & ~(i - 1);

                    uint32_t srdis_multi = extract32(env->pmsav7.drsr[n],

                                                     snd_rounded + 8, i);

                    if (srdis_mask ^ srdis_multi) {



                    srdis_mask = (srdis_mask << i) | srdis_mask;

                    rsize++;



            if (rsize < TARGET_PAGE_BITS) {

                qemu_log_mask(LOG_UNIMP,

                              "DRSR[%d]: No support for MPU (sub)region "

                              "alignment of %" PRIu32 " bits. Minimum is %d\n",

                              n, rsize, TARGET_PAGE_BITS);

                continue;


            if (srdis) {

                continue;






        if (n == -1) { /* no hits */

            if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {

                /* background fault */

                fi->type = ARMFault_Background;

                return true;


            get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);

        } else { /* a MPU hit! */

            uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);

            uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);



            if (m_is_system_region(env, address)) {

                /* System space is always execute never */

                xn = 1;




            if (is_user) { /* User mode AP bit decoding */

                switch (ap) {

                case 0:

                case 1:

                case 5:

                    break; /* no access */

                case 3:

                    *prot |= PAGE_WRITE;


                case 2:

                case 6:










                default:

                    qemu_log_mask(LOG_GUEST_ERROR,

                                  "DRACR[%d]: Bad value for AP bits: 0x%"

                                  PRIx32 "\n", n, ap);


            } else { /* Priv. mode AP bits decoding */

                switch (ap) {

                case 0:

                    break; /* no access */

                case 1:

                case 2:

                case 3:

                    *prot |= PAGE_WRITE;


                case 5:

                case 6:










                default:

                    qemu_log_mask(LOG_GUEST_ERROR,

                                  "DRACR[%d]: Bad value for AP bits: 0x%"

                                  PRIx32 "\n", n, ap);





            /* execute never */

            if (xn) {

                *prot &= ~PAGE_EXEC;






    fi->type = ARMFault_Permission;

    fi->level = 1;

    return !(*prot & (1 << access_type));

static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,

                                 MMUAccessType access_type, ARMMMUIdx mmu_idx,

                                 hwaddr *phys_ptr, int *prot,

                                 ARMMMUFaultInfo *fi)

{

    ARMCPU *cpu = arm_env_get_cpu(env);

    int n;

    bool is_user = regime_is_user(env, mmu_idx);



    *phys_ptr = address;

    *prot = 0;



    if (regime_translation_disabled(env, mmu_idx) ||

        m_is_ppb_region(env, address)) {

        













        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);

    } else { 

        for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {

            

            uint32_t base = env->pmsav7.drbar[n];

            uint32_t rsize = extract32(env->pmsav7.drsr[n], 1, 5);

            uint32_t rmask;

            bool srdis = false;



            if (!(env->pmsav7.drsr[n] & 0x1)) {

                continue;




            if (!rsize) {

                qemu_log_mask(LOG_GUEST_ERROR,

                              "DRSR[%d]: Rsize field cannot be 0\n", n);

                continue;


            rsize++;

            rmask = (1ull << rsize) - 1;



            if (base & rmask) {

                qemu_log_mask(LOG_GUEST_ERROR,

                              "DRBAR[%d]: 0x%" PRIx32 " misaligned "

                              "to DRSR region size, mask = 0x%" PRIx32 "\n",

                              n, base, rmask);

                continue;




            if (address < base || address > base + rmask) {

                continue;




            



            if (rsize >= 8) { 

                int i, snd;

                uint32_t srdis_mask;



                rsize -= 3; 

                snd = ((address - base) >> rsize) & 0x7;

                srdis = extract32(env->pmsav7.drsr[n], snd + 8, 1);



                srdis_mask = srdis ? 0x3 : 0x0;

                for (i = 2; i <= 8 && rsize < TARGET_PAGE_BITS; i *= 2) {

                    











                    int snd_rounded = snd & ~(i - 1);

                    uint32_t srdis_multi = extract32(env->pmsav7.drsr[n],

                                                     snd_rounded + 8, i);

                    if (srdis_mask ^ srdis_multi) {



                    srdis_mask = (srdis_mask << i) | srdis_mask;

                    rsize++;



            if (rsize < TARGET_PAGE_BITS) {

                qemu_log_mask(LOG_UNIMP,

                              "DRSR[%d]: No support for MPU (sub)region "

                              "alignment of %" PRIu32 " bits. Minimum is %d\n",

                              n, rsize, TARGET_PAGE_BITS);

                continue;


            if (srdis) {

                continue;






        if (n == -1) { 

            if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {

                

                fi->type = ARMFault_Background;

                return true;


            get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);

        } else { 

            uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);

            uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);



            if (m_is_system_region(env, address)) {

                

                xn = 1;




            if (is_user) { 

                switch (ap) {

                case 0:

                case 1:

                case 5:

                    break; 

                case 3:

                    *prot |= PAGE_WRITE;


                case 2:

                case 6:










                default:

                    qemu_log_mask(LOG_GUEST_ERROR,

                                  "DRACR[%d]: Bad value for AP bits: 0x%"

                                  PRIx32 "\n", n, ap);


            } else { 

                switch (ap) {

                case 0:

                    break; 

                case 1:

                case 2:

                case 3:

                    *prot |= PAGE_WRITE;


                case 5:

                case 6:










                default:

                    qemu_log_mask(LOG_GUEST_ERROR,

                                  "DRACR[%d]: Bad value for AP bits: 0x%"

                                  PRIx32 "\n", n, ap);





            

            if (xn) {

                *prot &= ~PAGE_EXEC;






    fi->type = ARMFault_Permission;

    fi->level = 1;

    return !(*prot & (1 << access_type));

static bool FUNC_0(CPUARMState *env, uint32_t address,

                                 MMUAccessType access_type, ARMMMUIdx mmu_idx,

                                 hwaddr *phys_ptr, int *prot,

                                 ARMMMUFaultInfo *fi)

{

    ARMCPU *cpu = arm_env_get_cpu(env);

    int VAR_0;

    bool is_user = regime_is_user(env, mmu_idx);



    *phys_ptr = address;

    *prot = 0;



    if (regime_translation_disabled(env, mmu_idx) ||

        m_is_ppb_region(env, address)) {

        













        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);

    } else { 

        for (VAR_0 = (int)cpu->pmsav7_dregion - 1; VAR_0 >= 0; VAR_0--) {

            

            uint32_t base = env->pmsav7.drbar[VAR_0];

            uint32_t rsize = extract32(env->pmsav7.drsr[VAR_0], 1, 5);

            uint32_t rmask;

            bool srdis = false;



            if (!(env->pmsav7.drsr[VAR_0] & 0x1)) {

                continue;




            if (!rsize) {

                qemu_log_mask(LOG_GUEST_ERROR,

                              "DRSR[%d]: Rsize field cannot be 0\VAR_0", VAR_0);

                continue;


            rsize++;

            rmask = (1ull << rsize) - 1;



            if (base & rmask) {

                qemu_log_mask(LOG_GUEST_ERROR,

                              "DRBAR[%d]: 0x%" PRIx32 " misaligned "

                              "to DRSR region size, mask = 0x%" PRIx32 "\VAR_0",

                              VAR_0, base, rmask);

                continue;




            if (address < base || address > base + rmask) {

                continue;




            



            if (rsize >= 8) { 

                int VAR_1, VAR_2;

                uint32_t srdis_mask;



                rsize -= 3; 

                VAR_2 = ((address - base) >> rsize) & 0x7;

                srdis = extract32(env->pmsav7.drsr[VAR_0], VAR_2 + 8, 1);



                srdis_mask = srdis ? 0x3 : 0x0;

                for (VAR_1 = 2; VAR_1 <= 8 && rsize < TARGET_PAGE_BITS; VAR_1 *= 2) {

                    











                    int snd_rounded = VAR_2 & ~(VAR_1 - 1);

                    uint32_t srdis_multi = extract32(env->pmsav7.drsr[VAR_0],

                                                     snd_rounded + 8, VAR_1);

                    if (srdis_mask ^ srdis_multi) {



                    srdis_mask = (srdis_mask << VAR_1) | srdis_mask;

                    rsize++;



            if (rsize < TARGET_PAGE_BITS) {

                qemu_log_mask(LOG_UNIMP,

                              "DRSR[%d]: No support for MPU (sub)region "

                              "alignment of %" PRIu32 " bits. Minimum is %d\VAR_0",

                              VAR_0, rsize, TARGET_PAGE_BITS);

                continue;


            if (srdis) {

                continue;






        if (VAR_0 == -1) { 

            if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {

                

                fi->type = ARMFault_Background;

                return true;


            get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);

        } else { 

            uint32_t ap = extract32(env->pmsav7.dracr[VAR_0], 8, 3);

            uint32_t xn = extract32(env->pmsav7.dracr[VAR_0], 12, 1);



            if (m_is_system_region(env, address)) {

                

                xn = 1;




            if (is_user) { 

                switch (ap) {

                case 0:

                case 1:

                case 5:

                    break; 

                case 3:

                    *prot |= PAGE_WRITE;


                case 2:

                case 6:










                default:

                    qemu_log_mask(LOG_GUEST_ERROR,

                                  "DRACR[%d]: Bad value for AP bits: 0x%"

                                  PRIx32 "\VAR_0", VAR_0, ap);


            } else { 

                switch (ap) {

                case 0:

                    break; 

                case 1:

                case 2:

                case 3:

                    *prot |= PAGE_WRITE;


                case 5:

                case 6:










                default:

                    qemu_log_mask(LOG_GUEST_ERROR,

                                  "DRACR[%d]: Bad value for AP bits: 0x%"

                                  PRIx32 "\VAR_0", VAR_0, ap);





            

            if (xn) {

                *prot &= ~PAGE_EXEC;






    fi->type = ARMFault_Permission;

    fi->level = 1;

    return !(*prot & (1 << access_type));

static bool FUNC_0(CPUARMState *env, uint32_t address,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
hwaddr *phys_ptr, int *prot,
ARMMMUFaultInfo *fi)
{ ARMCPU *cpu = arm_env_get_cpu(env); int VAR_0; bool is_user = regime_is_user(env, mmu_idx); *phys_ptr = address; *prot = 0; if (regime_translation_disabled(env, mmu_idx) ||
m_is_ppb_region(env, address)) { get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); } else { for (VAR_0 = (int)cpu->pmsav7_dregion - 1; VAR_0 >= 0; VAR_0--) { uint32_t base = env->pmsav7.drbar[VAR_0]; uint32_t rsize = extract32(env->pmsav7.drsr[VAR_0], 1, 5); uint32_t rmask; bool srdis = false; if (!(env->pmsav7.drsr[VAR_0] & 0x1)) { continue; if (!rsize) { qemu_log_mask(LOG_GUEST_ERROR,
"DRSR[%d]: Rsize field cannot be 0\VAR_0", VAR_0); continue; rsize++; rmask = (1ull << rsize) - 1; if (base & rmask) { qemu_log_mask(LOG_GUEST_ERROR,
"DRBAR[%d]: 0x%" PRIx32 " misaligned "
"to DRSR region size, mask = 0x%" PRIx32 "\VAR_0",
VAR_0, base, rmask); continue; if (address < base || address > base + rmask) { continue; if (rsize >= 8) { int VAR_1, VAR_2; uint32_t srdis_mask; rsize -= 3; VAR_2 = ((address - base) >> rsize) & 0x7; srdis = extract32(env->pmsav7.drsr[VAR_0], VAR_2 + 8, 1); srdis_mask = srdis ? 0x3 : 0x0; for (VAR_1 = 2; VAR_1 <= 8 && rsize < TARGET_PAGE_BITS; VAR_1 *= 2) { int snd_rounded = VAR_2 & ~(VAR_1 - 1); uint32_t srdis_multi = extract32(env->pmsav7.drsr[VAR_0],
snd_rounded + 8, VAR_1); if (srdis_mask ^ srdis_multi) { srdis_mask = (srdis_mask << VAR_1) | srdis_mask; rsize++; if (rsize < TARGET_PAGE_BITS) { qemu_log_mask(LOG_UNIMP,
"DRSR[%d]: No support for MPU (sub)region "
"alignment of %" PRIu32 " bits. Minimum is %d\VAR_0",
VAR_0, rsize, TARGET_PAGE_BITS); continue; if (srdis) { continue; if (VAR_0 == -1) { if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) { fi->type = ARMFault_Background; return true; get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); } else { uint32_t ap = extract32(env->pmsav7.dracr[VAR_0], 8, 3); uint32_t xn = extract32(env->pmsav7.dracr[VAR_0], 12, 1); if (m_is_system_region(env, address)) { xn = 1; if (is_user) { switch (ap) { case 0:
case 1:
case 5:
break; case 3:
*prot |= PAGE_WRITE; case 2:
case 6:
default:
qemu_log_mask(LOG_GUEST_ERROR,
"DRACR[%d]: Bad value for AP bits: 0x%"
PRIx32 "\VAR_0", VAR_0, ap); } else { switch (ap) { case 0:
break; case 1:
case 2:
case 3:
*prot |= PAGE_WRITE; case 5:
case 6:
default:
qemu_log_mask(LOG_GUEST_ERROR,
"DRACR[%d]: Bad value for AP bits: 0x%"
PRIx32 "\VAR_0", VAR_0, ap); if (xn) { *prot &= ~PAGE_EXEC; fi->type = ARMFault_Permission; fi->level = 1; return !(*prot & (1 << access_type));