From 0eab4bf2af73ffd9813eeba961589b0cb969bcfb Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 9 Dec 2019 14:01:33 +0000 Subject: [PATCH] arch: Add raw read/writeMem helpers 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23527 Tested-by: kokoro Reviewed-by: Gabe Black Reviewed-by: Daniel Carvalho Maintainer: Gabe Black --- src/arch/generic/memhelpers.hh | 56 ++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/arch/generic/memhelpers.hh b/src/arch/generic/memhelpers.hh index 2a5a380e3..d9adfdc07 100644 --- a/src/arch/generic/memhelpers.hh +++ b/src/arch/generic/memhelpers.hh @@ -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 @@ -47,6 +47,15 @@ #include "sim/byteswap.hh" #include "sim/insttracer.hh" +template +Fault +initiateMemRead(XC *xc, Addr addr, std::size_t size, + Request::Flags flags, + const std::vector &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 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(pkt, mem, traceData); } +/// Read from memory in atomic mode. +template +Fault +readMemAtomic(XC *xc, Addr addr, uint8_t *mem, + std::size_t size, Request::Flags flags, + const std::vector &byte_enable) +{ + return xc->readMem(addr, mem, size, flags, byte_enable); +} + /// Read from memory in atomic mode. template 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 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 +Fault +writeMemTiming(XC *xc, uint8_t *mem, Addr addr, + std::size_t size, Request::Flags flags, uint64_t *res, + const std::vector &byte_enable) +{ + return xc->writeMem(mem, size, addr, flags, res, byte_enable); +} + template 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 byte_enable(sizeof(MemT), true); + return writeMemTiming(xc, (uint8_t*)&mem, addr, + sizeof(MemT), flags, res, byte_enable); } template @@ -147,6 +181,15 @@ writeMemTimingBE(XC *xc, Trace::InstRecord *traceData, MemT mem, Addr addr, } /// Write to memory in atomic mode. +template +Fault +writeMemAtomic(XC *xc, uint8_t *mem, Addr addr, + std::size_t size, Request::Flags flags, + uint64_t *res, const std::vector &byte_enable) +{ + return xc->writeMem(mem, size, addr, flags, res, byte_enable); +} + template 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 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); -- 2.30.2