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