Go to the documentation of this file.
42 #include "debug/IPR.hh"
43 #include "debug/TLB.hh"
56 :
BaseTLB(
p), size(
p->size), usedEntries(0), lastReplaced(0),
57 cacheState(0), cacheValid(false)
61 fatal(
"SPARC T1 TLB registers don't support more than 64 TLB entries");
88 if (!
t->pte.locked()) {
108 "TLB: Inserting Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n",
109 va, PTE.
paddr(), partition_id, context_id, (
int)real, entry);
113 if (
tlb[
x].range.real == real &&
121 DPRINTF(
TLB,
"TLB: Conflicting entry %#X , deleting it\n",
x);
134 assert(entry < size && entry >= 0);
135 new_entry = &
tlb[entry];
146 goto insertAllLocked;
147 }
while (
tlb[
x].pte.locked());
162 if (new_entry->
valid)
172 new_entry->
pte = PTE;
173 new_entry->
used =
true;;
174 new_entry->
valid =
true;
184 new_entry->
used =
true;
198 DPRINTF(
TLB,
"TLB: Looking up entry va=%#x pid=%d cid=%d r=%d\n",
199 va, partition_id, context_id, real);
216 DPRINTF(
TLB,
"TLB: Valid entry found pa: %#x size: %#x\n",
t->pte.paddr(),
221 if (!
t->used && update_used) {
238 for (
int x = 0;
x <
size;
x++) {
240 DPRINTFN(
"%4d: %#2x:%#2x %c %#4x %#8x %#8x %#16x\n",
254 DPRINTF(IPR,
"TLB: Demapping Page va=%#x pid=%#d cid=%d r=%d\n",
255 va, partition_id, context_id, real);
269 DPRINTF(IPR,
"TLB: Demapped page\n");
270 i->second->valid =
false;
271 if (
i->second->used) {
272 i->second->used =
false;
283 DPRINTF(IPR,
"TLB: Demapping Context pid=%#d cid=%d\n",
284 partition_id, context_id);
286 for (
int x = 0;
x <
size;
x++) {
287 if (
tlb[
x].range.contextId == context_id &&
305 DPRINTF(
TLB,
"TLB: Demapping All pid=%#d\n", partition_id);
307 for (
int x = 0;
x <
size;
x++) {
308 if (
tlb[
x].valid && !
tlb[
x].pte.locked() &&
327 for (
int x = 0;
x <
size;
x++) {
340 panic(
"entry: %d\n", entry);
342 assert(entry <
size);
343 if (
tlb[entry].valid)
346 return (uint64_t)-1ll;
352 assert(entry <
size);
354 if (!
tlb[entry].valid)
355 return (uint64_t)-1ll;
359 tag |= (uint64_t)
tlb[entry].range.partitionId << 61;
361 tag |= (uint64_t)~
tlb[entry].pte._size() << 56;
395 DPRINTF(
TLB,
"TLB: Writing Tag Access: va: %#X ctx: %#X value: %#X\n",
405 DPRINTF(
TLB,
"TLB: Fault: A=%#x w=%d ct=%d ft=%d asi=%d\n",
406 a, (
int)write, ct, ft, asi);
421 DPRINTF(
TLB,
"TLB: ITB Request to translate va=%#x size=%d\n",
422 vaddr, req->getSize());
441 bool addr_mask =
bits(tlbdata,3,3);
442 bool lsu_im =
bits(tlbdata,4,4);
444 int part_id =
bits(tlbdata,15,8);
445 int tl =
bits(tlbdata,18,16);
446 int pri_context =
bits(tlbdata,47,32);
452 DPRINTF(
TLB,
"TLB: priv:%d hpriv:%d red:%d lsuim:%d part_id: %#X\n",
462 context = pri_context;
476 return std::make_shared<MemAddressNotAligned>();
484 return std::make_shared<InstructionAccessException>();
495 if (
e == NULL || !
e->valid) {
498 return std::make_shared<InstructionRealTranslationMiss>();
501 return std::make_shared<FastInstructionAccessMMUMiss>();
503 return std::make_shared<FastInstructionAccessMMUMiss>(
509 if (!
priv &&
e->pte.priv()) {
512 return std::make_shared<InstructionAccessException>();
520 req->setPaddr(
e->pte.translate(
vaddr));
536 asi = (
ASI)req->getArchFlags();
537 bool implicit =
false;
541 DPRINTF(
TLB,
"TLB: DTB Request to translate va=%#x size=%d asi=%#x\n",
553 if (
hpriv && implicit) {
565 Addr ce_va =
ce->range.va;
567 ce_va < vaddr + size && ce_va + ce->range.size >
vaddr &&
568 (!write ||
ce->pte.writable())) {
569 req->setPaddr(
ce->pte.translate(
vaddr));
570 if (
ce->pte.sideffect() || (
ce->pte.paddr() >> 39) & 1) {
580 Addr ce_va =
ce->range.va;
582 ce_va < vaddr + size && ce_va + ce->range.size >
vaddr &&
583 (!write ||
ce->pte.writable())) {
584 req->setPaddr(
ce->pte.translate(
vaddr));
585 if (
ce->pte.sideffect() || (
ce->pte.paddr() >> 39) & 1) {
598 bool addr_mask =
bits(tlbdata,3,3);
599 bool lsu_dm =
bits(tlbdata,5,5);
601 int part_id =
bits(tlbdata,15,8);
602 int tl =
bits(tlbdata,18,16);
603 int pri_context =
bits(tlbdata,47,32);
604 int sec_context =
bits(tlbdata,63,48);
612 DPRINTF(
TLB,
"TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n",
623 context = pri_context;
630 return std::make_shared<PrivilegedAction>();
635 return std::make_shared<DataAccessException>();
639 context = pri_context;
642 context = sec_context;
649 context = pri_context;
653 if (!implicit && asi !=
ASI_P && asi !=
ASI_S) {
655 panic(
"Little Endian ASIs not supported\n");
658 panic(
"Partial Store ASIs not supported\n");
661 panic(
"Cmt ASI registers not implmented\n");
664 goto handleIntRegAccess;
666 goto handleMmuRegAccess;
668 goto handleScratchRegAccess;
670 goto handleQueueRegAccess;
672 goto handleSparcErrorRegAccess;
676 panic(
"Accessing ASI %#X. Should we?\n", asi);
682 return std::make_shared<MemAddressNotAligned>();
690 return std::make_shared<DataAccessException>();
705 if (
e == NULL || !
e->valid) {
707 DPRINTF(
TLB,
"TLB: DTB Failed to find matching TLB entry\n");
709 return std::make_shared<DataRealTranslationMiss>();
712 return std::make_shared<FastDataAccessMMUMiss>();
714 return std::make_shared<FastDataAccessMMUMiss>(
720 if (!
priv &&
e->pte.priv()) {
723 return std::make_shared<DataAccessException>();
726 if (write && !
e->pte.writable()) {
729 return std::make_shared<FastDataAccessProtection>();
735 return std::make_shared<DataAccessException>();
741 return std::make_shared<DataAccessException>();
744 if (
e->pte.sideffect() || (
e->pte.paddr() >> 39) & 1)
763 req->setPaddr(
e->pte.translate(
vaddr));
772 return std::make_shared<DataAccessException>();
774 return std::make_shared<PrivilegedAction>();
780 return std::make_shared<DataAccessException>();
786 handleScratchRegAccess:
789 return std::make_shared<DataAccessException>();
793 handleQueueRegAccess:
796 return std::make_shared<PrivilegedAction>();
800 return std::make_shared<DataAccessException>();
804 handleSparcErrorRegAccess:
808 return std::make_shared<DataAccessException>();
810 return std::make_shared<PrivilegedAction>();
817 DPRINTF(
TLB,
"TLB: DTB Translating local access\n");
818 req->setLocalAccessor(
824 req->setPaddr(req->getVaddr());
856 bool addr_mask =
bits(tlbdata,3,3);
857 bool data_real = !
bits(tlbdata,5,5);
858 bool inst_real = !
bits(tlbdata,4,4);
859 bool ctx_zero =
bits(tlbdata,18,16) > 0;
860 int part_id =
bits(tlbdata,15,8);
861 int pri_context =
bits(tlbdata,47,32);
864 bool real = (
mode ==
Execute) ? inst_real : data_real;
873 req->setPaddr(
vaddr);
882 return std::make_shared<InstructionAccessException>();
884 return std::make_shared<DataAccessException>();
887 tbe =
lookup(
vaddr, part_id, real, ctx_zero ? 0 : pri_context,
false);
903 for (
int x = 0;
x < 4;
x++) {
904 ttetag =
betoh(
mem.read<uint64_t>(tsbs[
x]));
905 if (ttetag.
valid() && ttetag.
va() == va_tag) {
906 uint64_t entry =
mem.read<uint64_t>(tsbs[
x]) +
sizeof(uint64_t);
909 DPRINTF(
TLB,
"Virtual(%#x)->Physical(%#x) found in TTE\n",
918 return std::make_shared<InstructionRealTranslationMiss>();
920 return std::make_shared<FastInstructionAccessMMUMiss>();
922 return std::make_shared<FastInstructionAccessMMUMiss>(
vaddr);
925 return std::make_shared<DataRealTranslationMiss>();
927 return std::make_shared<FastDataAccessMMUMiss>();
929 return std::make_shared<FastDataAccessMMUMiss>(
vaddr);
955 DPRINTF(IPR,
"Memory Mapped IPR Read: asi=%#X a=%#x\n",
956 (uint32_t)pkt->
req->getArchFlags(), pkt->
getAddr());
1030 pkt->
setBE((uint64_t)0);
1049 goto doMmuReadError;
1071 goto doMmuReadError;
1126 panic(
"need to impl DTB::doMmuRegRead() got asi=%#x, va=%#x\n",
1138 ASI asi = (
ASI)pkt->
req->getArchFlags();
1144 int entry_insert = -1;
1151 DPRINTF(IPR,
"Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n",
1152 (uint32_t)asi,
va,
data);
1170 goto doMmuWriteError;
1228 inform(
"Ignoring write to SPARC ERROR regsiter\n");
1244 goto doMmuWriteError;
1248 entry_insert =
bits(
va, 8,3);
1251 assert(entry_insert != -1 ||
mbits(
va,10,9) ==
va);
1253 va_insert =
mbits(ta_insert, 63,13);
1254 ct_insert =
mbits(ta_insert, 12,0);
1256 real_insert =
bits(
va, 9,9);
1259 itb->
insert(va_insert, part_insert, ct_insert, real_insert,
1263 entry_insert =
bits(
va, 8,3);
1266 assert(entry_insert != -1 ||
mbits(
va,10,9) ==
va);
1268 va_insert =
mbits(ta_insert, 63,13);
1269 ct_insert =
mbits(ta_insert, 12,0);
1271 real_insert =
bits(
va, 9,9);
1274 insert(va_insert, part_insert, ct_insert, real_insert, pte,
1308 panic(
"Invalid type for IMMU demap\n");
1324 goto doMmuWriteError;
1358 panic(
"Invalid type for IMMU demap\n");
1376 getCpuPtr()->postInterrupt(0,
bits(
data, 5, 0), 0);
1380 panic(
"need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n",
1416 uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config)
1429 uint64_t ptr =
mbits(tsb,63,13);
1430 bool split =
bits(tsb,12,12);
1431 int tsb_size =
bits(tsb,3,0);
1432 int page_size = (
ps ==
Ps0) ?
bits(config, 2,0) :
bits(config,10,8);
1434 if (
ps ==
Ps1 && split)
1435 ptr |=
ULL(1) << (13 + tsb_size);
1436 ptr |= (
tag_access >> (9 + page_size * 3)) &
mask(12+tsb_size, 4);
1451 free_list.push_back(entry -
tlb);
1465 for (
int x = 0;
x <
size;
x++) {
1477 if (oldSize !=
size)
1478 panic(
"Don't support unserializing different sized TLBs\n");
1485 for (
int idx : free_list)
1498 for (
int x = 0;
x <
size;
x++) {
1511 SparcTLBParams::create()
#define fatal(...)
This implements a cprintf based fatal() function.
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
uint64_t TteRead(int entry)
Give an entry id, read that tlb entries' tte.
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, Mode mode)=0
@ ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1
@ ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS1
void makeAtomicResponse()
T getBE() const
Get the data in the packet byte swapped from big endian to host endian.
void demapContext(int partition_id, int context_id)
Remove all entries that match a given context/partition id.
void demapPage(Addr va, int partition_id, bool real, int context_id)
Remve all entries that match a certain partition id, (contextid), and va).
std::list< TlbEntry * > freeList
@ ASI_ITLB_DATA_ACCESS_REG
#define UNSERIALIZE_SCALAR(scalar)
bool asiIsUnPriv(ASI asi)
#define UNSERIALIZE_CONTAINER(member)
int findMsbSet(uint64_t val)
Returns the bit position of the MSB that is set in the input.
void GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs)
@ ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode) override
bool asiIsLittle(ASI asi)
iterator insert(TlbRange &r, TlbEntry *d)
Fault translateFunctional(const RequestPtr &req, ThreadContext *tc, Mode mode) override
Addr translate(Addr vaddr) const
bool asiIsPartialStore(ASI asi)
EmulationPageTable * pTable
Fault translateData(const RequestPtr &req, ThreadContext *tc, bool write)
TlbEntry * lookup(Addr va, int partition_id, bool real, int context_id=0, bool update_used=true)
lookup an entry in the TLB based on the partition id, and real bit if real is true or the partition i...
std::shared_ptr< Request > RequestPtr
RequestPtr req
A pointer to the original request.
Cycles doMmuRegWrite(ThreadContext *tc, Packet *pkt)
virtual PortProxy & getPhysProxy()=0
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
void writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi)
virtual Process * getProcessPtr()=0
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
uint64_t MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb, uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config)
bool asiIsNucleus(ASI asi)
void setBE(T v)
Set the value in the data pointer to v as big endian.
void serialize(CheckpointOut &cp) const
Cycles doMmuRegRead(ThreadContext *tc, Packet *pkt)
@ STRICT_ORDER
The request is required to be strictly ordered by CPU models and is non-speculative.
bool asiIsSecondary(ASI asi)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
void flushAll() override
Remove all entries from the TLB.
void insert(Addr vpn, int partition_id, int context_id, bool real, const PageTableEntry &PTE, int entry=-1)
Insert a PTE into the TLB.
@ ASI_DMMU_CTXT_NONZERO_CONFIG
@ ASI_DTLB_DATA_ACCESS_REG
std::shared_ptr< FaultBase > Fault
bool asiIsInterrupt(ASI asi)
void serialize(CheckpointOut &cp) const override
Serialize an object.
@ ASI_DMMU_TSB_PS0_PTR_REG
@ ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0
void clearInterrupt(ThreadID tid, int int_num, int index)
@ MISCREG_QUEUE_CPU_MONDO_HEAD
void demapAll(int partition_id)
Remove all non-locked entries from the tlb that match partition id.
@ UNCACHEABLE
The request is to an uncacheable address.
constexpr decltype(nullptr) NoFault
void unserialize(CheckpointIn &cp)
void populate(uint64_t e, EntryType t=sun4u)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
@ ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0
bool asiIsPrimary(ASI asi)
#define SERIALIZE_SCALAR(scalar)
bool asiIsNoFault(ASI asi)
virtual BaseTLB * getITBPtr()=0
void unserialize(CheckpointIn &cp) override
Unserialize an object.
@ MISCREG_SCRATCHPAD_R0
Scratchpad regiscers.
void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode) override
@ ASI_IMMU_CTXT_ZERO_CONFIG
Fault translateInst(const RequestPtr &req, ThreadContext *tc)
uint64_t get_vec(int int_num)
This object is a proxy for a port or other object which implements the functional response protocol,...
@ ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS1
#define SERIALIZE_CONTAINER(member)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
virtual RegVal readMiscReg(RegIndex misc_reg)=0
@ ASI_IMMU_CTXT_NONZERO_CONFIG
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
void writeTagAccess(Addr va, int context)
bool validVirtualAddress(Addr va, bool am)
Checks if the virtual address provided is a valid one.
Cycles is a wrapper class for representing cycle counts, i.e.
@ ASI_DMMU_CTXT_ZERO_CONFIG
const Addr StartVAddrHole
std::ostream CheckpointOut
bool asiIsScratchPad(ASI asi)
Fault finalizePhysical(const RequestPtr &req, ThreadContext *tc, Mode mode) const override
Do post-translation physical address finalization.
static void ignore(const char *expr)
@ ASI_IMMU_TSB_PS1_PTR_REG
@ ASI_IMMU_TSB_PS0_PTR_REG
@ MISCREG_MMU_P_CONTEXT
MMU Internal Registers.
@ ASI_DMMU_TSB_PS1_PTR_REG
@ ASI_SPARC_ERROR_STATUS_REG
bool asiIsSparcError(ASI asi)
virtual BaseCPU * getCpuPtr()=0
bool translate(Addr vaddr, Addr &paddr)
Translate function.
BaseInterrupts * getInterruptController(ThreadID tid)
@ ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1
std::string csprintf(const char *format, const Args &...args)
uint64_t TagRead(int entry)
Given an entry id, read that tlb entries' tag.
#define ULL(N)
uint64_t constant
virtual System * getSystemPtr()=0
iterator find(const TlbRange &r)
#define panic(...)
This implements a cprintf based panic() function.
bool asiIsAsIfUser(ASI asi)
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
@ ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0
Generated on Wed Sep 30 2020 14:01:59 for gem5 by doxygen 1.8.17