Commit 337a03f0 authored by Richard Henderson's avatar Richard Henderson Committed by Peter Maydell
Browse files

target/arm: Cache the Tagged bit for a page in MemTxAttrs



This "bit" is a particular value of the page's MemAttr.

Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20200626033144.790098-43-richard.henderson@linaro.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 7e98e21c
Loading
Loading
Loading
Loading
+45 −3
Original line number Diff line number Diff line
@@ -11834,9 +11834,19 @@ static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
 */
static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
{
    uint8_t s1lo = extract32(s1.attrs, 0, 4), s2lo = extract32(s2.attrs, 0, 4);
    uint8_t s1hi = extract32(s1.attrs, 4, 4), s2hi = extract32(s2.attrs, 4, 4);
    uint8_t s1lo, s2lo, s1hi, s2hi;
    ARMCacheAttrs ret;
    bool tagged = false;

    if (s1.attrs == 0xf0) {
        tagged = true;
        s1.attrs = 0xff;
    }

    s1lo = extract32(s1.attrs, 0, 4);
    s2lo = extract32(s2.attrs, 0, 4);
    s1hi = extract32(s1.attrs, 4, 4);
    s2hi = extract32(s2.attrs, 4, 4);

    /* Combine shareability attributes (table D4-43) */
    if (s1.shareability == 2 || s2.shareability == 2) {
@@ -11884,6 +11894,11 @@ static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
        }
    }

    /* TODO: CombineS1S2Desc does not consider transient, only WB, RWA. */
    if (tagged && ret.attrs == 0xff) {
        ret.attrs = 0xf0;
    }

    return ret;
}

@@ -11963,8 +11978,11 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
                 *  Normal Non-Shareable,
                 *  Inner Write-Back Read-Allocate Write-Allocate,
                 *  Outer Write-Back Read-Allocate Write-Allocate.
                 * Do not overwrite Tagged within attrs.
                 */
                if (cacheattrs->attrs != 0xf0) {
                    cacheattrs->attrs = 0xff;
                }
                cacheattrs->shareability = 0;
            }
            *cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
@@ -12029,6 +12047,9 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
    /* Definitely a real MMU, not an MPU */

    if (regime_translation_disabled(env, mmu_idx)) {
        uint64_t hcr;
        uint8_t memattr;

        /*
         * MMU disabled.  S1 addresses within aa64 translation regimes are
         * still checked for bounds -- see AArch64.TranslateAddressS1Off.
@@ -12066,6 +12087,27 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
        *phys_ptr = address;
        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
        *page_size = TARGET_PAGE_SIZE;

        /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
        hcr = arm_hcr_el2_eff(env);
        cacheattrs->shareability = 0;
        if (hcr & HCR_DC) {
            if (hcr & HCR_DCT) {
                memattr = 0xf0;  /* Tagged, Normal, WB, RWA */
            } else {
                memattr = 0xff;  /* Normal, WB, RWA */
            }
        } else if (access_type == MMU_INST_FETCH) {
            if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
                memattr = 0xee;  /* Normal, WT, RA, NT */
            } else {
                memattr = 0x44;  /* Normal, NC, No */
            }
            cacheattrs->shareability = 2; /* outer sharable */
        } else {
            memattr = 0x00;      /* Device, nGnRnE */
        }
        cacheattrs->attrs = memattr;
        return 0;
    }

+5 −0
Original line number Diff line number Diff line
@@ -188,6 +188,11 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
            phys_addr &= TARGET_PAGE_MASK;
            address &= TARGET_PAGE_MASK;
        }
        /* Notice and record tagged memory. */
        if (cpu_isar_feature(aa64_mte, cpu) && cacheattrs.attrs == 0xf0) {
            arm_tlb_mte_tagged(&attrs) = true;
        }

        tlb_set_page_with_attrs(cs, address, phys_addr, attrs,
                                prot, mmu_idx, page_size);
        return true;