memhelpers.hh revision 11328
113531Sjairo.balart@metempsy.com/*
213531Sjairo.balart@metempsy.com * Copyright (c) 2011 Google
313531Sjairo.balart@metempsy.com * Copyright (c) 2015 Advanced Micro Devices, Inc.
413531Sjairo.balart@metempsy.com * All rights reserved.
513531Sjairo.balart@metempsy.com *
613531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
713531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
813531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
913531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
1013531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
1113531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
1213531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
1313531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
1413531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
1513531Sjairo.balart@metempsy.com * this software without specific prior written permission.
1613531Sjairo.balart@metempsy.com *
1713531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1813531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1913531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2013531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2113531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2213531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2313531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2413531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2513531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2613531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2713531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2813531Sjairo.balart@metempsy.com *
2913531Sjairo.balart@metempsy.com * Authors: Gabe Black
3013531Sjairo.balart@metempsy.com */
3113531Sjairo.balart@metempsy.com
3213531Sjairo.balart@metempsy.com#ifndef __ARCH_X86_MEMHELPERS_HH__
3313531Sjairo.balart@metempsy.com#define __ARCH_X86_MEMHELPERS_HH__
3413531Sjairo.balart@metempsy.com
3513531Sjairo.balart@metempsy.com#include <array>
3613531Sjairo.balart@metempsy.com
3713531Sjairo.balart@metempsy.com#include "base/types.hh"
3813756Sjairo.balart@metempsy.com#include "sim/byteswap.hh"
3913531Sjairo.balart@metempsy.com#include "sim/insttracer.hh"
4013531Sjairo.balart@metempsy.com
4113531Sjairo.balart@metempsy.comnamespace X86ISA
4213531Sjairo.balart@metempsy.com{
4313531Sjairo.balart@metempsy.com
4413531Sjairo.balart@metempsy.com/// Initiate a read from memory in timing mode.
4513531Sjairo.balart@metempsy.comtemplate <class XC>
4613531Sjairo.balart@metempsy.comFault
4713531Sjairo.balart@metempsy.cominitiateMemRead(XC *xc, Trace::InstRecord *traceData, Addr addr,
4813531Sjairo.balart@metempsy.com                unsigned dataSize, unsigned flags)
4913531Sjairo.balart@metempsy.com{
5013531Sjairo.balart@metempsy.com    return xc->initiateMemRead(addr, dataSize, flags);
5113531Sjairo.balart@metempsy.com}
5213531Sjairo.balart@metempsy.com
5313531Sjairo.balart@metempsy.comstatic void
5413531Sjairo.balart@metempsy.comgetMem(PacketPtr pkt, uint64_t &mem, unsigned dataSize,
5513531Sjairo.balart@metempsy.com       Trace::InstRecord *traceData)
5613531Sjairo.balart@metempsy.com{
5713531Sjairo.balart@metempsy.com    switch (dataSize) {
5813531Sjairo.balart@metempsy.com      case 1:
5913756Sjairo.balart@metempsy.com        mem = pkt->get<uint8_t>();
6013531Sjairo.balart@metempsy.com        break;
6113531Sjairo.balart@metempsy.com      case 2:
6213531Sjairo.balart@metempsy.com        mem = pkt->get<uint16_t>();
6313531Sjairo.balart@metempsy.com        break;
6413531Sjairo.balart@metempsy.com      case 4:
6513531Sjairo.balart@metempsy.com        mem = pkt->get<uint32_t>();
6613756Sjairo.balart@metempsy.com        break;
6713531Sjairo.balart@metempsy.com      case 8:
6813531Sjairo.balart@metempsy.com        mem = pkt->get<uint64_t>();
6913531Sjairo.balart@metempsy.com        break;
7013531Sjairo.balart@metempsy.com      default:
7113531Sjairo.balart@metempsy.com        panic("Unhandled size in getMem.\n");
7213531Sjairo.balart@metempsy.com    }
7313531Sjairo.balart@metempsy.com    if (traceData)
7413531Sjairo.balart@metempsy.com        traceData->setData(mem);
7513531Sjairo.balart@metempsy.com}
7613531Sjairo.balart@metempsy.com
7713531Sjairo.balart@metempsy.com
7813531Sjairo.balart@metempsy.comtemplate <size_t N>
7913531Sjairo.balart@metempsy.comvoid
8013531Sjairo.balart@metempsy.comgetMem(PacketPtr pkt, std::array<uint64_t, N> &mem, unsigned dataSize,
8113531Sjairo.balart@metempsy.com       Trace::InstRecord *traceData)
8213531Sjairo.balart@metempsy.com{
8313531Sjairo.balart@metempsy.com    assert(dataSize >= 8);
8413531Sjairo.balart@metempsy.com    assert((dataSize % 8) == 0);
8513531Sjairo.balart@metempsy.com
8613531Sjairo.balart@metempsy.com    int num_words = dataSize / 8;
8713531Sjairo.balart@metempsy.com    assert(num_words <= N);
8813531Sjairo.balart@metempsy.com
8913531Sjairo.balart@metempsy.com    auto pkt_data = pkt->getConstPtr<const uint64_t>();
9013531Sjairo.balart@metempsy.com    for (int i = 0; i < num_words; ++i)
9113531Sjairo.balart@metempsy.com        mem[i] = gtoh(pkt_data[i]);
9213531Sjairo.balart@metempsy.com
9313531Sjairo.balart@metempsy.com    // traceData record only has space for 64 bits, so we just record
9413531Sjairo.balart@metempsy.com    // the first qword
9513531Sjairo.balart@metempsy.com    if (traceData)
9613531Sjairo.balart@metempsy.com        traceData->setData(mem[0]);
9713531Sjairo.balart@metempsy.com}
9813531Sjairo.balart@metempsy.com
9913531Sjairo.balart@metempsy.com
10013531Sjairo.balart@metempsy.comtemplate <class XC>
10113531Sjairo.balart@metempsy.comFault
10213756Sjairo.balart@metempsy.comreadMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, uint64_t &mem,
10313531Sjairo.balart@metempsy.com        unsigned dataSize, unsigned flags)
10413756Sjairo.balart@metempsy.com{
10513531Sjairo.balart@metempsy.com    memset(&mem, 0, sizeof(mem));
10613531Sjairo.balart@metempsy.com    Fault fault = xc->readMem(addr, (uint8_t *)&mem, dataSize, flags);
10713531Sjairo.balart@metempsy.com    if (fault == NoFault) {
10813531Sjairo.balart@metempsy.com        // If LE to LE, this is a nop, if LE to BE, the actual data ends up
10913531Sjairo.balart@metempsy.com        // in the right place because the LSBs where at the low addresses on
11013756Sjairo.balart@metempsy.com        // access. This doesn't work for BE guests.
11113531Sjairo.balart@metempsy.com        mem = gtoh(mem);
11213756Sjairo.balart@metempsy.com        if (traceData)
11313531Sjairo.balart@metempsy.com            traceData->setData(mem);
11413756Sjairo.balart@metempsy.com    }
11513531Sjairo.balart@metempsy.com    return fault;
11613756Sjairo.balart@metempsy.com}
11713531Sjairo.balart@metempsy.com
11813531Sjairo.balart@metempsy.comtemplate <class XC, size_t N>
11913531Sjairo.balart@metempsy.comFault
12013531Sjairo.balart@metempsy.comreadMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr,
12113531Sjairo.balart@metempsy.com              std::array<uint64_t, N> &mem, unsigned dataSize,
12213690Sjairo.balart@metempsy.com              unsigned flags)
12313690Sjairo.balart@metempsy.com{
12413690Sjairo.balart@metempsy.com    assert(dataSize >= 8);
12513690Sjairo.balart@metempsy.com    assert((dataSize % 8) == 0);
12613690Sjairo.balart@metempsy.com
12713690Sjairo.balart@metempsy.com    Fault fault = xc->readMem(addr, (uint8_t *)&mem, dataSize, flags);
12813690Sjairo.balart@metempsy.com
12913690Sjairo.balart@metempsy.com    if (fault == NoFault) {
13013690Sjairo.balart@metempsy.com        int num_words = dataSize / 8;
13113690Sjairo.balart@metempsy.com        assert(num_words <= N);
13213690Sjairo.balart@metempsy.com
13313690Sjairo.balart@metempsy.com        for (int i = 0; i < num_words; ++i)
13413690Sjairo.balart@metempsy.com            mem[i] = gtoh(mem[i]);
13513690Sjairo.balart@metempsy.com
13613690Sjairo.balart@metempsy.com        if (traceData)
13713690Sjairo.balart@metempsy.com            traceData->setData(mem[0]);
13813690Sjairo.balart@metempsy.com    }
13913690Sjairo.balart@metempsy.com    return fault;
14013531Sjairo.balart@metempsy.com}
14113531Sjairo.balart@metempsy.com
14213531Sjairo.balart@metempsy.comtemplate <class XC>
14313531Sjairo.balart@metempsy.comFault
14413531Sjairo.balart@metempsy.comwriteMemTiming(XC *xc, Trace::InstRecord *traceData, uint64_t mem,
14513531Sjairo.balart@metempsy.com        unsigned dataSize, Addr addr, unsigned flags, uint64_t *res)
14613531Sjairo.balart@metempsy.com{
14713531Sjairo.balart@metempsy.com    if (traceData) {
14813531Sjairo.balart@metempsy.com        traceData->setData(mem);
14913531Sjairo.balart@metempsy.com    }
15013531Sjairo.balart@metempsy.com    mem = TheISA::htog(mem);
15113531Sjairo.balart@metempsy.com    return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res);
15213690Sjairo.balart@metempsy.com}
15313531Sjairo.balart@metempsy.com
15413690Sjairo.balart@metempsy.comtemplate <class XC, size_t N>
15513690Sjairo.balart@metempsy.comFault
15613690Sjairo.balart@metempsy.comwriteMemTiming(XC *xc, Trace::InstRecord *traceData,
15713690Sjairo.balart@metempsy.com               std::array<uint64_t, N> &mem, unsigned dataSize,
15813690Sjairo.balart@metempsy.com               Addr addr, unsigned flags, uint64_t *res)
15913690Sjairo.balart@metempsy.com{
16013690Sjairo.balart@metempsy.com    assert(dataSize >= 8);
16113690Sjairo.balart@metempsy.com    assert((dataSize % 8) == 0);
16213690Sjairo.balart@metempsy.com
16313690Sjairo.balart@metempsy.com    if (traceData) {
16413690Sjairo.balart@metempsy.com        traceData->setData(mem[0]);
16513690Sjairo.balart@metempsy.com    }
16613690Sjairo.balart@metempsy.com
16713756Sjairo.balart@metempsy.com    int num_words = dataSize / 8;
16813531Sjairo.balart@metempsy.com    assert(num_words <= N);
16913756Sjairo.balart@metempsy.com
17013531Sjairo.balart@metempsy.com    for (int i = 0; i < num_words; ++i)
17113531Sjairo.balart@metempsy.com        mem[i] = htog(mem[i]);
17213531Sjairo.balart@metempsy.com
17313531Sjairo.balart@metempsy.com    return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res);
17413531Sjairo.balart@metempsy.com}
17513531Sjairo.balart@metempsy.com
17613531Sjairo.balart@metempsy.comtemplate <class XC>
17713531Sjairo.balart@metempsy.comFault
17813531Sjairo.balart@metempsy.comwriteMemAtomic(XC *xc, Trace::InstRecord *traceData, uint64_t mem,
17913531Sjairo.balart@metempsy.com        unsigned dataSize, Addr addr, unsigned flags, uint64_t *res)
18013878Sgiacomo.travaglini@arm.com{
18113531Sjairo.balart@metempsy.com    if (traceData) {
18213690Sjairo.balart@metempsy.com        traceData->setData(mem);
18313690Sjairo.balart@metempsy.com    }
18413531Sjairo.balart@metempsy.com    uint64_t host_mem = TheISA::htog(mem);
18513756Sjairo.balart@metempsy.com    Fault fault =
18613756Sjairo.balart@metempsy.com          xc->writeMem((uint8_t *)&host_mem, dataSize, addr, flags, res);
18713756Sjairo.balart@metempsy.com    if (fault == NoFault && res != NULL) {
18813531Sjairo.balart@metempsy.com        *res = gtoh(*res);
18913756Sjairo.balart@metempsy.com    }
19013531Sjairo.balart@metempsy.com    return fault;
19113531Sjairo.balart@metempsy.com}
19213531Sjairo.balart@metempsy.com
19313531Sjairo.balart@metempsy.comtemplate <class XC, size_t N>
19413531Sjairo.balart@metempsy.comFault
19513756Sjairo.balart@metempsy.comwriteMemAtomic(XC *xc, Trace::InstRecord *traceData,
19613756Sjairo.balart@metempsy.com               std::array<uint64_t, N> &mem, unsigned dataSize,
19713690Sjairo.balart@metempsy.com               Addr addr, unsigned flags, uint64_t *res)
19813531Sjairo.balart@metempsy.com{
19913756Sjairo.balart@metempsy.com    if (traceData) {
20013756Sjairo.balart@metempsy.com        traceData->setData(mem[0]);
20113756Sjairo.balart@metempsy.com    }
20213531Sjairo.balart@metempsy.com
20313531Sjairo.balart@metempsy.com    int num_words = dataSize / 8;
20413756Sjairo.balart@metempsy.com    assert(num_words <= N);
20513756Sjairo.balart@metempsy.com
20613756Sjairo.balart@metempsy.com    for (int i = 0; i < num_words; ++i)
20713756Sjairo.balart@metempsy.com        mem[i] = htog(mem[i]);
20813690Sjairo.balart@metempsy.com
20913756Sjairo.balart@metempsy.com    Fault fault = xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res);
21013756Sjairo.balart@metempsy.com
21113756Sjairo.balart@metempsy.com    if (fault == NoFault && res != NULL) {
21213756Sjairo.balart@metempsy.com        *res = gtoh(*res);
21313756Sjairo.balart@metempsy.com    }
21413756Sjairo.balart@metempsy.com
21513531Sjairo.balart@metempsy.com    return fault;
21613531Sjairo.balart@metempsy.com}
21713531Sjairo.balart@metempsy.com
218}
219
220#endif
221