port_proxy.hh revision 14196
18706Sandreas.hansson@arm.com/* 212522Sandreas.sandberg@arm.com * Copyright (c) 2011-2013, 2018 ARM Limited 38706Sandreas.hansson@arm.com * All rights reserved 48706Sandreas.hansson@arm.com * 58706Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68706Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78706Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88706Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98706Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108706Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118706Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128706Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138706Sandreas.hansson@arm.com * 148706Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 158706Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 168706Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 178706Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 188706Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 198706Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 208706Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 218706Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 228706Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 238706Sandreas.hansson@arm.com * this software without specific prior written permission. 248706Sandreas.hansson@arm.com * 258706Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 268706Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 278706Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 288706Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 298706Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 308706Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 318706Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 328706Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 338706Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 348706Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 358706Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 368706Sandreas.hansson@arm.com * 378706Sandreas.hansson@arm.com * Authors: Andreas Hansson 388706Sandreas.hansson@arm.com */ 398706Sandreas.hansson@arm.com 408706Sandreas.hansson@arm.com/** 418706Sandreas.hansson@arm.com * @file 428706Sandreas.hansson@arm.com * PortProxy Object Declaration. 438706Sandreas.hansson@arm.com * 448853Sandreas.hansson@arm.com * Port proxies are used when non-structural entities need access to 458853Sandreas.hansson@arm.com * the memory system (or structural entities that want to peak into 468853Sandreas.hansson@arm.com * the memory system without making a real memory access). 478853Sandreas.hansson@arm.com * 488853Sandreas.hansson@arm.com * Proxy objects replace the previous FunctionalPort, TranslatingPort 498853Sandreas.hansson@arm.com * and VirtualPort objects, which provided the same functionality as 508853Sandreas.hansson@arm.com * the proxies, but were instances of ports not corresponding to real 518853Sandreas.hansson@arm.com * structural ports of the simulated system. Via the port proxies all 528853Sandreas.hansson@arm.com * the accesses go through an actual port (either the system port, 538853Sandreas.hansson@arm.com * e.g. for processes or initialisation, or a the data port of the 548853Sandreas.hansson@arm.com * CPU, e.g. for threads) and thus are transparent to a potentially 558706Sandreas.hansson@arm.com * distributed memory and automatically adhere to the memory map of 568706Sandreas.hansson@arm.com * the system. 578706Sandreas.hansson@arm.com */ 588706Sandreas.hansson@arm.com 598706Sandreas.hansson@arm.com#ifndef __MEM_PORT_PROXY_HH__ 608706Sandreas.hansson@arm.com#define __MEM_PORT_PROXY_HH__ 618706Sandreas.hansson@arm.com 6214196Sgabeblack@google.com#include <functional> 6314012Sgabeblack@google.com#include <limits> 6414012Sgabeblack@google.com 658706Sandreas.hansson@arm.com#include "mem/port.hh" 668706Sandreas.hansson@arm.com#include "sim/byteswap.hh" 678706Sandreas.hansson@arm.com 688706Sandreas.hansson@arm.com/** 6914196Sgabeblack@google.com * This object is a proxy for a port or other object which implements the 7014196Sgabeblack@google.com * functional response protocol, to be used for debug accesses. 718706Sandreas.hansson@arm.com * 728706Sandreas.hansson@arm.com * This proxy object is used when non structural entities 738706Sandreas.hansson@arm.com * (e.g. thread contexts, object file loaders) need access to the 748706Sandreas.hansson@arm.com * memory system. It calls the corresponding functions on the underlying 7514196Sgabeblack@google.com * protocol, and provides templatized convenience access functions. 768706Sandreas.hansson@arm.com * 778706Sandreas.hansson@arm.com * The addresses are interpreted as physical addresses. 788706Sandreas.hansson@arm.com * 798706Sandreas.hansson@arm.com * @sa SETranslatingProxy 808706Sandreas.hansson@arm.com * @sa FSTranslatingProxy 818706Sandreas.hansson@arm.com */ 8214196Sgabeblack@google.comclass PortProxy : FunctionalRequestProtocol 838706Sandreas.hansson@arm.com{ 8414196Sgabeblack@google.com public: 8514196Sgabeblack@google.com typedef std::function<void(PacketPtr pkt)> SendFunctionalFunc; 8614196Sgabeblack@google.com 878853Sandreas.hansson@arm.com private: 8814196Sgabeblack@google.com SendFunctionalFunc sendFunctional; 898706Sandreas.hansson@arm.com 909814Sandreas.hansson@arm.com /** Granularity of any transactions issued through this proxy. */ 919814Sandreas.hansson@arm.com const unsigned int _cacheLineSize; 929814Sandreas.hansson@arm.com 9314196Sgabeblack@google.com void 9414196Sgabeblack@google.com recvFunctionalSnoop(PacketPtr pkt) override 9514196Sgabeblack@google.com { 9614196Sgabeblack@google.com // Since port proxies aren't anyone else's peer, they should never 9714196Sgabeblack@google.com // receive snoops. 9814196Sgabeblack@google.com panic("Port proxies should never receive snoops."); 9914196Sgabeblack@google.com } 10014196Sgabeblack@google.com 1018706Sandreas.hansson@arm.com public: 10214196Sgabeblack@google.com PortProxy(SendFunctionalFunc func, unsigned int cacheLineSize) : 10314196Sgabeblack@google.com sendFunctional(func), _cacheLineSize(cacheLineSize) 10414196Sgabeblack@google.com {} 10514196Sgabeblack@google.com PortProxy(const MasterPort &port, unsigned int cacheLineSize) : 10614196Sgabeblack@google.com sendFunctional([&port](PacketPtr pkt)->void { 10714196Sgabeblack@google.com port.sendFunctional(pkt); 10814196Sgabeblack@google.com }), _cacheLineSize(cacheLineSize) 10913893Sgabeblack@google.com {} 1108706Sandreas.hansson@arm.com virtual ~PortProxy() { } 1118706Sandreas.hansson@arm.com 1128706Sandreas.hansson@arm.com 1138706Sandreas.hansson@arm.com 11414008Sgabeblack@google.com /** Fixed functionality for use in base classes. */ 11512532Sandreas.sandberg@arm.com 11612532Sandreas.sandberg@arm.com /** 11712532Sandreas.sandberg@arm.com * Read size bytes memory at physical address and store in p. 11812532Sandreas.sandberg@arm.com */ 11912532Sandreas.sandberg@arm.com void readBlobPhys(Addr addr, Request::Flags flags, 12014009Sgabeblack@google.com void *p, int size) const; 12112532Sandreas.sandberg@arm.com 12212532Sandreas.sandberg@arm.com /** 12312532Sandreas.sandberg@arm.com * Write size bytes from p to physical address. 12412532Sandreas.sandberg@arm.com */ 12512532Sandreas.sandberg@arm.com void writeBlobPhys(Addr addr, Request::Flags flags, 12614009Sgabeblack@google.com const void *p, int size) const; 12712532Sandreas.sandberg@arm.com 12812532Sandreas.sandberg@arm.com /** 12912532Sandreas.sandberg@arm.com * Fill size bytes starting at physical addr with byte value val. 13012532Sandreas.sandberg@arm.com */ 13112532Sandreas.sandberg@arm.com void memsetBlobPhys(Addr addr, Request::Flags flags, 13212532Sandreas.sandberg@arm.com uint8_t v, int size) const; 1338706Sandreas.hansson@arm.com 13414008Sgabeblack@google.com 13514008Sgabeblack@google.com 13614008Sgabeblack@google.com /** Methods to override in base classes */ 13714008Sgabeblack@google.com 13814008Sgabeblack@google.com /** 13914008Sgabeblack@google.com * Read size bytes memory at address and store in p. 14014008Sgabeblack@google.com * Returns true on success and false on failure. 14114008Sgabeblack@google.com */ 14214008Sgabeblack@google.com virtual bool 14314009Sgabeblack@google.com tryReadBlob(Addr addr, void *p, int size) const 14414008Sgabeblack@google.com { 14514008Sgabeblack@google.com readBlobPhys(addr, 0, p, size); 14614008Sgabeblack@google.com return true; 14714008Sgabeblack@google.com } 14814008Sgabeblack@google.com 14914008Sgabeblack@google.com /** 15014008Sgabeblack@google.com * Write size bytes from p to address. 15114008Sgabeblack@google.com * Returns true on success and false on failure. 15214008Sgabeblack@google.com */ 15314008Sgabeblack@google.com virtual bool 15414009Sgabeblack@google.com tryWriteBlob(Addr addr, const void *p, int size) const 15514008Sgabeblack@google.com { 15614008Sgabeblack@google.com writeBlobPhys(addr, 0, p, size); 15714008Sgabeblack@google.com return true; 15814008Sgabeblack@google.com } 15914008Sgabeblack@google.com 16014008Sgabeblack@google.com /** 16114008Sgabeblack@google.com * Fill size bytes starting at addr with byte value val. 16214008Sgabeblack@google.com * Returns true on success and false on failure. 16314008Sgabeblack@google.com */ 16414008Sgabeblack@google.com virtual bool 16514008Sgabeblack@google.com tryMemsetBlob(Addr addr, uint8_t val, int size) const 16614008Sgabeblack@google.com { 16714008Sgabeblack@google.com memsetBlobPhys(addr, 0, val, size); 16814008Sgabeblack@google.com return true; 16914008Sgabeblack@google.com } 17014008Sgabeblack@google.com 17114008Sgabeblack@google.com 17214008Sgabeblack@google.com 17314008Sgabeblack@google.com /** Higher level interfaces based on the above. */ 17414008Sgabeblack@google.com 17514008Sgabeblack@google.com /** 17614008Sgabeblack@google.com * Same as tryReadBlob, but insists on success. 17714008Sgabeblack@google.com */ 17814008Sgabeblack@google.com void 17914009Sgabeblack@google.com readBlob(Addr addr, void *p, int size) const 18014008Sgabeblack@google.com { 18114008Sgabeblack@google.com if (!tryReadBlob(addr, p, size)) 18214008Sgabeblack@google.com fatal("readBlob(%#x, ...) failed", addr); 18314008Sgabeblack@google.com } 18414008Sgabeblack@google.com 18514008Sgabeblack@google.com /** 18614008Sgabeblack@google.com * Same as tryWriteBlob, but insists on success. 18714008Sgabeblack@google.com */ 18814008Sgabeblack@google.com void 18914009Sgabeblack@google.com writeBlob(Addr addr, const void *p, int size) const 19014008Sgabeblack@google.com { 19114008Sgabeblack@google.com if (!tryWriteBlob(addr, p, size)) 19214008Sgabeblack@google.com fatal("writeBlob(%#x, ...) failed", addr); 19314008Sgabeblack@google.com } 19414008Sgabeblack@google.com 19514008Sgabeblack@google.com /** 19614008Sgabeblack@google.com * Same as tryMemsetBlob, but insists on success. 19714008Sgabeblack@google.com */ 19814008Sgabeblack@google.com void 19914008Sgabeblack@google.com memsetBlob(Addr addr, uint8_t v, int size) const 20014008Sgabeblack@google.com { 20114008Sgabeblack@google.com if (!tryMemsetBlob(addr, v, size)) 20214008Sgabeblack@google.com fatal("memsetBlob(%#x, ...) failed", addr); 20314008Sgabeblack@google.com } 20414008Sgabeblack@google.com 2058706Sandreas.hansson@arm.com /** 2068706Sandreas.hansson@arm.com * Read sizeof(T) bytes from address and return as object T. 2078706Sandreas.hansson@arm.com */ 2088706Sandreas.hansson@arm.com template <typename T> 2098861Sandreas.hansson@arm.com T read(Addr address) const; 2108706Sandreas.hansson@arm.com 2118706Sandreas.hansson@arm.com /** 2128706Sandreas.hansson@arm.com * Write object T to address. Writes sizeof(T) bytes. 2138706Sandreas.hansson@arm.com */ 2148706Sandreas.hansson@arm.com template <typename T> 21514011Sgabeblack@google.com void write(Addr address, const T &data) const; 2168706Sandreas.hansson@arm.com 21712522Sandreas.sandberg@arm.com /** 21812522Sandreas.sandberg@arm.com * Read sizeof(T) bytes from address and return as object T. 21913893Sgabeblack@google.com * Performs endianness conversion from the selected guest to host order. 22012522Sandreas.sandberg@arm.com */ 22112522Sandreas.sandberg@arm.com template <typename T> 22213893Sgabeblack@google.com T read(Addr address, ByteOrder guest_byte_order) const; 22312522Sandreas.sandberg@arm.com 22412522Sandreas.sandberg@arm.com /** 22512522Sandreas.sandberg@arm.com * Write object T to address. Writes sizeof(T) bytes. 22613893Sgabeblack@google.com * Performs endianness conversion from host to the selected guest order. 22712522Sandreas.sandberg@arm.com */ 22812522Sandreas.sandberg@arm.com template <typename T> 22913893Sgabeblack@google.com void write(Addr address, T data, ByteOrder guest_byte_order) const; 23014008Sgabeblack@google.com 23114008Sgabeblack@google.com /** 23214008Sgabeblack@google.com * Write the string str into guest memory at address addr. 23314008Sgabeblack@google.com * Returns true on success and false on failure. 23414008Sgabeblack@google.com */ 23514008Sgabeblack@google.com bool tryWriteString(Addr addr, const char *str) const; 23614008Sgabeblack@google.com 23714008Sgabeblack@google.com /** 23814008Sgabeblack@google.com * Same as tryWriteString, but insists on success. 23914008Sgabeblack@google.com */ 24014008Sgabeblack@google.com void 24114008Sgabeblack@google.com writeString(Addr addr, const char *str) const 24214008Sgabeblack@google.com { 24314008Sgabeblack@google.com if (!tryWriteString(addr, str)) 24414008Sgabeblack@google.com fatal("writeString(%#x, ...) failed", addr); 24514008Sgabeblack@google.com } 24614008Sgabeblack@google.com 24714008Sgabeblack@google.com /** 24814008Sgabeblack@google.com * Reads the string at guest address addr into the std::string str. 24914008Sgabeblack@google.com * Returns true on success and false on failure. 25014008Sgabeblack@google.com */ 25114008Sgabeblack@google.com bool tryReadString(std::string &str, Addr addr) const; 25214008Sgabeblack@google.com 25314008Sgabeblack@google.com /** 25414008Sgabeblack@google.com * Same as tryReadString, but insists on success. 25514008Sgabeblack@google.com */ 25614008Sgabeblack@google.com void 25714008Sgabeblack@google.com readString(std::string &str, Addr addr) const 25814008Sgabeblack@google.com { 25914008Sgabeblack@google.com if (!tryReadString(str, addr)) 26014008Sgabeblack@google.com fatal("readString(%#x, ...) failed", addr); 26114008Sgabeblack@google.com } 26214012Sgabeblack@google.com 26314012Sgabeblack@google.com /** 26414012Sgabeblack@google.com * Reads the string at guest address addr into the char * str, reading up 26514012Sgabeblack@google.com * to maxlen characters. The last character read is always a nul 26614012Sgabeblack@google.com * terminator. Returns true on success and false on failure. 26714012Sgabeblack@google.com */ 26814012Sgabeblack@google.com bool tryReadString(char *str, Addr addr, size_t maxlen) const; 26914012Sgabeblack@google.com 27014012Sgabeblack@google.com /** 27114012Sgabeblack@google.com * Same as tryReadString, but insists on success. 27214012Sgabeblack@google.com */ 27314012Sgabeblack@google.com void 27414012Sgabeblack@google.com readString(char *str, Addr addr, size_t maxlen) const 27514012Sgabeblack@google.com { 27614012Sgabeblack@google.com if (!tryReadString(str, addr, maxlen)) 27714012Sgabeblack@google.com fatal("readString(%#x, ...) failed", addr); 27814012Sgabeblack@google.com } 2798706Sandreas.hansson@arm.com}; 2808706Sandreas.hansson@arm.com 2818706Sandreas.hansson@arm.com 2828706Sandreas.hansson@arm.comtemplate <typename T> 2838706Sandreas.hansson@arm.comT 2848861Sandreas.hansson@arm.comPortProxy::read(Addr address) const 2858706Sandreas.hansson@arm.com{ 2868706Sandreas.hansson@arm.com T data; 28714009Sgabeblack@google.com readBlob(address, &data, sizeof(T)); 2888706Sandreas.hansson@arm.com return data; 2898706Sandreas.hansson@arm.com} 2908706Sandreas.hansson@arm.com 2918706Sandreas.hansson@arm.comtemplate <typename T> 2928706Sandreas.hansson@arm.comvoid 29314011Sgabeblack@google.comPortProxy::write(Addr address, const T &data) const 2948706Sandreas.hansson@arm.com{ 29514009Sgabeblack@google.com writeBlob(address, &data, sizeof(T)); 2968706Sandreas.hansson@arm.com} 2978706Sandreas.hansson@arm.com 29812522Sandreas.sandberg@arm.comtemplate <typename T> 29912522Sandreas.sandberg@arm.comT 30013893Sgabeblack@google.comPortProxy::read(Addr address, ByteOrder byte_order) const 30112522Sandreas.sandberg@arm.com{ 30212522Sandreas.sandberg@arm.com T data; 30314009Sgabeblack@google.com readBlob(address, &data, sizeof(T)); 30412522Sandreas.sandberg@arm.com return gtoh(data, byte_order); 30512522Sandreas.sandberg@arm.com} 30612522Sandreas.sandberg@arm.com 30712522Sandreas.sandberg@arm.comtemplate <typename T> 30812522Sandreas.sandberg@arm.comvoid 30913893Sgabeblack@google.comPortProxy::write(Addr address, T data, ByteOrder byte_order) const 31012522Sandreas.sandberg@arm.com{ 31112522Sandreas.sandberg@arm.com data = htog(data, byte_order); 31214009Sgabeblack@google.com writeBlob(address, &data, sizeof(T)); 31312522Sandreas.sandberg@arm.com} 31412522Sandreas.sandberg@arm.com 3158706Sandreas.hansson@arm.com#endif // __MEM_PORT_PROXY_HH__ 316