tlb.cc revision 12808
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2001-2005 The Regents of The University of Michigan 311308Santhony.gutierrez@amd.com * Copyright (c) 2007 MIPS Technologies, Inc. 411308Santhony.gutierrez@amd.com * All rights reserved. 511308Santhony.gutierrez@amd.com * 611308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 711308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are 811308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright 911308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer; 1011308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright 1111308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the 1211308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution; 1311308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its 1411308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from 1511308Santhony.gutierrez@amd.com * this software without specific prior written permission. 1611308Santhony.gutierrez@amd.com * 1711308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1811308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1911308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2011308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2111308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2211308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2311308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2411308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2511308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2611308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2711308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2811308Santhony.gutierrez@amd.com * 2911308Santhony.gutierrez@amd.com * Authors: Nathan Binkert 3011308Santhony.gutierrez@amd.com * Steve Reinhardt 3111308Santhony.gutierrez@amd.com * Jaidev Patwardhan 3211308Santhony.gutierrez@amd.com * Zhengxing Li 3311308Santhony.gutierrez@amd.com * Deyuan Guo 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#include "arch/riscv/tlb.hh" 3711308Santhony.gutierrez@amd.com 3811308Santhony.gutierrez@amd.com#include <string> 3911308Santhony.gutierrez@amd.com#include <vector> 4011308Santhony.gutierrez@amd.com 4111308Santhony.gutierrez@amd.com#include "arch/riscv/faults.hh" 4211308Santhony.gutierrez@amd.com#include "arch/riscv/pagetable.hh" 4311308Santhony.gutierrez@amd.com#include "arch/riscv/pra_constants.hh" 4411308Santhony.gutierrez@amd.com#include "arch/riscv/system.hh" 4511308Santhony.gutierrez@amd.com#include "arch/riscv/utility.hh" 4611308Santhony.gutierrez@amd.com#include "base/inifile.hh" 4711308Santhony.gutierrez@amd.com#include "base/str.hh" 4811308Santhony.gutierrez@amd.com#include "base/trace.hh" 4911308Santhony.gutierrez@amd.com#include "cpu/thread_context.hh" 5011308Santhony.gutierrez@amd.com#include "debug/RiscvTLB.hh" 5111308Santhony.gutierrez@amd.com#include "debug/TLB.hh" 5211308Santhony.gutierrez@amd.com#include "mem/page_table.hh" 5311308Santhony.gutierrez@amd.com#include "params/RiscvTLB.hh" 5411308Santhony.gutierrez@amd.com#include "sim/full_system.hh" 5511308Santhony.gutierrez@amd.com#include "sim/process.hh" 5611308Santhony.gutierrez@amd.com 5711308Santhony.gutierrez@amd.comusing namespace std; 5811308Santhony.gutierrez@amd.comusing namespace RiscvISA; 5911308Santhony.gutierrez@amd.com 6011308Santhony.gutierrez@amd.com/////////////////////////////////////////////////////////////////////// 6111308Santhony.gutierrez@amd.com// 6211308Santhony.gutierrez@amd.com// RISC-V TLB 6311308Santhony.gutierrez@amd.com// 6411308Santhony.gutierrez@amd.com 6511308Santhony.gutierrez@amd.comTLB::TLB(const Params *p) 6611308Santhony.gutierrez@amd.com : BaseTLB(p), size(p->size), nlu(0) 6711308Santhony.gutierrez@amd.com{ 6811308Santhony.gutierrez@amd.com table = new PTE[size]; 6911308Santhony.gutierrez@amd.com memset(table, 0, sizeof(PTE[size])); 7011308Santhony.gutierrez@amd.com smallPages = 0; 7111308Santhony.gutierrez@amd.com} 7211308Santhony.gutierrez@amd.com 7311308Santhony.gutierrez@amd.comTLB::~TLB() 7411308Santhony.gutierrez@amd.com{ 7511308Santhony.gutierrez@amd.com if (table) 7611308Santhony.gutierrez@amd.com delete [] table; 7711308Santhony.gutierrez@amd.com} 7811308Santhony.gutierrez@amd.com 7911308Santhony.gutierrez@amd.com// look up an entry in the TLB 8011308Santhony.gutierrez@amd.comRiscvISA::PTE * 8111308Santhony.gutierrez@amd.comTLB::lookup(Addr vpn, uint8_t asn) const 8211308Santhony.gutierrez@amd.com{ 8311308Santhony.gutierrez@amd.com // assume not found... 8411308Santhony.gutierrez@amd.com PTE *retval = nullptr; 8511308Santhony.gutierrez@amd.com PageTable::const_iterator i = lookupTable.find(vpn); 8611308Santhony.gutierrez@amd.com if (i != lookupTable.end()) { 8711308Santhony.gutierrez@amd.com while (i->first == vpn) { 8811308Santhony.gutierrez@amd.com int index = i->second; 8911308Santhony.gutierrez@amd.com PTE *pte = &table[index]; 9011308Santhony.gutierrez@amd.com 9111308Santhony.gutierrez@amd.com /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 9211308Santhony.gutierrez@amd.com Addr Mask = pte->Mask; 9311308Santhony.gutierrez@amd.com Addr InvMask = ~Mask; 9411308Santhony.gutierrez@amd.com Addr VPN = pte->VPN; 9511308Santhony.gutierrez@amd.com if (((vpn & InvMask) == (VPN & InvMask)) && 9611308Santhony.gutierrez@amd.com (pte->G || (asn == pte->asid))) { 9711308Santhony.gutierrez@amd.com // We have a VPN + ASID Match 9811308Santhony.gutierrez@amd.com retval = pte; 9911308Santhony.gutierrez@amd.com break; 10011308Santhony.gutierrez@amd.com } 10111308Santhony.gutierrez@amd.com ++i; 10211308Santhony.gutierrez@amd.com } 10311308Santhony.gutierrez@amd.com } 10411308Santhony.gutierrez@amd.com 10511308Santhony.gutierrez@amd.com DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, 10611308Santhony.gutierrez@amd.com retval ? "hit" : "miss", retval ? retval->PFN1 : 0); 10711308Santhony.gutierrez@amd.com return retval; 10811308Santhony.gutierrez@amd.com} 10911308Santhony.gutierrez@amd.com 11011308Santhony.gutierrez@amd.comRiscvISA::PTE* 11111308Santhony.gutierrez@amd.comTLB::getEntry(unsigned Index) const 11211308Santhony.gutierrez@amd.com{ 11311308Santhony.gutierrez@amd.com // Make sure that Index is valid 11411308Santhony.gutierrez@amd.com assert(Index<size); 11511308Santhony.gutierrez@amd.com return &table[Index]; 11611308Santhony.gutierrez@amd.com} 11711308Santhony.gutierrez@amd.com 11811308Santhony.gutierrez@amd.comint 11911308Santhony.gutierrez@amd.comTLB::probeEntry(Addr vpn, uint8_t asn) const 12011308Santhony.gutierrez@amd.com{ 12111308Santhony.gutierrez@amd.com // assume not found... 12211308Santhony.gutierrez@amd.com int Ind = -1; 12311308Santhony.gutierrez@amd.com PageTable::const_iterator i = lookupTable.find(vpn); 12411308Santhony.gutierrez@amd.com if (i != lookupTable.end()) { 12511308Santhony.gutierrez@amd.com while (i->first == vpn) { 12611308Santhony.gutierrez@amd.com int index = i->second; 12711308Santhony.gutierrez@amd.com PTE *pte = &table[index]; 12811308Santhony.gutierrez@amd.com 12911308Santhony.gutierrez@amd.com /* 1KB TLB Lookup code - from MIPS ARM Volume III - Rev. 2.50 */ 13011308Santhony.gutierrez@amd.com Addr Mask = pte->Mask; 13111308Santhony.gutierrez@amd.com Addr InvMask = ~Mask; 13211308Santhony.gutierrez@amd.com Addr VPN = pte->VPN; 13311308Santhony.gutierrez@amd.com if (((vpn & InvMask) == (VPN & InvMask)) && 13411308Santhony.gutierrez@amd.com (pte->G || (asn == pte->asid))) { 13511308Santhony.gutierrez@amd.com // We have a VPN + ASID Match 13611308Santhony.gutierrez@amd.com Ind = index; 13711308Santhony.gutierrez@amd.com break; 13811308Santhony.gutierrez@amd.com } 13911308Santhony.gutierrez@amd.com ++i; 14011308Santhony.gutierrez@amd.com } 14111308Santhony.gutierrez@amd.com } 14211308Santhony.gutierrez@amd.com DPRINTF(RiscvTLB,"VPN: %x, asid: %d, Result of TLBP: %d\n",vpn,asn,Ind); 14311308Santhony.gutierrez@amd.com return Ind; 14411308Santhony.gutierrez@amd.com} 14511308Santhony.gutierrez@amd.com 14611308Santhony.gutierrez@amd.cominline Fault 14711308Santhony.gutierrez@amd.comTLB::checkCacheability(const RequestPtr &req) 14811308Santhony.gutierrez@amd.com{ 14911308Santhony.gutierrez@amd.com Addr VAddrUncacheable = 0xA0000000; 15011308Santhony.gutierrez@amd.com // In MIPS, cacheability is controlled by certain bits of the virtual 15111308Santhony.gutierrez@amd.com // address or by the TLB entry 15211308Santhony.gutierrez@amd.com if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { 15311308Santhony.gutierrez@amd.com // mark request as uncacheable 15411308Santhony.gutierrez@amd.com req->setFlags(Request::UNCACHEABLE | Request::STRICT_ORDER); 15511308Santhony.gutierrez@amd.com } 15611308Santhony.gutierrez@amd.com return NoFault; 15711308Santhony.gutierrez@amd.com} 15811308Santhony.gutierrez@amd.com 15911308Santhony.gutierrez@amd.comvoid 16011308Santhony.gutierrez@amd.comTLB::insertAt(PTE &pte, unsigned Index, int _smallPages) 16111308Santhony.gutierrez@amd.com{ 16211308Santhony.gutierrez@amd.com smallPages = _smallPages; 16311308Santhony.gutierrez@amd.com if (Index > size) { 16411308Santhony.gutierrez@amd.com warn("Attempted to write at index (%d) beyond TLB size (%d)", 16511308Santhony.gutierrez@amd.com Index, size); 16611308Santhony.gutierrez@amd.com } else { 16711308Santhony.gutierrez@amd.com // Update TLB 16811308Santhony.gutierrez@amd.com DPRINTF(TLB, "TLB[%d]: %x %x %x %x\n", 16911308Santhony.gutierrez@amd.com Index, pte.Mask << 11, 17011308Santhony.gutierrez@amd.com ((pte.VPN << 11) | pte.asid), 17111308Santhony.gutierrez@amd.com ((pte.PFN0 << 6) | (pte.C0 << 3) | 17211308Santhony.gutierrez@amd.com (pte.D0 << 2) | (pte.V0 <<1) | pte.G), 17311308Santhony.gutierrez@amd.com ((pte.PFN1 <<6) | (pte.C1 << 3) | 17411308Santhony.gutierrez@amd.com (pte.D1 << 2) | (pte.V1 <<1) | pte.G)); 17511308Santhony.gutierrez@amd.com if (table[Index].V0 || table[Index].V1) { 17611308Santhony.gutierrez@amd.com // Previous entry is valid 17711308Santhony.gutierrez@amd.com PageTable::iterator i = lookupTable.find(table[Index].VPN); 17811308Santhony.gutierrez@amd.com lookupTable.erase(i); 17911308Santhony.gutierrez@amd.com } 18011308Santhony.gutierrez@amd.com table[Index]=pte; 18111308Santhony.gutierrez@amd.com // Update fast lookup table 18211308Santhony.gutierrez@amd.com lookupTable.insert(make_pair(table[Index].VPN, Index)); 18311308Santhony.gutierrez@amd.com } 18411308Santhony.gutierrez@amd.com} 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.com// insert a new TLB entry 18711308Santhony.gutierrez@amd.comvoid 18811308Santhony.gutierrez@amd.comTLB::insert(Addr addr, PTE &pte) 18911308Santhony.gutierrez@amd.com{ 19011308Santhony.gutierrez@amd.com fatal("TLB Insert not yet implemented\n"); 19111308Santhony.gutierrez@amd.com} 19211308Santhony.gutierrez@amd.com 19311308Santhony.gutierrez@amd.comvoid 19411308Santhony.gutierrez@amd.comTLB::flushAll() 19511308Santhony.gutierrez@amd.com{ 19611308Santhony.gutierrez@amd.com DPRINTF(TLB, "flushAll\n"); 19711308Santhony.gutierrez@amd.com memset(table, 0, sizeof(PTE[size])); 19811308Santhony.gutierrez@amd.com lookupTable.clear(); 19911308Santhony.gutierrez@amd.com nlu = 0; 20011308Santhony.gutierrez@amd.com} 20111308Santhony.gutierrez@amd.com 20211308Santhony.gutierrez@amd.comvoid 20311308Santhony.gutierrez@amd.comTLB::serialize(CheckpointOut &cp) const 20411308Santhony.gutierrez@amd.com{ 20511308Santhony.gutierrez@amd.com SERIALIZE_SCALAR(size); 20611308Santhony.gutierrez@amd.com SERIALIZE_SCALAR(nlu); 20711308Santhony.gutierrez@amd.com 20811308Santhony.gutierrez@amd.com for (int i = 0; i < size; i++) { 20911308Santhony.gutierrez@amd.com ScopedCheckpointSection sec(cp, csprintf("PTE%d", i)); 21011308Santhony.gutierrez@amd.com table[i].serialize(cp); 21111308Santhony.gutierrez@amd.com } 21211308Santhony.gutierrez@amd.com} 21311308Santhony.gutierrez@amd.com 21411308Santhony.gutierrez@amd.comvoid 21511308Santhony.gutierrez@amd.comTLB::unserialize(CheckpointIn &cp) 21611308Santhony.gutierrez@amd.com{ 21711308Santhony.gutierrez@amd.com UNSERIALIZE_SCALAR(size); 21811308Santhony.gutierrez@amd.com UNSERIALIZE_SCALAR(nlu); 21911308Santhony.gutierrez@amd.com 22011308Santhony.gutierrez@amd.com for (int i = 0; i < size; i++) { 22111308Santhony.gutierrez@amd.com ScopedCheckpointSection sec(cp, csprintf("PTE%d", i)); 22211308Santhony.gutierrez@amd.com table[i].unserialize(cp); 22311308Santhony.gutierrez@amd.com if (table[i].V0 || table[i].V1) { 22411308Santhony.gutierrez@amd.com lookupTable.insert(make_pair(table[i].VPN, i)); 22511308Santhony.gutierrez@amd.com } 22611308Santhony.gutierrez@amd.com } 22711308Santhony.gutierrez@amd.com} 22811308Santhony.gutierrez@amd.com 22911308Santhony.gutierrez@amd.comvoid 23011308Santhony.gutierrez@amd.comTLB::regStats() 23111308Santhony.gutierrez@amd.com{ 23211308Santhony.gutierrez@amd.com BaseTLB::regStats(); 23311308Santhony.gutierrez@amd.com 23411308Santhony.gutierrez@amd.com read_hits 23511308Santhony.gutierrez@amd.com .name(name() + ".read_hits") 23611308Santhony.gutierrez@amd.com .desc("DTB read hits") 23711308Santhony.gutierrez@amd.com ; 23811534Sjohn.kalamatianos@amd.com 23911308Santhony.gutierrez@amd.com read_misses 24011308Santhony.gutierrez@amd.com .name(name() + ".read_misses") 24111308Santhony.gutierrez@amd.com .desc("DTB read misses") 24211308Santhony.gutierrez@amd.com ; 24311308Santhony.gutierrez@amd.com 24411308Santhony.gutierrez@amd.com 24511308Santhony.gutierrez@amd.com read_accesses 24611308Santhony.gutierrez@amd.com .name(name() + ".read_accesses") 24711308Santhony.gutierrez@amd.com .desc("DTB read accesses") 24811308Santhony.gutierrez@amd.com ; 24911308Santhony.gutierrez@amd.com 25011308Santhony.gutierrez@amd.com write_hits 25111308Santhony.gutierrez@amd.com .name(name() + ".write_hits") 25211308Santhony.gutierrez@amd.com .desc("DTB write hits") 25311308Santhony.gutierrez@amd.com ; 25411308Santhony.gutierrez@amd.com 25511308Santhony.gutierrez@amd.com write_misses 25611308Santhony.gutierrez@amd.com .name(name() + ".write_misses") 25711308Santhony.gutierrez@amd.com .desc("DTB write misses") 25811308Santhony.gutierrez@amd.com ; 25911534Sjohn.kalamatianos@amd.com 26011308Santhony.gutierrez@amd.com 26111308Santhony.gutierrez@amd.com write_accesses 26211308Santhony.gutierrez@amd.com .name(name() + ".write_accesses") 26311308Santhony.gutierrez@amd.com .desc("DTB write accesses") 26411308Santhony.gutierrez@amd.com ; 26511308Santhony.gutierrez@amd.com 26611308Santhony.gutierrez@amd.com hits 26711308Santhony.gutierrez@amd.com .name(name() + ".hits") 26811308Santhony.gutierrez@amd.com .desc("DTB hits") 26911308Santhony.gutierrez@amd.com ; 27011308Santhony.gutierrez@amd.com 27111308Santhony.gutierrez@amd.com misses 27211308Santhony.gutierrez@amd.com .name(name() + ".misses") 27311308Santhony.gutierrez@amd.com .desc("DTB misses") 27411308Santhony.gutierrez@amd.com ; 27511308Santhony.gutierrez@amd.com 27611308Santhony.gutierrez@amd.com accesses 27711308Santhony.gutierrez@amd.com .name(name() + ".accesses") 27811308Santhony.gutierrez@amd.com .desc("DTB accesses") 27911308Santhony.gutierrez@amd.com ; 28011534Sjohn.kalamatianos@amd.com 28111308Santhony.gutierrez@amd.com hits = read_hits + write_hits; 28211308Santhony.gutierrez@amd.com misses = read_misses + write_misses; 28311308Santhony.gutierrez@amd.com accesses = read_accesses + write_accesses; 28411308Santhony.gutierrez@amd.com} 28511308Santhony.gutierrez@amd.com 28611308Santhony.gutierrez@amd.comFault 28711308Santhony.gutierrez@amd.comTLB::translateInst(const RequestPtr &req, ThreadContext *tc) 28811308Santhony.gutierrez@amd.com{ 28911308Santhony.gutierrez@amd.com if (FullSystem) { 29011308Santhony.gutierrez@amd.com /** 29111308Santhony.gutierrez@amd.com * check if we simulate a bare metal system 29211308Santhony.gutierrez@amd.com * if so, we have no tlb, phys addr == virt addr 29311308Santhony.gutierrez@amd.com */ 29411308Santhony.gutierrez@amd.com if (static_cast<RiscvSystem *>(tc->getSystemPtr())->isBareMetal()) 29511308Santhony.gutierrez@amd.com req->setFlags(Request::PHYSICAL); 29611308Santhony.gutierrez@amd.com 29711308Santhony.gutierrez@amd.com if (req->getFlags() & Request::PHYSICAL) { 29811308Santhony.gutierrez@amd.com /** 29911308Santhony.gutierrez@amd.com * we simply set the virtual address to physical address 30011308Santhony.gutierrez@amd.com */ 30111308Santhony.gutierrez@amd.com req->setPaddr(req->getVaddr()); 30211308Santhony.gutierrez@amd.com return checkCacheability(req); 30311308Santhony.gutierrez@amd.com } else { 30411308Santhony.gutierrez@amd.com /** 30511308Santhony.gutierrez@amd.com * as we currently support bare metal only, we throw a panic, 30611308Santhony.gutierrez@amd.com * if it is not a bare metal system 30711308Santhony.gutierrez@amd.com */ 30811308Santhony.gutierrez@amd.com panic("translateInst not implemented in RISC-V.\n"); 30911308Santhony.gutierrez@amd.com } 31011308Santhony.gutierrez@amd.com } else { 31111308Santhony.gutierrez@amd.com Process * p = tc->getProcessPtr(); 31211308Santhony.gutierrez@amd.com 31311308Santhony.gutierrez@amd.com Fault fault = p->pTable->translate(req); 31411308Santhony.gutierrez@amd.com if (fault != NoFault) 31511534Sjohn.kalamatianos@amd.com return fault; 31611308Santhony.gutierrez@amd.com 31711308Santhony.gutierrez@amd.com return NoFault; 31811308Santhony.gutierrez@amd.com } 31911308Santhony.gutierrez@amd.com} 32011308Santhony.gutierrez@amd.com 32111308Santhony.gutierrez@amd.comFault 32211308Santhony.gutierrez@amd.comTLB::translateData(const RequestPtr &req, ThreadContext *tc, bool write) 32311308Santhony.gutierrez@amd.com{ 32411308Santhony.gutierrez@amd.com if (FullSystem) { 32511308Santhony.gutierrez@amd.com /** 32611308Santhony.gutierrez@amd.com * check if we simulate a bare metal system 32711308Santhony.gutierrez@amd.com * if so, we have no tlb, phys addr == virt addr 32811308Santhony.gutierrez@amd.com */ 32911308Santhony.gutierrez@amd.com if (static_cast<RiscvSystem *>(tc->getSystemPtr())->isBareMetal()) 33011308Santhony.gutierrez@amd.com req->setFlags(Request::PHYSICAL); 33111308Santhony.gutierrez@amd.com 33211308Santhony.gutierrez@amd.com if (req->getFlags() & Request::PHYSICAL) { 33311308Santhony.gutierrez@amd.com /** 33411308Santhony.gutierrez@amd.com * we simply set the virtual address to physical address 33511308Santhony.gutierrez@amd.com */ 33611308Santhony.gutierrez@amd.com req->setPaddr(req->getVaddr()); 33711308Santhony.gutierrez@amd.com return checkCacheability(req); 33811308Santhony.gutierrez@amd.com } else { 33911308Santhony.gutierrez@amd.com /** 34011308Santhony.gutierrez@amd.com * as we currently support bare metal only, we throw a panic, 34111308Santhony.gutierrez@amd.com * if it is not a bare metal system 34211308Santhony.gutierrez@amd.com */ 34311308Santhony.gutierrez@amd.com panic("translateData not implemented in RISC-V.\n"); 34411308Santhony.gutierrez@amd.com } 34511308Santhony.gutierrez@amd.com } else { 34611308Santhony.gutierrez@amd.com // In the O3 CPU model, sometimes a memory access will be speculatively 34711308Santhony.gutierrez@amd.com // executed along a branch that will end up not being taken where the 34811308Santhony.gutierrez@amd.com // address is invalid. In that case, return a fault rather than trying 34911534Sjohn.kalamatianos@amd.com // to translate it (which will cause a panic). Since RISC-V allows 35011308Santhony.gutierrez@amd.com // unaligned memory accesses, this should only happen if the request's 35111308Santhony.gutierrez@amd.com // length is long enough to wrap around from the end of the memory to 35211308Santhony.gutierrez@amd.com // the start. 35311308Santhony.gutierrez@amd.com assert(req->getSize() > 0); 35411308Santhony.gutierrez@amd.com if (req->getVaddr() + req->getSize() - 1 < req->getVaddr()) 35511308Santhony.gutierrez@amd.com return make_shared<GenericPageTableFault>(req->getVaddr()); 35611308Santhony.gutierrez@amd.com 35711308Santhony.gutierrez@amd.com Process * p = tc->getProcessPtr(); 35811308Santhony.gutierrez@amd.com 35911308Santhony.gutierrez@amd.com Fault fault = p->pTable->translate(req); 36011308Santhony.gutierrez@amd.com if (fault != NoFault) 36111308Santhony.gutierrez@amd.com return fault; 36211308Santhony.gutierrez@amd.com 36311308Santhony.gutierrez@amd.com return NoFault; 36411308Santhony.gutierrez@amd.com } 36511308Santhony.gutierrez@amd.com} 36611308Santhony.gutierrez@amd.com 36711308Santhony.gutierrez@amd.comFault 36811308Santhony.gutierrez@amd.comTLB::translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode) 36911308Santhony.gutierrez@amd.com{ 37011308Santhony.gutierrez@amd.com if (mode == Execute) 37111308Santhony.gutierrez@amd.com return translateInst(req, tc); 37211308Santhony.gutierrez@amd.com else 37311308Santhony.gutierrez@amd.com return translateData(req, tc, mode == Write); 37411308Santhony.gutierrez@amd.com} 37511534Sjohn.kalamatianos@amd.com 37611308Santhony.gutierrez@amd.comvoid 37711308Santhony.gutierrez@amd.comTLB::translateTiming(const RequestPtr &req, ThreadContext *tc, 37811308Santhony.gutierrez@amd.com Translation *translation, Mode mode) 37911308Santhony.gutierrez@amd.com{ 38011308Santhony.gutierrez@amd.com assert(translation); 38111308Santhony.gutierrez@amd.com translation->finish(translateAtomic(req, tc, mode), req, tc, mode); 38211308Santhony.gutierrez@amd.com} 38311308Santhony.gutierrez@amd.com 38411308Santhony.gutierrez@amd.comFault 38511308Santhony.gutierrez@amd.comTLB::finalizePhysical(const RequestPtr &req, 38611308Santhony.gutierrez@amd.com ThreadContext *tc, Mode mode) const 38711308Santhony.gutierrez@amd.com{ 38811308Santhony.gutierrez@amd.com return NoFault; 38911308Santhony.gutierrez@amd.com} 39011308Santhony.gutierrez@amd.com 39111308Santhony.gutierrez@amd.com 39211308Santhony.gutierrez@amd.comRiscvISA::PTE & 39311308Santhony.gutierrez@amd.comTLB::index(bool advance) 39411308Santhony.gutierrez@amd.com{ 39511308Santhony.gutierrez@amd.com PTE *pte = &table[nlu]; 39611308Santhony.gutierrez@amd.com 39711308Santhony.gutierrez@amd.com if (advance) 39811308Santhony.gutierrez@amd.com nextnlu(); 39911308Santhony.gutierrez@amd.com 40011308Santhony.gutierrez@amd.com return *pte; 40111308Santhony.gutierrez@amd.com} 40211308Santhony.gutierrez@amd.com 40311308Santhony.gutierrez@amd.comRiscvISA::TLB * 40411534Sjohn.kalamatianos@amd.comRiscvTLBParams::create() 40511308Santhony.gutierrez@amd.com{ 40611308Santhony.gutierrez@amd.com return new TLB(this); 40711308Santhony.gutierrez@amd.com} 40811308Santhony.gutierrez@amd.com