port_proxy.hh revision 14012:1bdf42ed6add
18706Sandreas.hansson@arm.com/* 28706Sandreas.hansson@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. 136892SBrad.Beckmann@amd.com * 146892SBrad.Beckmann@amd.com * Redistribution and use in source and binary forms, with or without 156892SBrad.Beckmann@amd.com * modification, are permitted provided that the following conditions are 166892SBrad.Beckmann@amd.com * met: redistributions of source code must retain the above copyright 176892SBrad.Beckmann@amd.com * notice, this list of conditions and the following disclaimer; 186892SBrad.Beckmann@amd.com * redistributions in binary form must reproduce the above copyright 196892SBrad.Beckmann@amd.com * notice, this list of conditions and the following disclaimer in the 206892SBrad.Beckmann@amd.com * documentation and/or other materials provided with the distribution; 216892SBrad.Beckmann@amd.com * neither the name of the copyright holders nor the names of its 226892SBrad.Beckmann@amd.com * contributors may be used to endorse or promote products derived from 236892SBrad.Beckmann@amd.com * this software without specific prior written permission. 246892SBrad.Beckmann@amd.com * 256892SBrad.Beckmann@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266892SBrad.Beckmann@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276892SBrad.Beckmann@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286892SBrad.Beckmann@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 296892SBrad.Beckmann@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 306892SBrad.Beckmann@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316892SBrad.Beckmann@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326892SBrad.Beckmann@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336892SBrad.Beckmann@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346892SBrad.Beckmann@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356892SBrad.Beckmann@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366892SBrad.Beckmann@amd.com * 376892SBrad.Beckmann@amd.com * Authors: Andreas Hansson 386892SBrad.Beckmann@amd.com */ 396892SBrad.Beckmann@amd.com 406892SBrad.Beckmann@amd.com/** 416892SBrad.Beckmann@amd.com * @file 427563SBrad.Beckmann@amd.com * PortProxy Object Declaration. 436892SBrad.Beckmann@amd.com * 446892SBrad.Beckmann@amd.com * Port proxies are used when non-structural entities need access to 456892SBrad.Beckmann@amd.com * the memory system (or structural entities that want to peak into 4610118Snilay@cs.wisc.edu * the memory system without making a real memory access). 4710118Snilay@cs.wisc.edu * 4810524Snilay@cs.wisc.edu * Proxy objects replace the previous FunctionalPort, TranslatingPort 4910118Snilay@cs.wisc.edu * and VirtualPort objects, which provided the same functionality as 506892SBrad.Beckmann@amd.com * the proxies, but were instances of ports not corresponding to real 517538SBrad.Beckmann@amd.com * structural ports of the simulated system. Via the port proxies all 528939SBrad.Beckmann@amd.com * the accesses go through an actual port (either the system port, 538939SBrad.Beckmann@amd.com * e.g. for processes or initialisation, or a the data port of the 548939SBrad.Beckmann@amd.com * CPU, e.g. for threads) and thus are transparent to a potentially 559791Sakash.bagdia@arm.com * distributed memory and automatically adhere to the memory map of 569791Sakash.bagdia@arm.com * the system. 579791Sakash.bagdia@arm.com */ 589791Sakash.bagdia@arm.com 5910525Snilay@cs.wisc.edu#ifndef __MEM_PORT_PROXY_HH__ 6010525Snilay@cs.wisc.edu#define __MEM_PORT_PROXY_HH__ 6110525Snilay@cs.wisc.edu 629841Snilay@cs.wisc.edu#include <limits> 639841Snilay@cs.wisc.edu 649841Snilay@cs.wisc.edu#include "mem/port.hh" 659841Snilay@cs.wisc.edu#include "sim/byteswap.hh" 669841Snilay@cs.wisc.edu 677538SBrad.Beckmann@amd.com/** 687538SBrad.Beckmann@amd.com * This object is a proxy for a structural port, to be used for debug 697538SBrad.Beckmann@amd.com * accesses. 707538SBrad.Beckmann@amd.com * 717538SBrad.Beckmann@amd.com * This proxy object is used when non structural entities 729576Snilay@cs.wisc.edu * (e.g. thread contexts, object file loaders) need access to the 739576Snilay@cs.wisc.edu * memory system. It calls the corresponding functions on the underlying 748612Stushar@csail.mit.edu * structural port, and provides templatized convenience access functions. 758612Stushar@csail.mit.edu * 767538SBrad.Beckmann@amd.com * The addresses are interpreted as physical addresses. 777538SBrad.Beckmann@amd.com * 787917SBrad.Beckmann@amd.com * @sa SETranslatingProxy 797563SBrad.Beckmann@amd.com * @sa FSTranslatingProxy 807563SBrad.Beckmann@amd.com */ 817538SBrad.Beckmann@amd.comclass PortProxy 827566SBrad.Beckmann@amd.com{ 837566SBrad.Beckmann@amd.com private: 847809Snilay@cs.wisc.edu 857809Snilay@cs.wisc.edu /** The actual physical port used by this proxy. */ 867809Snilay@cs.wisc.edu MasterPort &_port; 877809Snilay@cs.wisc.edu 887538SBrad.Beckmann@amd.com /** Granularity of any transactions issued through this proxy. */ 897538SBrad.Beckmann@amd.com const unsigned int _cacheLineSize; 907538SBrad.Beckmann@amd.com 917538SBrad.Beckmann@amd.com public: 9210524Snilay@cs.wisc.edu PortProxy(MasterPort &port, unsigned int cacheLineSize) : 9310524Snilay@cs.wisc.edu _port(port), _cacheLineSize(cacheLineSize) 9410524Snilay@cs.wisc.edu {} 9510524Snilay@cs.wisc.edu virtual ~PortProxy() { } 9610524Snilay@cs.wisc.edu 9710524Snilay@cs.wisc.edu 9810524Snilay@cs.wisc.edu 9910524Snilay@cs.wisc.edu /** Fixed functionality for use in base classes. */ 10010524Snilay@cs.wisc.edu 10110524Snilay@cs.wisc.edu /** 10210524Snilay@cs.wisc.edu * Read size bytes memory at physical address and store in p. 10310524Snilay@cs.wisc.edu */ 10410524Snilay@cs.wisc.edu void readBlobPhys(Addr addr, Request::Flags flags, 10510524Snilay@cs.wisc.edu void *p, int size) const; 10610524Snilay@cs.wisc.edu 10710524Snilay@cs.wisc.edu /** 10810524Snilay@cs.wisc.edu * Write size bytes from p to physical address. 10910524Snilay@cs.wisc.edu */ 11010524Snilay@cs.wisc.edu void writeBlobPhys(Addr addr, Request::Flags flags, 11110524Snilay@cs.wisc.edu const void *p, int size) const; 11210524Snilay@cs.wisc.edu 11310524Snilay@cs.wisc.edu /** 11410524Snilay@cs.wisc.edu * Fill size bytes starting at physical addr with byte value val. 11510524Snilay@cs.wisc.edu */ 11610524Snilay@cs.wisc.edu void memsetBlobPhys(Addr addr, Request::Flags flags, 11710524Snilay@cs.wisc.edu uint8_t v, int size) const; 11810524Snilay@cs.wisc.edu 11910524Snilay@cs.wisc.edu 12010524Snilay@cs.wisc.edu 12110524Snilay@cs.wisc.edu /** Methods to override in base classes */ 12210524Snilay@cs.wisc.edu 12310524Snilay@cs.wisc.edu /** 12410524Snilay@cs.wisc.edu * Read size bytes memory at address and store in p. 12510524Snilay@cs.wisc.edu * Returns true on success and false on failure. 12610524Snilay@cs.wisc.edu */ 12710524Snilay@cs.wisc.edu virtual bool 12810524Snilay@cs.wisc.edu tryReadBlob(Addr addr, void *p, int size) const 12910524Snilay@cs.wisc.edu { 13010524Snilay@cs.wisc.edu readBlobPhys(addr, 0, p, size); 13110524Snilay@cs.wisc.edu return true; 13210524Snilay@cs.wisc.edu } 13310524Snilay@cs.wisc.edu 13410524Snilay@cs.wisc.edu /** 13510524Snilay@cs.wisc.edu * Write size bytes from p to address. 13610524Snilay@cs.wisc.edu * Returns true on success and false on failure. 13710524Snilay@cs.wisc.edu */ 13810524Snilay@cs.wisc.edu virtual bool 13910524Snilay@cs.wisc.edu tryWriteBlob(Addr addr, const void *p, int size) const 14010524Snilay@cs.wisc.edu { 14110524Snilay@cs.wisc.edu writeBlobPhys(addr, 0, p, size); 14210524Snilay@cs.wisc.edu return true; 1439100SBrad.Beckmann@amd.com } 1449100SBrad.Beckmann@amd.com 1459100SBrad.Beckmann@amd.com /** 1469100SBrad.Beckmann@amd.com * Fill size bytes starting at addr with byte value val. 1479100SBrad.Beckmann@amd.com * Returns true on success and false on failure. 1489100SBrad.Beckmann@amd.com */ 1499100SBrad.Beckmann@amd.com virtual bool 1509100SBrad.Beckmann@amd.com tryMemsetBlob(Addr addr, uint8_t val, int size) const 1519100SBrad.Beckmann@amd.com { 1529100SBrad.Beckmann@amd.com memsetBlobPhys(addr, 0, val, size); 15310519Snilay@cs.wisc.edu return true; 1546892SBrad.Beckmann@amd.com } 15510524Snilay@cs.wisc.edu 1568436SBrad.Beckmann@amd.com 1578436SBrad.Beckmann@amd.com 1588257SBrad.Beckmann@amd.com /** Higher level interfaces based on the above. */ 1598257SBrad.Beckmann@amd.com 16010122Snilay@cs.wisc.edu /** 16110122Snilay@cs.wisc.edu * Same as tryReadBlob, but insists on success. 16210122Snilay@cs.wisc.edu */ 16310122Snilay@cs.wisc.edu void 16410122Snilay@cs.wisc.edu readBlob(Addr addr, void *p, int size) const 16510122Snilay@cs.wisc.edu { 1668257SBrad.Beckmann@amd.com if (!tryReadBlob(addr, p, size)) 16710122Snilay@cs.wisc.edu fatal("readBlob(%#x, ...) failed", addr); 16810122Snilay@cs.wisc.edu } 16910122Snilay@cs.wisc.edu 17010122Snilay@cs.wisc.edu /** 17110122Snilay@cs.wisc.edu * Same as tryWriteBlob, but insists on success. 17210122Snilay@cs.wisc.edu */ 1738257SBrad.Beckmann@amd.com void 17410122Snilay@cs.wisc.edu writeBlob(Addr addr, const void *p, int size) const 17510122Snilay@cs.wisc.edu { 17610122Snilay@cs.wisc.edu if (!tryWriteBlob(addr, p, size)) 17710122Snilay@cs.wisc.edu fatal("writeBlob(%#x, ...) failed", addr); 17810122Snilay@cs.wisc.edu } 1799148Spowerjg@cs.wisc.edu 18010311Snilay@cs.wisc.edu /** 18110311Snilay@cs.wisc.edu * Same as tryMemsetBlob, but insists on success. 18210311Snilay@cs.wisc.edu */ 18310311Snilay@cs.wisc.edu void 18410311Snilay@cs.wisc.edu memsetBlob(Addr addr, uint8_t v, int size) const 18510551Ssteve.reinhardt@amd.com { 18610551Ssteve.reinhardt@amd.com if (!tryMemsetBlob(addr, v, size)) 18710311Snilay@cs.wisc.edu fatal("memsetBlob(%#x, ...) failed", addr); 18810311Snilay@cs.wisc.edu } 18910551Ssteve.reinhardt@amd.com 19010551Ssteve.reinhardt@amd.com /** 19110551Ssteve.reinhardt@amd.com * Read sizeof(T) bytes from address and return as object T. 19210311Snilay@cs.wisc.edu */ 19310551Ssteve.reinhardt@amd.com template <typename T> 19410311Snilay@cs.wisc.edu T read(Addr address) const; 19510311Snilay@cs.wisc.edu 19610311Snilay@cs.wisc.edu /** 19710311Snilay@cs.wisc.edu * Write object T to address. Writes sizeof(T) bytes. 19810311Snilay@cs.wisc.edu */ 19910311Snilay@cs.wisc.edu template <typename T> 20010311Snilay@cs.wisc.edu void write(Addr address, const T &data) const; 20110311Snilay@cs.wisc.edu 20210311Snilay@cs.wisc.edu /** 20310311Snilay@cs.wisc.edu * Read sizeof(T) bytes from address and return as object T. 20410311Snilay@cs.wisc.edu * Performs endianness conversion from the selected guest to host order. 20510311Snilay@cs.wisc.edu */ 20610311Snilay@cs.wisc.edu template <typename T> 2079148Spowerjg@cs.wisc.edu T read(Addr address, ByteOrder guest_byte_order) const; 2089862Snilay@cs.wisc.edu 2099862Snilay@cs.wisc.edu /** 21010122Snilay@cs.wisc.edu * Write object T to address. Writes sizeof(T) bytes. 21110122Snilay@cs.wisc.edu * Performs endianness conversion from host to the selected guest order. 21210122Snilay@cs.wisc.edu */ 21310122Snilay@cs.wisc.edu template <typename T> 21410122Snilay@cs.wisc.edu void write(Addr address, T data, ByteOrder guest_byte_order) const; 2158257SBrad.Beckmann@amd.com 2168612Stushar@csail.mit.edu /** 2178612Stushar@csail.mit.edu * Write the string str into guest memory at address addr. 2189593Snilay@cs.wisc.edu * Returns true on success and false on failure. 2199593Snilay@cs.wisc.edu */ 2206892SBrad.Beckmann@amd.com bool tryWriteString(Addr addr, const char *str) const; 22110524Snilay@cs.wisc.edu 22210116Snilay@cs.wisc.edu /** 22310116Snilay@cs.wisc.edu * Same as tryWriteString, but insists on success. 22410116Snilay@cs.wisc.edu */ 22510116Snilay@cs.wisc.edu void 22610116Snilay@cs.wisc.edu writeString(Addr addr, const char *str) const 22710116Snilay@cs.wisc.edu { 22810116Snilay@cs.wisc.edu if (!tryWriteString(addr, str)) 22910116Snilay@cs.wisc.edu fatal("writeString(%#x, ...) failed", addr); 23010116Snilay@cs.wisc.edu } 23110116Snilay@cs.wisc.edu 23210120Snilay@cs.wisc.edu /** 23310012Snilay@cs.wisc.edu * Reads the string at guest address addr into the std::string str. 2347809Snilay@cs.wisc.edu * Returns true on success and false on failure. 23510525Snilay@cs.wisc.edu */ 23610630Snilay@cs.wisc.edu bool tryReadString(std::string &str, Addr addr) const; 23710630Snilay@cs.wisc.edu 23810630Snilay@cs.wisc.edu /** 23910630Snilay@cs.wisc.edu * Same as tryReadString, but insists on success. 24010630Snilay@cs.wisc.edu */ 24110529Smorr@cs.wisc.edu void 24210529Smorr@cs.wisc.edu readString(std::string &str, Addr addr) const 24310529Smorr@cs.wisc.edu { 24410529Smorr@cs.wisc.edu if (!tryReadString(str, addr)) 24510529Smorr@cs.wisc.edu fatal("readString(%#x, ...) failed", addr); 24610529Smorr@cs.wisc.edu } 24710529Smorr@cs.wisc.edu 248 /** 249 * Reads the string at guest address addr into the char * str, reading up 250 * to maxlen characters. The last character read is always a nul 251 * terminator. Returns true on success and false on failure. 252 */ 253 bool tryReadString(char *str, Addr addr, size_t maxlen) const; 254 255 /** 256 * Same as tryReadString, but insists on success. 257 */ 258 void 259 readString(char *str, Addr addr, size_t maxlen) const 260 { 261 if (!tryReadString(str, addr, maxlen)) 262 fatal("readString(%#x, ...) failed", addr); 263 } 264}; 265 266 267template <typename T> 268T 269PortProxy::read(Addr address) const 270{ 271 T data; 272 readBlob(address, &data, sizeof(T)); 273 return data; 274} 275 276template <typename T> 277void 278PortProxy::write(Addr address, const T &data) const 279{ 280 writeBlob(address, &data, sizeof(T)); 281} 282 283template <typename T> 284T 285PortProxy::read(Addr address, ByteOrder byte_order) const 286{ 287 T data; 288 readBlob(address, &data, sizeof(T)); 289 return gtoh(data, byte_order); 290} 291 292template <typename T> 293void 294PortProxy::write(Addr address, T data, ByteOrder byte_order) const 295{ 296 data = htog(data, byte_order); 297 writeBlob(address, &data, sizeof(T)); 298} 299 300#endif // __MEM_PORT_PROXY_HH__ 301