Commit c449d8ba authored by KONRAD Frederic's avatar KONRAD Frederic Committed by David Gibson
Browse files

booke206: fix tlbnps for fixed size TLB



Some OS don't populate the TSIZE field when using a fixed size TLB which result
in a 1KB TLB. When the TLB is a fixed size TLB the TSIZE field should be
ignored.

Fix this wrong behavior with MAV 2.0.

Signed-off-by: default avatarKONRAD Frederic <frederic.konrad@adacore.com>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 3f330293
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -2491,6 +2491,28 @@ static inline uint32_t booke206_tlbnps(CPUPPCState *env, const int tlbn)
    return ret;
}

static inline void booke206_fixed_size_tlbn(CPUPPCState *env, const int tlbn,
                                            ppcmas_tlb_t *tlb)
{
    uint8_t i;
    int32_t tsize = -1;

    for (i = 0; i < 32; i++) {
        if ((env->spr[SPR_BOOKE_TLB0PS + tlbn]) & (1ULL << i)) {
            if (tsize == -1) {
                tsize = i;
            } else {
                return;
            }
        }
    }

    /* TLBnPS unimplemented? Odd.. */
    assert(tsize != -1);
    tlb->mas1 &= ~MAS1_TSIZE_MASK;
    tlb->mas1 |= ((uint32_t)tsize) << MAS1_TSIZE_SHIFT;
}

#endif

static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr)
+10 −6
Original line number Diff line number Diff line
@@ -2632,13 +2632,17 @@ void helper_booke206_tlbwe(CPUPPCState *env)
        env->spr[SPR_BOOKE_MAS3];
    tlb->mas1 = env->spr[SPR_BOOKE_MAS1];

    /* MAV 1.0 only */
    if ((env->spr[SPR_MMUCFG] & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
        /* For TLB which has a fixed size TSIZE is ignored with MAV2 */
        booke206_fixed_size_tlbn(env, tlbn, tlb);
    } else {
        if (!(tlbncfg & TLBnCFG_AVAIL)) {
            /* force !AVAIL TLB entries to correct page size */
            tlb->mas1 &= ~MAS1_TSIZE_MASK;
            /* XXX can be configured in MMUCSR0 */
            tlb->mas1 |= (tlbncfg & TLBnCFG_MINSIZE) >> 12;
        }
    }

    /* Make a mask from TLB size to discard invalid bits in EPN field */
    mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);