static void update_dtlb(unsigned long address, pte_t pte) { u32 tlbehi; u32 mmucr; tlbehi = sysreg_read(TLBEHI); tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); tlbehi |= address & MMU_VPN_MASK; tlbehi |= SYSREG_BIT(TLBEHI_V); sysreg_write(TLBEHI, tlbehi); __builtin_tlbs(); mmucr = sysreg_read(MMUCR); if (mmucr & SYSREG_BIT(MMUCR_N)) { unsigned int rp; u32 tlbar = sysreg_read(TLBARLO); rp = 32 - fls(tlbar); if (rp == 32) { rp = 0; sysreg_write(TLBARLO, -1L); } mmucr = SYSREG_BFINS(DRP, rp, mmucr); sysreg_write(MMUCR, mmucr); } sysreg_write(TLBELO, pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK); __builtin_tlbw(); }
static void update_dtlb(unsigned long address, pte_t pte) { u32 tlbehi; u32 mmucr; /* * We're not changing the ASID here, so no need to flush the * pipeline. */ tlbehi = sysreg_read(TLBEHI); tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); tlbehi |= address & MMU_VPN_MASK; tlbehi |= SYSREG_BIT(TLBEHI_V); sysreg_write(TLBEHI, tlbehi); /* Does this mapping already exist? */ __builtin_tlbs(); mmucr = sysreg_read(MMUCR); if (mmucr & SYSREG_BIT(MMUCR_N)) { /* Not found -- pick a not-recently-accessed entry */ unsigned int rp; u32 tlbar = sysreg_read(TLBARLO); rp = 32 - fls(tlbar); if (rp == 32) { rp = 0; sysreg_write(TLBARLO, -1L); } mmucr = SYSREG_BFINS(DRP, rp, mmucr); sysreg_write(MMUCR, mmucr); } sysreg_write(TLBELO, pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK); /* Let's go */ __builtin_tlbw(); }