18442Sgblack@eecs.umich.edu/*
210026SAli.Saidi@ARM.com * Copyright (c) 2013 ARM Limited
310026SAli.Saidi@ARM.com * All rights reserved
410026SAli.Saidi@ARM.com *
510026SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall
610026SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual
710026SAli.Saidi@ARM.com * property including but not limited to intellectual property relating
810026SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software
910026SAli.Saidi@ARM.com * licensed hereunder.  You may use the software subject to the license
1010026SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated
1110026SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software,
1210026SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form.
1310026SAli.Saidi@ARM.com *
148442Sgblack@eecs.umich.edu * Copyright (c) 2011 Google
158442Sgblack@eecs.umich.edu * All rights reserved.
168442Sgblack@eecs.umich.edu *
178442Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
188442Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
198442Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
208442Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
218442Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
228442Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
238442Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
248442Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
258442Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
268442Sgblack@eecs.umich.edu * this software without specific prior written permission.
278442Sgblack@eecs.umich.edu *
288442Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
298442Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
308442Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
318442Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
328442Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
338442Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
348442Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
358442Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
368442Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
378442Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
388442Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
398442Sgblack@eecs.umich.edu *
408442Sgblack@eecs.umich.edu * Authors: Gabe Black
418442Sgblack@eecs.umich.edu */
428442Sgblack@eecs.umich.edu
438442Sgblack@eecs.umich.edu#ifndef __ARCH_GENERIC_MEMHELPERS_HH__
448442Sgblack@eecs.umich.edu#define __ARCH_GENERIC_MEMHELPERS_HH__
458442Sgblack@eecs.umich.edu
4611881Sandreas.sandberg@arm.com#include "arch/isa_traits.hh"
478442Sgblack@eecs.umich.edu#include "base/types.hh"
4811881Sandreas.sandberg@arm.com#include "mem/packet.hh"
4910026SAli.Saidi@ARM.com#include "mem/request.hh"
508442Sgblack@eecs.umich.edu#include "sim/byteswap.hh"
518442Sgblack@eecs.umich.edu#include "sim/insttracer.hh"
528442Sgblack@eecs.umich.edu
5311303Ssteve.reinhardt@amd.com/// Initiate a read from memory in timing mode.  Note that the 'mem'
5411303Ssteve.reinhardt@amd.com/// parameter is unused; only the type of that parameter is used
5511303Ssteve.reinhardt@amd.com/// to determine the size of the access.
568442Sgblack@eecs.umich.edutemplate <class XC, class MemT>
578442Sgblack@eecs.umich.eduFault
5811303Ssteve.reinhardt@amd.cominitiateMemRead(XC *xc, Trace::InstRecord *traceData, Addr addr,
5911608Snikos.nikoleris@arm.com                MemT &mem, Request::Flags flags)
608442Sgblack@eecs.umich.edu{
6111303Ssteve.reinhardt@amd.com    return xc->initiateMemRead(addr, sizeof(MemT), flags);
628442Sgblack@eecs.umich.edu}
638442Sgblack@eecs.umich.edu
648442Sgblack@eecs.umich.edu/// Extract the data returned from a timing mode read.
658442Sgblack@eecs.umich.edutemplate <class MemT>
668442Sgblack@eecs.umich.eduvoid
678442Sgblack@eecs.umich.edugetMem(PacketPtr pkt, MemT &mem, Trace::InstRecord *traceData)
688442Sgblack@eecs.umich.edu{
6913234Sgabeblack@google.com    mem = pkt->get<MemT>(TheISA::GuestByteOrder);
708442Sgblack@eecs.umich.edu    if (traceData)
718442Sgblack@eecs.umich.edu        traceData->setData(mem);
728442Sgblack@eecs.umich.edu}
738442Sgblack@eecs.umich.edu
748442Sgblack@eecs.umich.edu/// Read from memory in atomic mode.
758442Sgblack@eecs.umich.edutemplate <class XC, class MemT>
768442Sgblack@eecs.umich.eduFault
778442Sgblack@eecs.umich.edureadMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, MemT &mem,
7811608Snikos.nikoleris@arm.com              Request::Flags flags)
798442Sgblack@eecs.umich.edu{
808442Sgblack@eecs.umich.edu    memset(&mem, 0, sizeof(mem));
8111301Ssteve.reinhardt@amd.com    Fault fault = xc->readMem(addr, (uint8_t *)&mem, sizeof(MemT), flags);
828442Sgblack@eecs.umich.edu    if (fault == NoFault) {
838737Skoansin.tan@gmail.com        mem = TheISA::gtoh(mem);
848442Sgblack@eecs.umich.edu        if (traceData)
858442Sgblack@eecs.umich.edu            traceData->setData(mem);
868442Sgblack@eecs.umich.edu    }
878442Sgblack@eecs.umich.edu    return fault;
888442Sgblack@eecs.umich.edu}
898442Sgblack@eecs.umich.edu
908442Sgblack@eecs.umich.edu/// Write to memory in timing mode.
918442Sgblack@eecs.umich.edutemplate <class XC, class MemT>
928442Sgblack@eecs.umich.eduFault
938442Sgblack@eecs.umich.eduwriteMemTiming(XC *xc, Trace::InstRecord *traceData, MemT mem, Addr addr,
9411608Snikos.nikoleris@arm.com               Request::Flags flags, uint64_t *res)
958442Sgblack@eecs.umich.edu{
968442Sgblack@eecs.umich.edu    if (traceData) {
978442Sgblack@eecs.umich.edu        traceData->setData(mem);
988442Sgblack@eecs.umich.edu    }
998442Sgblack@eecs.umich.edu    mem = TheISA::htog(mem);
1008444Sgblack@eecs.umich.edu    return xc->writeMem((uint8_t *)&mem, sizeof(MemT), addr, flags, res);
1018442Sgblack@eecs.umich.edu}
1028442Sgblack@eecs.umich.edu
1038442Sgblack@eecs.umich.edu/// Write to memory in atomic mode.
1048442Sgblack@eecs.umich.edutemplate <class XC, class MemT>
1058442Sgblack@eecs.umich.eduFault
1068442Sgblack@eecs.umich.eduwriteMemAtomic(XC *xc, Trace::InstRecord *traceData, const MemT &mem,
10711608Snikos.nikoleris@arm.com               Addr addr, Request::Flags flags, uint64_t *res)
1088442Sgblack@eecs.umich.edu{
10911301Ssteve.reinhardt@amd.com    if (traceData) {
11011301Ssteve.reinhardt@amd.com        traceData->setData(mem);
11111301Ssteve.reinhardt@amd.com    }
11211301Ssteve.reinhardt@amd.com    MemT host_mem = TheISA::htog(mem);
11311301Ssteve.reinhardt@amd.com    Fault fault =
11411301Ssteve.reinhardt@amd.com          xc->writeMem((uint8_t *)&host_mem, sizeof(MemT), addr, flags, res);
1158442Sgblack@eecs.umich.edu    if (fault == NoFault && res != NULL) {
11610026SAli.Saidi@ARM.com        if (flags & Request::MEM_SWAP || flags & Request::MEM_SWAP_COND)
11712386Sgabeblack@google.com            *(MemT *)res = TheISA::gtoh(*(MemT *)res);
11810026SAli.Saidi@ARM.com        else
11910026SAli.Saidi@ARM.com            *res = TheISA::gtoh(*res);
1208442Sgblack@eecs.umich.edu    }
1218442Sgblack@eecs.umich.edu    return fault;
1228442Sgblack@eecs.umich.edu}
1238442Sgblack@eecs.umich.edu
12412767Sqtt2@cornell.edu/// Do atomic read-modify-write (AMO) in atomic mode
12512767Sqtt2@cornell.edutemplate <class XC, class MemT>
12612767Sqtt2@cornell.eduFault
12712767Sqtt2@cornell.eduamoMemAtomic(XC *xc, Trace::InstRecord *traceData, MemT &mem, Addr addr,
12814297Sjordi.vaquero@metempsy.com             Request::Flags flags, AtomicOpFunctor *_amo_op)
12912767Sqtt2@cornell.edu{
13014297Sjordi.vaquero@metempsy.com    assert(_amo_op);
13112767Sqtt2@cornell.edu
13212767Sqtt2@cornell.edu    // mem will hold the previous value at addr after the AMO completes
13312767Sqtt2@cornell.edu    memset(&mem, 0, sizeof(mem));
13412767Sqtt2@cornell.edu
13514297Sjordi.vaquero@metempsy.com    AtomicOpFunctorPtr amo_op = AtomicOpFunctorPtr(_amo_op);
13612767Sqtt2@cornell.edu    Fault fault = xc->amoMem(addr, (uint8_t *)&mem, sizeof(MemT), flags,
13714297Sjordi.vaquero@metempsy.com                             std::move(amo_op));
13812767Sqtt2@cornell.edu
13912767Sqtt2@cornell.edu    if (fault == NoFault) {
14012767Sqtt2@cornell.edu        mem = TheISA::gtoh(mem);
14112767Sqtt2@cornell.edu        if (traceData)
14212767Sqtt2@cornell.edu            traceData->setData(mem);
14312767Sqtt2@cornell.edu    }
14412767Sqtt2@cornell.edu    return fault;
14512767Sqtt2@cornell.edu}
14612767Sqtt2@cornell.edu
14712767Sqtt2@cornell.edu/// Do atomic read-modify-wrote (AMO) in timing mode
14812767Sqtt2@cornell.edutemplate <class XC, class MemT>
14912767Sqtt2@cornell.eduFault
15012767Sqtt2@cornell.eduinitiateMemAMO(XC *xc, Trace::InstRecord *traceData, Addr addr, MemT& mem,
15114297Sjordi.vaquero@metempsy.com               Request::Flags flags, AtomicOpFunctor *_amo_op)
15212767Sqtt2@cornell.edu{
15314297Sjordi.vaquero@metempsy.com    assert(_amo_op);
15414297Sjordi.vaquero@metempsy.com    AtomicOpFunctorPtr amo_op = AtomicOpFunctorPtr(_amo_op);
15514297Sjordi.vaquero@metempsy.com    return xc->initiateMemAMO(addr, sizeof(MemT), flags, std::move(amo_op));
15612767Sqtt2@cornell.edu}
15712767Sqtt2@cornell.edu
1588442Sgblack@eecs.umich.edu#endif
159