Mem = Data;
Base = merge(Base, EA - SegBase, addressSize);
''');
-
+ defineMicroStoreOp('Cda', 'Mem = 0;', "Request::NO_ACCESS")
iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
{"code": "Data = merge(Data, EA, dataSize);",
microopClasses["tia"] = TiaOp
- iop = InstObjParams("cda", "Cda", 'X86ISA::LdStOp',
- {"code": '''
- Addr paddr;
- fault = xc->translateDataWriteAddr(EA, paddr,
- dataSize, (1 << segment));
- ''',
- "ea_code": calculateEA})
- header_output += MicroLeaDeclare.subst(iop)
- decoder_output += MicroLdStOpConstructor.subst(iop)
- exec_output += MicroLeaExecute.subst(iop)
-
class CdaOp(LdStOp):
def __init__(self, segment, addr, disp = 0,
dataSize="env.dataSize", addressSize="env.addressSize"):
template <class T>
Fault read(Addr addr, T &data, unsigned flags);
- Fault translateDataReadAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags);
-
/**
* Does a write to a given address.
* @param data The data to be written.
Fault write(T data, Addr addr, unsigned flags,
uint64_t *res);
- Fault translateDataWriteAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags);
-
void prefetch(Addr addr, unsigned flags);
void writeHint(Addr addr, int size, unsigned flags);
Fault copySrcTranslate(Addr src);
{ thread->storeCondFailures = sc_failures; }
};
-template<class Impl>
-Fault
-BaseDynInst<Impl>::translateDataReadAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags)
-{
- if (traceData) {
- traceData->setAddr(vaddr);
- }
-
- reqMade = true;
- Request *req = new Request();
- req->setVirt(asid, vaddr, size, flags, PC);
- req->setThreadContext(thread->contextId(), threadNumber);
-
- fault = cpu->translateDataReadReq(req, thread);
-
- if (fault == NoFault)
- paddr = req->getPaddr();
-
- delete req;
- return fault;
-}
-
template<class Impl>
template<class T>
inline Fault
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->contextId(), threadNumber);
- fault = cpu->translateDataReadReq(req, thread);
+ fault = cpu->dtb->translate(req, thread->getTC(), false);
if (req->isUncacheable())
isUncacheable = true;
return fault;
}
-template<class Impl>
-Fault
-BaseDynInst<Impl>::translateDataWriteAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags)
-{
- if (traceData) {
- traceData->setAddr(vaddr);
- }
-
- reqMade = true;
- Request *req = new Request();
- req->setVirt(asid, vaddr, size, flags, PC);
- req->setThreadContext(thread->contextId(), threadNumber);
-
- fault = cpu->translateDataWriteReq(req, thread);
-
- if (fault == NoFault)
- paddr = req->getPaddr();
-
- delete req;
- return fault;
-}
-
template<class Impl>
template<class T>
inline Fault
req->setVirt(asid, addr, sizeof(T), flags, this->PC);
req->setThreadContext(thread->contextId(), threadNumber);
- fault = cpu->translateDataWriteReq(req, thread);
+ fault = cpu->dtb->translate(req, thread->getTC(), true);
if (req->isUncacheable())
isUncacheable = true;
memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
// translate to physical address
- translateDataReadReq(memReq);
+ dtb->translate(memReq, tc, false);
PacketPtr pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
memReq->setVirt(0, addr, sizeof(T), flags, thread->readPC());
// translate to physical address
- thread->translateDataWriteReq(memReq);
+ dtb->translate(memReq, tc, true);
// Can compare the write data and result only if it's cacheable,
// not a store conditional, or is a store conditional that
}
#endif // FULL_SYSTEM
-bool
-CheckerCPU::translateInstReq(Request *req)
-{
-#if FULL_SYSTEM
- return (thread->translateInstReq(req) == NoFault);
-#else
- thread->translateInstReq(req);
- return true;
-#endif
-}
-
-void
-CheckerCPU::translateDataReadReq(Request *req)
-{
- thread->translateDataReadReq(req);
-
- if (req->getVaddr() != unverifiedReq->getVaddr()) {
- warn("%lli: Request virtual addresses do not match! Inst: %#x, "
- "checker: %#x",
- curTick, unverifiedReq->getVaddr(), req->getVaddr());
- handleError();
- }
- req->setPaddr(unverifiedReq->getPaddr());
-
- if (checkFlags(req)) {
- warn("%lli: Request flags do not match! Inst: %#x, checker: %#x",
- curTick, unverifiedReq->getFlags(), req->getFlags());
- handleError();
- }
-}
-
-void
-CheckerCPU::translateDataWriteReq(Request *req)
-{
- thread->translateDataWriteReq(req);
-
- if (req->getVaddr() != unverifiedReq->getVaddr()) {
- warn("%lli: Request virtual addresses do not match! Inst: %#x, "
- "checker: %#x",
- curTick, unverifiedReq->getVaddr(), req->getVaddr());
- handleError();
- }
- req->setPaddr(unverifiedReq->getPaddr());
-
- if (checkFlags(req)) {
- warn("%lli: Request flags do not match! Inst: %#x, checker: %#x",
- curTick, unverifiedReq->getFlags(), req->getFlags());
- handleError();
- }
-}
-
bool
CheckerCPU::checkFlags(Request *req)
{
this->dtb->demapPage(vaddr, asn);
}
- bool translateInstReq(Request *req);
- void translateDataWriteReq(Request *req);
- void translateDataReadReq(Request *req);
-
#if FULL_SYSTEM
Fault hwrei() { return thread->hwrei(); }
void ev5_trap(Fault fault) { fault->invoke(tc); }
fetch_PC, thread->contextId(),
inst->threadNumber);
- bool succeeded = translateInstReq(memReq);
+ bool succeeded = itb->translate(memReq, thread);
if (!succeeded) {
if (inst->getFault() == NoFault) {
/** Debug function to print all instructions on the list. */
void dumpInsts();
- /** Translates instruction requestion in syscall emulation mode. */
- Fault translateInstReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data read request in syscall emulation mode. */
- Fault translateDataReadReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data write request in syscall emulation mode. */
- Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
/** Forwards an instruction read to the appropriate data
* resource (indexes into Resource Pool thru "dataPortIdx")
*/
case FetchLookup:
{
tlb_req->fault =
- this->cpu->translateInstReq(tlb_req->memReq, cpu->thread[tid]);
+ this->cpu->itb->translate(tlb_req->memReq,
+ cpu->thread[tid]->getTC());
if (tlb_req->fault != NoFault) {
DPRINTF(Resource, "[tid:%i]: %s encountered while translating "
tid, seq_num, tlb_req->memReq->getVaddr());
tlb_req->fault =
- this->cpu->translateInstReq(tlb_req->memReq, cpu->thread[tid]);
+ this->cpu->itb->translate(tlb_req->memReq,
+ cpu->thread[tid]->getTC());
if (tlb_req->fault != NoFault) {
DPRINTF(Resource, "[tid:%i]: %s encountered while translating "
this->dtb->demapPage(vaddr, asn);
}
- /** Translates instruction requestion. */
- Fault translateInstReq(RequestPtr &req, Thread *thread)
- {
- return this->itb->translate(req, thread->getTC());
- }
-
- /** Translates data read request. */
- Fault translateDataReadReq(RequestPtr &req, Thread *thread)
- {
- return this->dtb->translate(req, thread->getTC(), false);
- }
-
- /** Translates data write request. */
- Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
- {
- return this->dtb->translate(req, thread->getTC(), true);
- }
-
/** Returns a specific port. */
Port *getPort(const std::string &if_name, int idx);
memReq[tid] = mem_req;
// Translate the instruction request.
- fault = cpu->translateInstReq(mem_req, cpu->thread[tid]);
+ fault = cpu->itb->translate(mem_req, cpu->thread[tid]->getTC());
// In the case of faults, the fetch stage may need to stall and wait
// for the ITB miss to be handled.
void demapPage(Addr vaddr, uint64_t asn)
{
- itb->demap(vaddr, asn);
- dtb->demap(vaddr, asn);
+ cpu->itb->demap(vaddr, asn);
+ cpu->dtb->demap(vaddr, asn);
}
void demapInstPage(Addr vaddr, uint64_t asn)
{
- itb->demap(vaddr, asn);
+ cpu->itb->demap(vaddr, asn);
}
void demapDataPage(Addr vaddr, uint64_t asn)
{
- dtb->demap(vaddr, asn);
+ cpu->dtb->demap(vaddr, asn);
}
-#if FULL_SYSTEM
- /** Translates instruction requestion. */
- Fault translateInstReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
- {
- return itb->translate(req, thread->getTC());
- }
-
- /** Translates data read request. */
- Fault translateDataReadReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
- {
- return dtb->translate(req, thread->getTC(), false);
- }
-
- /** Translates data write request. */
- Fault translateDataWriteReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
- {
- return dtb->translate(req, thread->getTC(), true);
- }
-
-#else
- /** Translates instruction requestion in syscall emulation mode. */
- Fault translateInstReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data read request in syscall emulation mode. */
- Fault translateDataReadReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-
- /** Translates data write request in syscall emulation mode. */
- Fault translateDataWriteReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
- {
- return thread->getProcessPtr()->pTable->translate(req);
- }
-#endif
-
/** CPU read function, forwards read to LSQ. */
template <class T>
Fault read(Request *req, T &data, int load_idx)
PC, cpu->thread->contextId());
// Translate the instruction request.
- fault = cpu->translateInstReq(memReq, thread);
+ fault = cpu->itb->translate(memReq, thread);
// Now do the timing access to see whether or not the instruction
// exists within the cache.
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
- Fault fault = cpu->translateDataReadReq(memReq);
+ Fault fault = cpu->dtb->translate(memReq, thread->getTC(), false);
// if we have a cache, do cache access too
if (fault == NoFault && dcacheInterface) {
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
- Fault fault = cpu->translateDataWriteReq(memReq);
+ Fault fault = cpu->dtb->translate(memReq, thread->getTC(), true);
if (fault == NoFault && dcacheInterface) {
memReq->cmd = Write;
req->setVirt(0, addr, dataSize, flags, thread->readPC());
// translate to physical address
- Fault fault = thread->translateDataReadReq(req);
+ Fault fault = thread->dtb->translate(req, tc, false);
// Now do the access.
if (fault == NoFault) {
}
}
-Fault
-AtomicSimpleCPU::translateDataReadAddr(Addr vaddr, Addr & paddr,
- int size, unsigned flags)
-{
- // use the CPU's statically allocated read request and packet objects
- Request *req = &data_read_req;
-
- if (traceData) {
- traceData->setAddr(vaddr);
- }
-
- //The block size of our peer.
- int blockSize = dcachePort.peerBlockSize();
- //The size of the data we're trying to read.
- int dataSize = size;
-
- bool firstTimeThrough = true;
-
- //The address of the second part of this access if it needs to be split
- //across a cache line boundary.
- Addr secondAddr = roundDown(vaddr + dataSize - 1, blockSize);
-
- if(secondAddr > vaddr)
- dataSize = secondAddr - vaddr;
-
- while(1) {
- req->setVirt(0, vaddr, dataSize, flags, thread->readPC());
-
- // translate to physical address
- Fault fault = thread->translateDataReadReq(req);
-
- //If there's a fault, return it
- if (fault != NoFault)
- return fault;
-
- if (firstTimeThrough) {
- paddr = req->getPaddr();
- firstTimeThrough = false;
- }
-
- //If we don't need to access a second cache line, stop now.
- if (secondAddr <= vaddr)
- return fault;
-
- /*
- * Set up for accessing the second cache line.
- */
-
- //Adjust the size to get the remaining bytes.
- dataSize = vaddr + size - secondAddr;
- //And access the right address.
- vaddr = secondAddr;
- }
-}
-
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
req->setVirt(0, addr, dataSize, flags, thread->readPC());
// translate to physical address
- Fault fault = thread->translateDataWriteReq(req);
+ Fault fault = thread->dtb->translate(req, tc, true);
// Now do the access.
if (fault == NoFault) {
}
}
-Fault
-AtomicSimpleCPU::translateDataWriteAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags)
-{
- // use the CPU's statically allocated write request and packet objects
- Request *req = &data_write_req;
-
- if (traceData) {
- traceData->setAddr(vaddr);
- }
-
- //The block size of our peer.
- int blockSize = dcachePort.peerBlockSize();
-
- //The address of the second part of this access if it needs to be split
- //across a cache line boundary.
- Addr secondAddr = roundDown(vaddr + size - 1, blockSize);
-
- //The size of the data we're trying to read.
- int dataSize = size;
-
- bool firstTimeThrough = true;
-
- if(secondAddr > vaddr)
- dataSize = secondAddr - vaddr;
-
- dcache_latency = 0;
-
- while(1) {
- req->setVirt(0, vaddr, dataSize, flags, thread->readPC());
-
- // translate to physical address
- Fault fault = thread->translateDataWriteReq(req);
-
- //If there's a fault or we don't need to access a second cache line,
- //stop now.
- if (fault != NoFault)
- return fault;
-
- if (firstTimeThrough) {
- paddr = req->getPaddr();
- firstTimeThrough = false;
- }
-
- if (secondAddr <= vaddr)
- return fault;
-
- /*
- * Set up for accessing the second cache line.
- */
-
- //Adjust the size to get the remaining bytes.
- dataSize = vaddr + size - secondAddr;
- //And access the right address.
- vaddr = secondAddr;
- }
-}
-
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <class T>
Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
- Fault translateDataReadAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags);
- Fault translateDataWriteAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags);
-
/**
* Print state of address in memory system via PrintReq (for
* debugging).
Addr fetchPC = (threadPC & PCMask) + fetchOffset;
req->setVirt(0, fetchPC, sizeof(MachInst), 0, threadPC);
- Fault fault = thread->translateInstReq(req);
+ Fault fault = thread->itb->translate(req, tc);
return fault;
}
if ((fault = buildPacket(pkt1, req1, read)) != NoFault ||
(fault = buildPacket(pkt2, req2, read)) != NoFault) {
delete req;
+ delete req1;
delete pkt1;
req = NULL;
pkt1 = NULL;
req->setPhys(req1->getPaddr(), req->getSize(), req1->getFlags());
PacketPtr pkt = new Packet(req, pkt1->cmd.responseCommand(),
Packet::Broadcast);
+ if (req->getFlags().isSet(Request::NO_ACCESS)) {
+ delete req1;
+ delete pkt1;
+ delete req2;
+ delete pkt2;
+ pkt1 = pkt;
+ pkt2 = NULL;
+ return NoFault;
+ }
pkt->dataDynamic<uint8_t>(data);
pkt1->dataStatic<uint8_t>(data);
Fault
TimingSimpleCPU::buildPacket(PacketPtr &pkt, RequestPtr &req, bool read)
{
- Fault fault = read ? thread->translateDataReadReq(req) :
- thread->translateDataWriteReq(req);
+ Fault fault = thread->dtb->translate(req, tc, !read);
MemCmd cmd;
if (fault != NoFault) {
delete req;
if (split_addr > addr) {
PacketPtr pkt1, pkt2;
- this->buildSplitPacket(pkt1, pkt2, req,
+ Fault fault = this->buildSplitPacket(pkt1, pkt2, req,
split_addr, (uint8_t *)(new T), true);
- if (handleReadPacket(pkt1)) {
+ if (fault != NoFault)
+ return fault;
+ if (req->getFlags().isSet(Request::NO_ACCESS)) {
+ dcache_pkt = pkt1;
+ } else if (handleReadPacket(pkt1)) {
SplitFragmentSenderState * send_state =
dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
send_state->clearFromParent();
if (fault != NoFault) {
return fault;
}
- pkt->dataDynamic<T>(new T);
-
- handleReadPacket(pkt);
+ if (req->getFlags().isSet(Request::NO_ACCESS)) {
+ dcache_pkt = pkt;
+ } else {
+ pkt->dataDynamic<T>(new T);
+ handleReadPacket(pkt);
+ }
}
if (traceData) {
return NoFault;
}
-Fault
-TimingSimpleCPU::translateDataReadAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags)
-{
- Request *req =
- new Request(0, vaddr, size, flags, thread->readPC(), _cpuId, 0);
-
- if (traceData) {
- traceData->setAddr(vaddr);
- }
-
- Fault fault = thread->translateDataWriteReq(req);
-
- if (fault == NoFault)
- paddr = req->getPaddr();
-
- delete req;
- return fault;
-}
-
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
if (fault != NoFault)
return fault;
dcache_pkt = pkt1;
- if (handleWritePacket()) {
- SplitFragmentSenderState * send_state =
- dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
- send_state->clearFromParent();
- dcache_pkt = pkt2;
- if (handleReadPacket(pkt2)) {
- send_state =
- dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState);
+ if (!req->getFlags().isSet(Request::NO_ACCESS)) {
+ if (handleWritePacket()) {
+ SplitFragmentSenderState * send_state =
+ dynamic_cast<SplitFragmentSenderState *>(
+ pkt1->senderState);
send_state->clearFromParent();
+ dcache_pkt = pkt2;
+ if (handleReadPacket(pkt2)) {
+ send_state =
+ dynamic_cast<SplitFragmentSenderState *>(
+ pkt1->senderState);
+ send_state->clearFromParent();
+ }
}
}
} else {
if (fault != NoFault)
return fault;
- if (req->isLocked()) {
- do_access = TheISA::handleLockedWrite(thread, req);
- } else if (req->isCondSwap()) {
- assert(res);
- req->setExtraData(*res);
- }
+ if (!req->getFlags().isSet(Request::NO_ACCESS)) {
+ if (req->isLocked()) {
+ do_access = TheISA::handleLockedWrite(thread, req);
+ } else if (req->isCondSwap()) {
+ assert(res);
+ req->setExtraData(*res);
+ }
- dcache_pkt->allocate();
- if (req->isMmapedIpr())
- dcache_pkt->set(htog(data));
- else
- dcache_pkt->set(data);
+ dcache_pkt->allocate();
+ if (req->isMmapedIpr())
+ dcache_pkt->set(htog(data));
+ else
+ dcache_pkt->set(data);
- if (do_access)
- handleWritePacket();
+ if (do_access)
+ handleWritePacket();
+ }
}
if (traceData) {
return NoFault;
}
-Fault
-TimingSimpleCPU::translateDataWriteAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags)
-{
- Request *req =
- new Request(0, vaddr, size, flags, thread->readPC(), _cpuId, 0);
-
- if (traceData) {
- traceData->setAddr(vaddr);
- }
-
- Fault fault = thread->translateDataWriteReq(req);
-
- if (fault == NoFault)
- paddr = req->getPaddr();
-
- delete req;
- return fault;
-}
-
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
template <class T>
Fault read(Addr addr, T &data, unsigned flags);
- Fault translateDataReadAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags);
-
template <class T>
Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
- Fault translateDataWriteAddr(Addr vaddr, Addr &paddr,
- int size, unsigned flags);
-
void fetch();
void completeIfetch(PacketPtr );
void completeDataAccess(PacketPtr );
*/
ThreadContext *getTC() { return tc; }
- Fault translateInstReq(RequestPtr &req)
- {
- return itb->translate(req, tc);
- }
-
- Fault translateDataReadReq(RequestPtr &req)
- {
- return dtb->translate(req, tc, false);
- }
-
- Fault translateDataWriteReq(RequestPtr &req)
- {
- return dtb->translate(req, tc, true);
- }
-
void demapPage(Addr vaddr, uint64_t asn)
{
itb->demapPage(vaddr, asn);
static const FlagsType UNCACHEABLE = 0x00001000;
/** The request should not cause a page fault. */
static const FlagsType NO_FAULT = 0x00002000;
+ /** The request should not cause a memory access. */
+ static const FlagsType NO_ACCESS = 0x00004000;
/** The request should be prefetched into the exclusive state. */
static const FlagsType PF_EXCLUSIVE = 0x00010000;
/** The request should be marked as LRU. */