diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -171,7 +171,7 @@ %(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; } diff --git a/src/arch/x86/isa/formats/monitor_mwait.isa b/src/arch/x86/isa/formats/monitor_mwait.isa --- a/src/arch/x86/isa/formats/monitor_mwait.isa +++ b/src/arch/x86/isa/formats/monitor_mwait.isa @@ -67,10 +67,9 @@ 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; } }}; diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -127,7 +127,7 @@ %(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; } diff --git a/src/arch/x86/memhelpers.hh b/src/arch/x86/memhelpers.hh --- a/src/arch/x86/memhelpers.hh +++ b/src/arch/x86/memhelpers.hh @@ -38,12 +38,13 @@ namespace X86ISA { +/// Initiate a read from memory in timing mode. template 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 diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -313,7 +313,7 @@ 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); @@ -873,8 +873,7 @@ template Fault -BaseDynInst::readMem(Addr addr, uint8_t *data, - unsigned size, unsigned flags) +BaseDynInst::initiateMemRead(Addr addr, unsigned size, unsigned flags) { instFlags[ReqMade] = true; Request *req = NULL; @@ -916,13 +915,6 @@ // 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) diff --git a/src/cpu/exec_context.hh b/src/cpu/exec_context.hh --- a/src/cpu/exec_context.hh +++ b/src/cpu/exec_context.hh @@ -12,6 +12,7 @@ * 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 @@ -173,9 +174,36 @@ */ 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; diff --git a/src/cpu/minor/exec_context.hh b/src/cpu/minor/exec_context.hh --- a/src/cpu/minor/exec_context.hh +++ b/src/cpu/minor/exec_context.hh @@ -103,10 +103,9 @@ } 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; } diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh --- a/src/cpu/simple/atomic.hh +++ b/src/cpu/simple/atomic.hh @@ -205,6 +205,8 @@ 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; diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -415,6 +415,12 @@ } } +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, diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -145,6 +145,8 @@ 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; diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh --- a/src/cpu/simple/exec_context.hh +++ b/src/cpu/simple/exec_context.hh @@ -291,6 +291,12 @@ 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 { diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh --- a/src/cpu/simple/timing.hh +++ b/src/cpu/simple/timing.hh @@ -286,6 +286,8 @@ 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; diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -407,6 +407,13 @@ 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; # Node ID 2e28c22945504063885c2cb96f93e6715a79819a # Parent 62dba3a2ff4ac5d63c59b650c63a5b2a0f653630 diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -223,7 +223,7 @@ %(ea_code)s; if (fault == NoFault) { - fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags); + fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); } return fault; diff --git a/src/arch/arm/isa/templates/mem.isa b/src/arch/arm/isa/templates/mem.isa --- a/src/arch/arm/isa/templates/mem.isa +++ b/src/arch/arm/isa/templates/mem.isa @@ -438,7 +438,8 @@ 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); @@ -461,13 +462,10 @@ %(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); diff --git a/src/arch/arm/isa/templates/mem64.isa b/src/arch/arm/isa/templates/mem64.isa --- a/src/arch/arm/isa/templates/mem64.isa +++ b/src/arch/arm/isa/templates/mem64.isa @@ -191,7 +191,7 @@ %(ea_code)s; if (fault == NoFault) { - fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags); + fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); } return fault; diff --git a/src/arch/arm/isa/templates/neon64.isa b/src/arch/arm/isa/templates/neon64.isa --- a/src/arch/arm/isa/templates/neon64.isa +++ b/src/arch/arm/isa/templates/neon64.isa @@ -313,11 +313,8 @@ %(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; diff --git a/src/arch/generic/memhelpers.hh b/src/arch/generic/memhelpers.hh --- a/src/arch/generic/memhelpers.hh +++ b/src/arch/generic/memhelpers.hh @@ -48,13 +48,15 @@ #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 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. diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -253,7 +253,7 @@ %(ea_code)s; if (fault == NoFault) { - fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags); + fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); } return fault; diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa --- a/src/arch/power/isa/formats/mem.isa +++ b/src/arch/power/isa/formats/mem.isa @@ -109,7 +109,7 @@ %(ea_code)s; if (fault == NoFault) { - fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags); + fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); xc->setEA(EA); }