%(ea_code)s;
if (fault == NoFault) {
- fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+ fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
}
return fault;
if (%(predicate_test)s)
{
if (fault == NoFault) {
- fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+ fault = initiateMemRead(xc, traceData, EA, Mem,
+ memAccessFlags);
}
} else {
xc->setPredicate(false);
%(op_rd)s;
%(ea_code)s;
- MemUnion memUnion;
- uint8_t *dataPtr = memUnion.bytes;
-
if (%(predicate_test)s)
{
if (fault == NoFault) {
- fault = xc->readMem(EA, dataPtr, %(size)d, memAccessFlags);
+ fault = xc->initiateMemRead(EA, %(size)d, memAccessFlags);
}
} else {
xc->setPredicate(false);
%(ea_code)s;
if (fault == NoFault) {
- fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+ fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
}
return fault;
%(op_rd)s;
%(ea_code)s;
- MemUnion memUnion;
- uint8_t *dataPtr = memUnion.bytes;
-
if (fault == NoFault) {
- fault = xc->readMem(EA, dataPtr, accSize, memAccessFlags);
+ fault = xc->initiateMemRead(EA, accSize, memAccessFlags);
}
return fault;
#include "sim/byteswap.hh"
#include "sim/insttracer.hh"
-/// Read from memory in timing mode.
+/// Initiate a read from memory in timing mode. Note that the 'mem'
+/// parameter is unused; only the type of that parameter is used
+/// to determine the size of the access.
template <class XC, class MemT>
Fault
-readMemTiming(XC *xc, Trace::InstRecord *traceData, Addr addr,
- MemT &mem, unsigned flags)
+initiateMemRead(XC *xc, Trace::InstRecord *traceData, Addr addr,
+ MemT &mem, unsigned flags)
{
- return xc->readMem(addr, (uint8_t *)&mem, sizeof(MemT), flags);
+ return xc->initiateMemRead(addr, sizeof(MemT), flags);
}
/// Extract the data returned from a timing mode read.
%(ea_code)s;
if (fault == NoFault) {
- fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+ fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
}
return fault;
%(ea_code)s;
if (fault == NoFault) {
- fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+ fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
xc->setEA(EA);
}
%(fault_check)s;
if (fault == NoFault) {
%(EA_trunc)s
- fault = readMemTiming(xc, traceData, EA, Mem, %(asi_val)s);
+ fault = initiateMemRead(xc, traceData, EA, Mem, %(asi_val)s);
}
return fault;
}
Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc,
Trace::InstRecord * traceData) const
{
- uint64_t m = 0; //mem
unsigned s = 0x8; //size
unsigned f = 0; //flags
- readMemTiming(xc, traceData, xc->getAddrMonitor()->vAddr, m, s, f);
+ initiateMemRead(xc, traceData, xc->getAddrMonitor()->vAddr, s, f);
return NoFault;
}
}};
%(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
- fault = readMemTiming(xc, traceData, EA, Mem, dataSize, memFlags);
+ fault = initiateMemRead(xc, traceData, EA, dataSize, memFlags);
return fault;
}
namespace X86ISA
{
+/// Initiate a read from memory in timing mode.
template <class XC>
Fault
-readMemTiming(XC *xc, Trace::InstRecord *traceData, Addr addr,
- uint64_t &mem, unsigned dataSize, unsigned flags)
+initiateMemRead(XC *xc, Trace::InstRecord *traceData, Addr addr,
+ unsigned dataSize, unsigned flags)
{
- return xc->readMem(addr, (uint8_t *)&mem, dataSize, flags);
+ return xc->initiateMemRead(addr, dataSize, flags);
}
static inline uint64_t
cpu->demapPage(vaddr, asn);
}
- Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
+ Fault initiateMemRead(Addr addr, unsigned size, unsigned flags);
Fault writeMem(uint8_t *data, unsigned size,
Addr addr, unsigned flags, uint64_t *res);
template<class Impl>
Fault
-BaseDynInst<Impl>::readMem(Addr addr, uint8_t *data,
- unsigned size, unsigned flags)
+BaseDynInst<Impl>::initiateMemRead(Addr addr, unsigned size, unsigned flags)
{
instFlags[ReqMade] = true;
Request *req = NULL;
// instruction as executed.
this->setExecuted();
}
-
- if (fault != NoFault) {
- // Return a fixed value to keep simulation deterministic even
- // along misspeculated paths.
- if (data)
- bzero(data, size);
- }
}
if (traceData)
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2015 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
*/
virtual Addr getEA() const = 0;
+ /**
+ * Perform an atomic memory read operation. Must be overridden
+ * for exec contexts that support atomic memory mode. Not pure
+ * virtual since exec contexts that only support timing memory
+ * mode need not override (though in that case this function
+ * should never be called).
+ */
virtual Fault readMem(Addr addr, uint8_t *data, unsigned int size,
- unsigned int flags) = 0;
+ unsigned int flags)
+ {
+ panic("ExecContext::readMem() should be overridden\n");
+ }
+ /**
+ * Initiate a timing memory read operation. Must be overridden
+ * for exec contexts that support timing memory mode. Not pure
+ * virtual since exec contexts that only support atomic memory
+ * mode need not override (though in that case this function
+ * should never be called).
+ */
+ virtual Fault initiateMemRead(Addr addr, unsigned int size,
+ unsigned int flags)
+ {
+ panic("ExecContext::initiateMemRead() should be overridden\n");
+ }
+
+ /**
+ * For atomic-mode contexts, perform an atomic memory write operation.
+ * For timing-mode contexts, initiate a timing memory write operation.
+ */
virtual Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
unsigned int flags, uint64_t *res) = 0;
}
Fault
- readMem(Addr addr, uint8_t *data, unsigned int size,
- unsigned int flags)
+ initiateMemRead(Addr addr, unsigned int size, unsigned int flags)
{
- execute.getLSQ().pushRequest(inst, true /* load */, data,
+ execute.getLSQ().pushRequest(inst, true /* load */, nullptr,
size, addr, flags, NULL);
return NoFault;
}
}
}
+Fault
+AtomicSimpleCPU::initiateMemRead(Addr addr, unsigned size, unsigned flags)
+{
+ panic("initiateMemRead() is for timing accesses, and should "
+ "never be called on AtomicSimpleCPU.\n");
+}
Fault
AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size,
Fault readMem(Addr addr, uint8_t *data, unsigned size,
unsigned flags) override;
+ Fault initiateMemRead(Addr addr, unsigned size, unsigned flags) override;
+
Fault writeMem(uint8_t *data, unsigned size,
Addr addr, unsigned flags, uint64_t *res) override;
virtual Fault readMem(Addr addr, uint8_t* data, unsigned size,
unsigned flags) = 0;
+ virtual Fault initiateMemRead(Addr addr, unsigned size, unsigned flags) = 0;
+
virtual Fault writeMem(uint8_t* data, unsigned size, Addr addr,
unsigned flags, uint64_t* res) = 0;
return cpu->readMem(addr, data, size, flags);
}
+ Fault initiateMemRead(Addr addr, unsigned int size,
+ unsigned int flags) override
+ {
+ return cpu->initiateMemRead(addr, size, flags);
+ }
+
Fault writeMem(uint8_t *data, unsigned int size, Addr addr,
unsigned int flags, uint64_t *res) override
{
Fault
TimingSimpleCPU::readMem(Addr addr, uint8_t *data,
unsigned size, unsigned flags)
+{
+ panic("readMem() is for atomic accesses, and should "
+ "never be called on TimingSimpleCPU.\n");
+}
+
+Fault
+TimingSimpleCPU::initiateMemRead(Addr addr, unsigned size, unsigned flags)
{
SimpleExecContext &t_info = *threadInfo[curThread];
SimpleThread* thread = t_info.thread;
Fault readMem(Addr addr, uint8_t *data, unsigned size,
unsigned flags) override;
+ Fault initiateMemRead(Addr addr, unsigned size, unsigned flags) override;
+
Fault writeMem(uint8_t *data, unsigned size,
Addr addr, unsigned flags, uint64_t *res) override;