memhelpers.hh revision 11608
18442Sgblack@eecs.umich.edu/*
28442Sgblack@eecs.umich.edu * Copyright (c) 2011 Google
311328Ssteve.reinhardt@amd.com * Copyright (c) 2015 Advanced Micro Devices, Inc.
48442Sgblack@eecs.umich.edu * All rights reserved.
58442Sgblack@eecs.umich.edu *
68442Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
78442Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
88442Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
98442Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
108442Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
118442Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
128442Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
138442Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
148442Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
158442Sgblack@eecs.umich.edu * this software without specific prior written permission.
168442Sgblack@eecs.umich.edu *
178442Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
188442Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
198442Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
208442Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
218442Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
228442Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
238442Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248442Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258442Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268442Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
278442Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288442Sgblack@eecs.umich.edu *
298442Sgblack@eecs.umich.edu * Authors: Gabe Black
308442Sgblack@eecs.umich.edu */
318442Sgblack@eecs.umich.edu
328442Sgblack@eecs.umich.edu#ifndef __ARCH_X86_MEMHELPERS_HH__
338442Sgblack@eecs.umich.edu#define __ARCH_X86_MEMHELPERS_HH__
348442Sgblack@eecs.umich.edu
3511328Ssteve.reinhardt@amd.com#include <array>
3611328Ssteve.reinhardt@amd.com
378442Sgblack@eecs.umich.edu#include "base/types.hh"
388442Sgblack@eecs.umich.edu#include "sim/byteswap.hh"
398442Sgblack@eecs.umich.edu#include "sim/insttracer.hh"
408442Sgblack@eecs.umich.edu
418442Sgblack@eecs.umich.edunamespace X86ISA
428442Sgblack@eecs.umich.edu{
438442Sgblack@eecs.umich.edu
4411303Ssteve.reinhardt@amd.com/// Initiate a read from memory in timing mode.
458442Sgblack@eecs.umich.edutemplate <class XC>
468442Sgblack@eecs.umich.eduFault
4711303Ssteve.reinhardt@amd.cominitiateMemRead(XC *xc, Trace::InstRecord *traceData, Addr addr,
4811608Snikos.nikoleris@arm.com                unsigned dataSize, Request::Flags flags)
498442Sgblack@eecs.umich.edu{
5011303Ssteve.reinhardt@amd.com    return xc->initiateMemRead(addr, dataSize, flags);
518442Sgblack@eecs.umich.edu}
528442Sgblack@eecs.umich.edu
5311328Ssteve.reinhardt@amd.comstatic void
5411328Ssteve.reinhardt@amd.comgetMem(PacketPtr pkt, uint64_t &mem, unsigned dataSize,
5511328Ssteve.reinhardt@amd.com       Trace::InstRecord *traceData)
568442Sgblack@eecs.umich.edu{
578442Sgblack@eecs.umich.edu    switch (dataSize) {
588442Sgblack@eecs.umich.edu      case 1:
598442Sgblack@eecs.umich.edu        mem = pkt->get<uint8_t>();
608442Sgblack@eecs.umich.edu        break;
618442Sgblack@eecs.umich.edu      case 2:
628442Sgblack@eecs.umich.edu        mem = pkt->get<uint16_t>();
638442Sgblack@eecs.umich.edu        break;
648442Sgblack@eecs.umich.edu      case 4:
658442Sgblack@eecs.umich.edu        mem = pkt->get<uint32_t>();
668442Sgblack@eecs.umich.edu        break;
678442Sgblack@eecs.umich.edu      case 8:
688442Sgblack@eecs.umich.edu        mem = pkt->get<uint64_t>();
698442Sgblack@eecs.umich.edu        break;
708442Sgblack@eecs.umich.edu      default:
718442Sgblack@eecs.umich.edu        panic("Unhandled size in getMem.\n");
728442Sgblack@eecs.umich.edu    }
738442Sgblack@eecs.umich.edu    if (traceData)
748442Sgblack@eecs.umich.edu        traceData->setData(mem);
758442Sgblack@eecs.umich.edu}
768442Sgblack@eecs.umich.edu
7711328Ssteve.reinhardt@amd.com
7811328Ssteve.reinhardt@amd.comtemplate <size_t N>
7911328Ssteve.reinhardt@amd.comvoid
8011328Ssteve.reinhardt@amd.comgetMem(PacketPtr pkt, std::array<uint64_t, N> &mem, unsigned dataSize,
8111328Ssteve.reinhardt@amd.com       Trace::InstRecord *traceData)
8211328Ssteve.reinhardt@amd.com{
8311328Ssteve.reinhardt@amd.com    assert(dataSize >= 8);
8411328Ssteve.reinhardt@amd.com    assert((dataSize % 8) == 0);
8511328Ssteve.reinhardt@amd.com
8611328Ssteve.reinhardt@amd.com    int num_words = dataSize / 8;
8711328Ssteve.reinhardt@amd.com    assert(num_words <= N);
8811328Ssteve.reinhardt@amd.com
8911328Ssteve.reinhardt@amd.com    auto pkt_data = pkt->getConstPtr<const uint64_t>();
9011328Ssteve.reinhardt@amd.com    for (int i = 0; i < num_words; ++i)
9111328Ssteve.reinhardt@amd.com        mem[i] = gtoh(pkt_data[i]);
9211328Ssteve.reinhardt@amd.com
9311328Ssteve.reinhardt@amd.com    // traceData record only has space for 64 bits, so we just record
9411328Ssteve.reinhardt@amd.com    // the first qword
9511328Ssteve.reinhardt@amd.com    if (traceData)
9611328Ssteve.reinhardt@amd.com        traceData->setData(mem[0]);
9711328Ssteve.reinhardt@amd.com}
9811328Ssteve.reinhardt@amd.com
9911328Ssteve.reinhardt@amd.com
1008442Sgblack@eecs.umich.edutemplate <class XC>
1018442Sgblack@eecs.umich.eduFault
1028442Sgblack@eecs.umich.edureadMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, uint64_t &mem,
10311608Snikos.nikoleris@arm.com              unsigned dataSize, Request::Flags flags)
1048442Sgblack@eecs.umich.edu{
1058442Sgblack@eecs.umich.edu    memset(&mem, 0, sizeof(mem));
10611301Ssteve.reinhardt@amd.com    Fault fault = xc->readMem(addr, (uint8_t *)&mem, dataSize, flags);
1078442Sgblack@eecs.umich.edu    if (fault == NoFault) {
1088442Sgblack@eecs.umich.edu        // If LE to LE, this is a nop, if LE to BE, the actual data ends up
1098442Sgblack@eecs.umich.edu        // in the right place because the LSBs where at the low addresses on
1108442Sgblack@eecs.umich.edu        // access. This doesn't work for BE guests.
1118442Sgblack@eecs.umich.edu        mem = gtoh(mem);
1128442Sgblack@eecs.umich.edu        if (traceData)
1138442Sgblack@eecs.umich.edu            traceData->setData(mem);
1148442Sgblack@eecs.umich.edu    }
1158442Sgblack@eecs.umich.edu    return fault;
1168442Sgblack@eecs.umich.edu}
1178442Sgblack@eecs.umich.edu
11811328Ssteve.reinhardt@amd.comtemplate <class XC, size_t N>
11911328Ssteve.reinhardt@amd.comFault
12011328Ssteve.reinhardt@amd.comreadMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr,
12111328Ssteve.reinhardt@amd.com              std::array<uint64_t, N> &mem, unsigned dataSize,
12211328Ssteve.reinhardt@amd.com              unsigned flags)
12311328Ssteve.reinhardt@amd.com{
12411328Ssteve.reinhardt@amd.com    assert(dataSize >= 8);
12511328Ssteve.reinhardt@amd.com    assert((dataSize % 8) == 0);
12611328Ssteve.reinhardt@amd.com
12711328Ssteve.reinhardt@amd.com    Fault fault = xc->readMem(addr, (uint8_t *)&mem, dataSize, flags);
12811328Ssteve.reinhardt@amd.com
12911328Ssteve.reinhardt@amd.com    if (fault == NoFault) {
13011328Ssteve.reinhardt@amd.com        int num_words = dataSize / 8;
13111328Ssteve.reinhardt@amd.com        assert(num_words <= N);
13211328Ssteve.reinhardt@amd.com
13311328Ssteve.reinhardt@amd.com        for (int i = 0; i < num_words; ++i)
13411328Ssteve.reinhardt@amd.com            mem[i] = gtoh(mem[i]);
13511328Ssteve.reinhardt@amd.com
13611328Ssteve.reinhardt@amd.com        if (traceData)
13711328Ssteve.reinhardt@amd.com            traceData->setData(mem[0]);
13811328Ssteve.reinhardt@amd.com    }
13911328Ssteve.reinhardt@amd.com    return fault;
14011328Ssteve.reinhardt@amd.com}
14111328Ssteve.reinhardt@amd.com
1428442Sgblack@eecs.umich.edutemplate <class XC>
1438442Sgblack@eecs.umich.eduFault
1448442Sgblack@eecs.umich.eduwriteMemTiming(XC *xc, Trace::InstRecord *traceData, uint64_t mem,
14511608Snikos.nikoleris@arm.com               unsigned dataSize, Addr addr, Request::Flags flags,
14611608Snikos.nikoleris@arm.com               uint64_t *res)
1478442Sgblack@eecs.umich.edu{
1488442Sgblack@eecs.umich.edu    if (traceData) {
1498442Sgblack@eecs.umich.edu        traceData->setData(mem);
1508442Sgblack@eecs.umich.edu    }
1518442Sgblack@eecs.umich.edu    mem = TheISA::htog(mem);
1528444Sgblack@eecs.umich.edu    return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res);
1538442Sgblack@eecs.umich.edu}
1548442Sgblack@eecs.umich.edu
15511328Ssteve.reinhardt@amd.comtemplate <class XC, size_t N>
15611328Ssteve.reinhardt@amd.comFault
15711328Ssteve.reinhardt@amd.comwriteMemTiming(XC *xc, Trace::InstRecord *traceData,
15811328Ssteve.reinhardt@amd.com               std::array<uint64_t, N> &mem, unsigned dataSize,
15911328Ssteve.reinhardt@amd.com               Addr addr, unsigned flags, uint64_t *res)
16011328Ssteve.reinhardt@amd.com{
16111328Ssteve.reinhardt@amd.com    assert(dataSize >= 8);
16211328Ssteve.reinhardt@amd.com    assert((dataSize % 8) == 0);
16311328Ssteve.reinhardt@amd.com
16411328Ssteve.reinhardt@amd.com    if (traceData) {
16511328Ssteve.reinhardt@amd.com        traceData->setData(mem[0]);
16611328Ssteve.reinhardt@amd.com    }
16711328Ssteve.reinhardt@amd.com
16811328Ssteve.reinhardt@amd.com    int num_words = dataSize / 8;
16911328Ssteve.reinhardt@amd.com    assert(num_words <= N);
17011328Ssteve.reinhardt@amd.com
17111328Ssteve.reinhardt@amd.com    for (int i = 0; i < num_words; ++i)
17211328Ssteve.reinhardt@amd.com        mem[i] = htog(mem[i]);
17311328Ssteve.reinhardt@amd.com
17411328Ssteve.reinhardt@amd.com    return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res);
17511328Ssteve.reinhardt@amd.com}
17611328Ssteve.reinhardt@amd.com
1778442Sgblack@eecs.umich.edutemplate <class XC>
1788442Sgblack@eecs.umich.eduFault
1798442Sgblack@eecs.umich.eduwriteMemAtomic(XC *xc, Trace::InstRecord *traceData, uint64_t mem,
18011608Snikos.nikoleris@arm.com               unsigned dataSize, Addr addr, Request::Flags flags,
18111608Snikos.nikoleris@arm.com               uint64_t *res)
1828442Sgblack@eecs.umich.edu{
18311301Ssteve.reinhardt@amd.com    if (traceData) {
18411301Ssteve.reinhardt@amd.com        traceData->setData(mem);
18511301Ssteve.reinhardt@amd.com    }
18611301Ssteve.reinhardt@amd.com    uint64_t host_mem = TheISA::htog(mem);
18711301Ssteve.reinhardt@amd.com    Fault fault =
18811301Ssteve.reinhardt@amd.com          xc->writeMem((uint8_t *)&host_mem, dataSize, addr, flags, res);
1898442Sgblack@eecs.umich.edu    if (fault == NoFault && res != NULL) {
1908442Sgblack@eecs.umich.edu        *res = gtoh(*res);
1918442Sgblack@eecs.umich.edu    }
1928442Sgblack@eecs.umich.edu    return fault;
1938442Sgblack@eecs.umich.edu}
1948442Sgblack@eecs.umich.edu
19511328Ssteve.reinhardt@amd.comtemplate <class XC, size_t N>
19611328Ssteve.reinhardt@amd.comFault
19711328Ssteve.reinhardt@amd.comwriteMemAtomic(XC *xc, Trace::InstRecord *traceData,
19811328Ssteve.reinhardt@amd.com               std::array<uint64_t, N> &mem, unsigned dataSize,
19911328Ssteve.reinhardt@amd.com               Addr addr, unsigned flags, uint64_t *res)
20011328Ssteve.reinhardt@amd.com{
20111328Ssteve.reinhardt@amd.com    if (traceData) {
20211328Ssteve.reinhardt@amd.com        traceData->setData(mem[0]);
20311328Ssteve.reinhardt@amd.com    }
20411328Ssteve.reinhardt@amd.com
20511328Ssteve.reinhardt@amd.com    int num_words = dataSize / 8;
20611328Ssteve.reinhardt@amd.com    assert(num_words <= N);
20711328Ssteve.reinhardt@amd.com
20811328Ssteve.reinhardt@amd.com    for (int i = 0; i < num_words; ++i)
20911328Ssteve.reinhardt@amd.com        mem[i] = htog(mem[i]);
21011328Ssteve.reinhardt@amd.com
21111328Ssteve.reinhardt@amd.com    Fault fault = xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res);
21211328Ssteve.reinhardt@amd.com
21311328Ssteve.reinhardt@amd.com    if (fault == NoFault && res != NULL) {
21411328Ssteve.reinhardt@amd.com        *res = gtoh(*res);
21511328Ssteve.reinhardt@amd.com    }
21611328Ssteve.reinhardt@amd.com
21711328Ssteve.reinhardt@amd.com    return fault;
21811328Ssteve.reinhardt@amd.com}
21911328Ssteve.reinhardt@amd.com
2208442Sgblack@eecs.umich.edu}
2218442Sgblack@eecs.umich.edu
2228442Sgblack@eecs.umich.edu#endif
223