arch: Add raw read/writeMem helpers
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Mon, 9 Dec 2019 14:01:33 +0000 (14:01 +0000)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 30 Sep 2020 08:50:39 +0000 (08:50 +0000)
With some exceptions (in arm/x86) the standard memory read/write interface
for instructions relies upon the helper functions in

src/arch/generic/memhelpers.hh

which wrap the ExecContext interface.

(readMem, writeMem...)

Those helpers rely on the source/destination data to be provided (as
expected) but not on the size of the transaction. The latter gets
evaluated via the host size of the source/destination data
(sizeof(MemT)).
For this reason some instructions, which are instead using an
incompatible MemT data (as an example, a SIMD operation loading data in
an array of integers), make direct use of the ExecContext interface,
which is simply requesting for a pointer and a number of bytes.
Some other instructions are using the ExecContext interface since the
helpers do not accept a byteEnable argument.

This patch is adding some helpers to address these issues. The idea is
to deprecate direct usage of the ExecContext APIs.
These new wrappers do not work with the type detection mechanism
to evaluate the number of bytes we are accessing.

JIRA: https://gem5.atlassian.net/browse/GEM5-196

Change-Id: I5b822d278bdf325a68a01aa1861b6487c6628245
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23527
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Gabe Black <gabeblack@google.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabeblack@google.com>

src/arch/generic/memhelpers.hh

index 2a5a380e36567c1400c532770b427c9a9fcaf367..d9adfdc075ff11b5dbcbbf087d66ffe643c212f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 ARM Limited
+ * Copyright (c) 2013, 2019 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
 #include "sim/byteswap.hh"
 #include "sim/insttracer.hh"
 
+template <class XC>
+Fault
+initiateMemRead(XC *xc, Addr addr, std::size_t size,
+                Request::Flags flags,
+                const std::vector<bool> &byte_enable)
+{
+    return xc->initiateMemRead(addr, size, flags, byte_enable);
+}
+
 /// 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.
@@ -55,7 +64,9 @@ Fault
 initiateMemRead(XC *xc, Trace::InstRecord *traceData, Addr addr,
                 MemT &mem, Request::Flags flags)
 {
-    return xc->initiateMemRead(addr, sizeof(MemT), flags);
+    static const std::vector<bool> byte_enable(sizeof(MemT), true);
+    return initiateMemRead(xc, addr, sizeof(MemT),
+                           flags, byte_enable);
 }
 
 /// Extract the data returned from a timing mode read.
@@ -82,6 +93,16 @@ getMemBE(PacketPtr pkt, MemT &mem, Trace::InstRecord *traceData)
     getMem<ByteOrder::big>(pkt, mem, traceData);
 }
 
+/// Read from memory in atomic mode.
+template <class XC>
+Fault
+readMemAtomic(XC *xc, Addr addr, uint8_t *mem,
+              std::size_t size, Request::Flags flags,
+              const std::vector<bool> &byte_enable)
+{
+    return xc->readMem(addr, mem, size, flags, byte_enable);
+}
+
 /// Read from memory in atomic mode.
 template <ByteOrder Order, class XC, class MemT>
 Fault
@@ -89,7 +110,9 @@ readMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, MemT &mem,
               Request::Flags flags)
 {
     memset(&mem, 0, sizeof(mem));
-    Fault fault = xc->readMem(addr, (uint8_t *)&mem, sizeof(MemT), flags);
+    static const std::vector<bool> byte_enable(sizeof(MemT), true);
+    Fault fault = readMemAtomic(xc, addr, (uint8_t*)&mem,
+                                sizeof(MemT), flags, byte_enable);
     if (fault == NoFault) {
         mem = gtoh(mem, Order);
         if (traceData)
@@ -116,6 +139,15 @@ readMemAtomicBE(XC *xc, Trace::InstRecord *traceData, Addr addr, MemT &mem,
 }
 
 /// Write to memory in timing mode.
+template <class XC>
+Fault
+writeMemTiming(XC *xc, uint8_t *mem, Addr addr,
+               std::size_t size, Request::Flags flags, uint64_t *res,
+               const std::vector<bool> &byte_enable)
+{
+    return xc->writeMem(mem, size, addr, flags, res, byte_enable);
+}
+
 template <ByteOrder Order, class XC, class MemT>
 Fault
 writeMemTiming(XC *xc, Trace::InstRecord *traceData, MemT mem, Addr addr,
@@ -125,7 +157,9 @@ writeMemTiming(XC *xc, Trace::InstRecord *traceData, MemT mem, Addr addr,
         traceData->setData(mem);
     }
     mem = htog(mem, Order);
-    return xc->writeMem((uint8_t *)&mem, sizeof(MemT), addr, flags, res);
+    static const std::vector<bool> byte_enable(sizeof(MemT), true);
+    return writeMemTiming(xc, (uint8_t*)&mem, addr,
+                          sizeof(MemT), flags, res, byte_enable);
 }
 
 template <class XC, class MemT>
@@ -147,6 +181,15 @@ writeMemTimingBE(XC *xc, Trace::InstRecord *traceData, MemT mem, Addr addr,
 }
 
 /// Write to memory in atomic mode.
+template <class XC>
+Fault
+writeMemAtomic(XC *xc, uint8_t *mem, Addr addr,
+               std::size_t size, Request::Flags flags,
+               uint64_t *res, const std::vector<bool> &byte_enable)
+{
+    return xc->writeMem(mem, size, addr, flags, res, byte_enable);
+}
+
 template <ByteOrder Order, class XC, class MemT>
 Fault
 writeMemAtomic(XC *xc, Trace::InstRecord *traceData, const MemT &mem,
@@ -156,8 +199,9 @@ writeMemAtomic(XC *xc, Trace::InstRecord *traceData, const MemT &mem,
         traceData->setData(mem);
     }
     MemT host_mem = htog(mem, Order);
-    Fault fault =
-          xc->writeMem((uint8_t *)&host_mem, sizeof(MemT), addr, flags, res);
+    static const std::vector<bool> byte_enable(sizeof(MemT), true);
+    Fault fault = writeMemAtomic(xc, (uint8_t*)&host_mem,
+                                 addr, sizeof(MemT), flags, res, byte_enable);
     if (fault == NoFault && res != NULL) {
         if (flags & Request::MEM_SWAP || flags & Request::MEM_SWAP_COND)
             *(MemT *)res = gtoh(*(MemT *)res, Order);