cpu. arch: add initiateMemRead() to ExecContext interface
authorSteve Reinhardt <steve.reinhardt@amd.com>
Mon, 18 Jan 2016 02:27:46 +0000 (18:27 -0800)
committerSteve Reinhardt <steve.reinhardt@amd.com>
Mon, 18 Jan 2016 02:27:46 +0000 (18:27 -0800)
For historical reasons, the ExecContext interface had a single
function, readMem(), that did two different things depending on
whether the ExecContext supported atomic memory mode (i.e.,
AtomicSimpleCPU) or timing memory mode (all the other models).
In the former case, it actually performed a memory read; in the
latter case, it merely initiated a read access, and the read
completion did not happen until later when a response packet
arrived from the memory system.

This led to some confusing things, including timing accesses
being required to provide a pointer for the return data even
though that pointer was only used in atomic mode.

This patch splits this interface, adding a new initiateMemRead()
function to the ExecContext interface to replace the timing-mode
use of readMem().

For consistency and clarity, the readMemTiming() helper function
in the ISA definitions is renamed to initiateMemRead() as well.
For x86, where the access size is passed in explicitly, we can
also get rid of the data parameter at this level.  For other ISAs,
where the access size is determined from the type of the data
parameter, we have to keep the parameter for that purpose.

20 files changed:
src/arch/alpha/isa/mem.isa
src/arch/arm/isa/templates/mem.isa
src/arch/arm/isa/templates/mem64.isa
src/arch/arm/isa/templates/neon64.isa
src/arch/generic/memhelpers.hh
src/arch/mips/isa/formats/mem.isa
src/arch/power/isa/formats/mem.isa
src/arch/sparc/isa/formats/mem/util.isa
src/arch/x86/isa/formats/monitor_mwait.isa
src/arch/x86/isa/microops/ldstop.isa
src/arch/x86/memhelpers.hh
src/cpu/base_dyn_inst.hh
src/cpu/exec_context.hh
src/cpu/minor/exec_context.hh
src/cpu/simple/atomic.cc
src/cpu/simple/atomic.hh
src/cpu/simple/base.hh
src/cpu/simple/exec_context.hh
src/cpu/simple/timing.cc
src/cpu/simple/timing.hh

index 71b1343404a0f9e2171a82ca0f18dcfb5a9df26a..6ba8ee5d08c96a35b3dc57a580bd4c56fe264687 100644 (file)
@@ -223,7 +223,7 @@ def template LoadInitiateAcc {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
         }
 
         return fault;
index bac1cd2114480ba07ea615615e4c2b9aa97e572a..51f598f5046434abd784d2b1c49ca3b3f950d1e2 100644 (file)
@@ -438,7 +438,8 @@ def template LoadInitiateAcc {{
         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 @@ def template NeonLoadInitiateAcc {{
         %(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);
index 72ee882a76adf2cd787d649f676f60084bfc2bee..e831f17a584e114ce594ed9fd8f0eb75bd76b83c 100644 (file)
@@ -191,7 +191,7 @@ def template Load64InitiateAcc {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
         }
 
         return fault;
index 19dd50910bcb118168f90b788849f0384e3788c0..6356073c5bf90dcbe4260a55e8db1abe777d16d4 100644 (file)
@@ -313,11 +313,8 @@ def template NeonLoadInitiateAcc64 {{
         %(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;
index aa082553ab18201ef929cef3ca8698baec81dc14..b12e7b0b16e0b0be438ac6c2037b9f463d9c306a 100644 (file)
 #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.
index 80107be8b9274535e2ce6e06172bee7787973508..052ead82c379b4e5a1f9b1b149ec3dda4f798f79 100644 (file)
@@ -253,7 +253,7 @@ def template LoadInitiateAcc {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
         }
 
         return fault;
index 0c0dff6ca3d79f913e63d5b07ba81a05548e1383..eafd6aea73289007d4b85e479228d54acc210913 100644 (file)
@@ -109,7 +109,7 @@ def template LoadInitiateAcc {{
         %(ea_code)s;
 
         if (fault == NoFault) {
-            fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
+            fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags);
             xc->setEA(EA);
         }
 
index 53559e493179a98f7ecdcd4bfd4789dc660bf244..a5c64dda545dc98aa47093edae9a2ea9e49bc3bb 100644 (file)
@@ -171,7 +171,7 @@ def template LoadInitiateAcc {{
             %(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;
         }
index b26c1f26700fb075f72df70dc05c0422740a8f69..c901cedede59b4dadb4442124b3d7cc5e9427233 100644 (file)
@@ -67,10 +67,9 @@ def template MwaitInitiateAcc {{
     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;
     }
 }};
index a7c201f441be645cf26278c384a5d7ebbcd43c2d..fa8bc6f2b29252265436e61c665a45905e877a1b 100644 (file)
@@ -127,7 +127,7 @@ def template MicroLoadInitiateAcc {{
         %(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;
     }
index 64032732582e475bbd870366b079022510793e9f..705457d675fe48b1c51024218f439d8b4b68db21 100644 (file)
 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
index b6b8c045aea0953d4d33b746cdf7b46f5ff94d22..031337aec32595800e31b817e52b48e4ed91981f 100644 (file)
@@ -313,7 +313,7 @@ class BaseDynInst : public ExecContext, public RefCounted
         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 @@ class BaseDynInst : public ExecContext, public RefCounted
 
 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;
@@ -916,13 +915,6 @@ BaseDynInst<Impl>::readMem(Addr addr, uint8_t *data,
             // 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)
index c65841db2152a0bc36ca1fccf3426d3bcb8379f5..951c9c2b3e14d0c6f0ccda935d3c6cfd9d865348 100644 (file)
@@ -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 @@ class ExecContext {
      */
     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;
 
index 625d2b877688e9ecf60efbc3df237e07abd430bf..092ad5a2dcba82ba8d919980c85fb345224149a6 100644 (file)
@@ -103,10 +103,9 @@ class ExecContext : public ::ExecContext
     }
 
     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;
     }
index 77706966bcde11bb837231de9920e37ac7a82383..4afd019d0b7946c48374501a058a4d6657f6de0a 100644 (file)
@@ -415,6 +415,12 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t * data,
     }
 }
 
+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,
index 1a2f19949e367a17a03e9908bd1b73214c46fc06..c643bfe581961678a7e578a2e301621f248714a8 100644 (file)
@@ -205,6 +205,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
     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;
 
index 0ec9e502bff5abc9fc7f8d82e8c083d00267a459..9164a2960b66e69a319bc2c805c3589434cee509 100644 (file)
@@ -145,6 +145,8 @@ class BaseSimpleCPU : public BaseCPU
     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;
 
index 43a0124049d566e80f8d863ec108b1766fa9c4c7..f9d80d0d51447087539fb2b4c7aac330e4d41455 100644 (file)
@@ -291,6 +291,12 @@ class SimpleExecContext : public ExecContext {
         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
     {
index 6d67f610b54a72a35fffbb4c7ae6e394eea5f757..441d5f896109efa9f1e895e29bdb38e96f4d682f 100644 (file)
@@ -406,6 +406,13 @@ TimingSimpleCPU::buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2,
 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;
index 36e01e9be233b4c3ea7b3325f59a83002f1a8bb7..da8320793114764fce2c1c9d79a7dc2d577f0ea4 100644 (file)
@@ -286,6 +286,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
     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;