12391SN/A/* 213998Stiago.muck@arm.com * Copyright (c) 2012, 2019 ARM Limited 38931Sandreas.hansson@arm.com * All rights reserved 48931Sandreas.hansson@arm.com * 58931Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68931Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78931Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88931Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98931Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108931Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118931Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128931Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138931Sandreas.hansson@arm.com * 142391SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 152391SN/A * All rights reserved. 162391SN/A * 172391SN/A * Redistribution and use in source and binary forms, with or without 182391SN/A * modification, are permitted provided that the following conditions are 192391SN/A * met: redistributions of source code must retain the above copyright 202391SN/A * notice, this list of conditions and the following disclaimer; 212391SN/A * redistributions in binary form must reproduce the above copyright 222391SN/A * notice, this list of conditions and the following disclaimer in the 232391SN/A * documentation and/or other materials provided with the distribution; 242391SN/A * neither the name of the copyright holders nor the names of its 252391SN/A * contributors may be used to endorse or promote products derived from 262391SN/A * this software without specific prior written permission. 272391SN/A * 282391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392665SN/A * 402665SN/A * Authors: Ron Dreslinski 418931Sandreas.hansson@arm.com * Andreas Hansson 422391SN/A */ 432391SN/A 448931Sandreas.hansson@arm.com/** 458931Sandreas.hansson@arm.com * @file 468931Sandreas.hansson@arm.com * AbstractMemory declaration 472391SN/A */ 482391SN/A 4912492Sodanrc@yahoo.com.br#ifndef __MEM_ABSTRACT_MEMORY_HH__ 5012492Sodanrc@yahoo.com.br#define __MEM_ABSTRACT_MEMORY_HH__ 512391SN/A 5213853Sgabeblack@google.com#include "mem/backdoor.hh" 5313892Sgabeblack@google.com#include "mem/port.hh" 548931Sandreas.hansson@arm.com#include "params/AbstractMemory.hh" 5513892Sgabeblack@google.com#include "sim/clocked_object.hh" 568719SN/A#include "sim/stats.hh" 572462SN/A 589053Sdam.sunwoo@arm.com 599053Sdam.sunwoo@arm.comclass System; 609053Sdam.sunwoo@arm.com 618931Sandreas.hansson@arm.com/** 629293Sandreas.hansson@arm.com * Locked address class that represents a physical address and a 639293Sandreas.hansson@arm.com * context id. 649293Sandreas.hansson@arm.com */ 659293Sandreas.hansson@arm.comclass LockedAddr { 669293Sandreas.hansson@arm.com 679293Sandreas.hansson@arm.com private: 689293Sandreas.hansson@arm.com 699293Sandreas.hansson@arm.com // on alpha, minimum LL/SC granularity is 16 bytes, so lower 709293Sandreas.hansson@arm.com // bits need to masked off. 719293Sandreas.hansson@arm.com static const Addr Addr_Mask = 0xf; 729293Sandreas.hansson@arm.com 739293Sandreas.hansson@arm.com public: 749293Sandreas.hansson@arm.com 759293Sandreas.hansson@arm.com // locked address 769293Sandreas.hansson@arm.com Addr addr; 779293Sandreas.hansson@arm.com 789293Sandreas.hansson@arm.com // locking hw context 7911005Sandreas.sandberg@arm.com const ContextID contextId; 809293Sandreas.hansson@arm.com 819293Sandreas.hansson@arm.com static Addr mask(Addr paddr) { return (paddr & ~Addr_Mask); } 829293Sandreas.hansson@arm.com 839293Sandreas.hansson@arm.com // check for matching execution context 8412749Sgiacomo.travaglini@arm.com bool matchesContext(const RequestPtr &req) const 859293Sandreas.hansson@arm.com { 8613998Stiago.muck@arm.com assert(contextId != InvalidContextID); 8713998Stiago.muck@arm.com assert(req->hasContextId()); 889293Sandreas.hansson@arm.com return (contextId == req->contextId()); 899293Sandreas.hansson@arm.com } 909293Sandreas.hansson@arm.com 9112749Sgiacomo.travaglini@arm.com LockedAddr(const RequestPtr &req) : addr(mask(req->getPaddr())), 9212749Sgiacomo.travaglini@arm.com contextId(req->contextId()) 939293Sandreas.hansson@arm.com {} 949293Sandreas.hansson@arm.com 959293Sandreas.hansson@arm.com // constructor for unserialization use 969293Sandreas.hansson@arm.com LockedAddr(Addr _addr, int _cid) : addr(_addr), contextId(_cid) 979293Sandreas.hansson@arm.com {} 989293Sandreas.hansson@arm.com}; 999293Sandreas.hansson@arm.com 1009293Sandreas.hansson@arm.com/** 1018931Sandreas.hansson@arm.com * An abstract memory represents a contiguous block of physical 1028931Sandreas.hansson@arm.com * memory, with an associated address range, and also provides basic 1038931Sandreas.hansson@arm.com * functionality for reading and writing this memory without any 10413892Sgabeblack@google.com * timing information. It is a ClockedObject since subclasses may need timing 10513892Sgabeblack@google.com * information. 1068931Sandreas.hansson@arm.com */ 10713892Sgabeblack@google.comclass AbstractMemory : public ClockedObject 1082391SN/A{ 1096107SN/A protected: 1106107SN/A 1118931Sandreas.hansson@arm.com // Address range of this memory 1129235Sandreas.hansson@arm.com AddrRange range; 1132413SN/A 1148931Sandreas.hansson@arm.com // Pointer to host memory used to implement this memory 1158931Sandreas.hansson@arm.com uint8_t* pmemAddr; 1162413SN/A 11713853Sgabeblack@google.com // Backdoor to access this memory. 11813853Sgabeblack@google.com MemBackdoor backdoor; 11913853Sgabeblack@google.com 1208931Sandreas.hansson@arm.com // Enable specific memories to be reported to the configuration table 12111614Sdavid.j.hashe@gmail.com const bool confTableReported; 1222413SN/A 1238931Sandreas.hansson@arm.com // Should the memory appear in the global address map 12411614Sdavid.j.hashe@gmail.com const bool inAddrMap; 12511614Sdavid.j.hashe@gmail.com 12611614Sdavid.j.hashe@gmail.com // Should KVM map this memory for the guest 12711614Sdavid.j.hashe@gmail.com const bool kvmMap; 1283170SN/A 1293170SN/A std::list<LockedAddr> lockedAddrList; 1303170SN/A 1313170SN/A // helper function for checkLockedAddrs(): we really want to 1323170SN/A // inline a quick check for an empty locked addr list (hopefully 1333170SN/A // the common case), and do the full list search (if necessary) in 1343170SN/A // this out-of-line function 1354626SN/A bool checkLockedAddrList(PacketPtr pkt); 1363170SN/A 1373170SN/A // Record the address of a load-locked operation so that we can 1383170SN/A // clear the execution context's lock flag if a matching store is 1393170SN/A // performed 1404626SN/A void trackLoadLocked(PacketPtr pkt); 1413170SN/A 1423170SN/A // Compare a store address with any locked addresses so we can 1433170SN/A // clear the lock flag appropriately. Return value set to 'false' 1443170SN/A // if store operation should be suppressed (because it was a 1453170SN/A // conditional store and the address was no longer locked by the 1463170SN/A // requesting execution context), 'true' otherwise. Note that 1473170SN/A // this method must be called on *all* stores since even 1483170SN/A // non-conditional stores must clear any matching lock addresses. 1494626SN/A bool writeOK(PacketPtr pkt) { 15012749Sgiacomo.travaglini@arm.com const RequestPtr &req = pkt->req; 1513170SN/A if (lockedAddrList.empty()) { 1523170SN/A // no locked addrs: nothing to check, store_conditional fails 1536102SN/A bool isLLSC = pkt->isLLSC(); 1546102SN/A if (isLLSC) { 1554040SN/A req->setExtraData(0); 1563170SN/A } 1576102SN/A return !isLLSC; // only do write if not an sc 1583170SN/A } else { 1593170SN/A // iterate over list... 1604626SN/A return checkLockedAddrList(pkt); 1613170SN/A } 1623170SN/A } 1633170SN/A 1648719SN/A /** Number of total bytes read from this memory */ 1659053Sdam.sunwoo@arm.com Stats::Vector bytesRead; 1668719SN/A /** Number of instruction bytes read from this memory */ 1679053Sdam.sunwoo@arm.com Stats::Vector bytesInstRead; 1688719SN/A /** Number of bytes written to this memory */ 1699053Sdam.sunwoo@arm.com Stats::Vector bytesWritten; 1708719SN/A /** Number of read requests */ 1719053Sdam.sunwoo@arm.com Stats::Vector numReads; 1728719SN/A /** Number of write requests */ 1739053Sdam.sunwoo@arm.com Stats::Vector numWrites; 1748719SN/A /** Number of other requests */ 1759053Sdam.sunwoo@arm.com Stats::Vector numOther; 1768719SN/A /** Read bandwidth from this memory */ 1778719SN/A Stats::Formula bwRead; 1788719SN/A /** Read bandwidth from this memory */ 1798719SN/A Stats::Formula bwInstRead; 1808719SN/A /** Write bandwidth from this memory */ 1818719SN/A Stats::Formula bwWrite; 1828719SN/A /** Total bandwidth from this memory */ 1838719SN/A Stats::Formula bwTotal; 1848719SN/A 1859053Sdam.sunwoo@arm.com /** Pointor to the System object. 1869053Sdam.sunwoo@arm.com * This is used for getting the number of masters in the system which is 1879053Sdam.sunwoo@arm.com * needed when registering stats 1889053Sdam.sunwoo@arm.com */ 1899053Sdam.sunwoo@arm.com System *_system; 1909053Sdam.sunwoo@arm.com 1919053Sdam.sunwoo@arm.com 1928931Sandreas.hansson@arm.com private: 1938931Sandreas.hansson@arm.com 1948931Sandreas.hansson@arm.com // Prevent copying 1958931Sandreas.hansson@arm.com AbstractMemory(const AbstractMemory&); 1968931Sandreas.hansson@arm.com 1978931Sandreas.hansson@arm.com // Prevent assignment 1988931Sandreas.hansson@arm.com AbstractMemory& operator=(const AbstractMemory&); 1992391SN/A 2002391SN/A public: 2018931Sandreas.hansson@arm.com 2028931Sandreas.hansson@arm.com typedef AbstractMemoryParams Params; 2038931Sandreas.hansson@arm.com 2048931Sandreas.hansson@arm.com AbstractMemory(const Params* p); 2059293Sandreas.hansson@arm.com virtual ~AbstractMemory() {} 2069293Sandreas.hansson@arm.com 2079293Sandreas.hansson@arm.com /** 20810466Sandreas.hansson@arm.com * Initialise this memory. 20910466Sandreas.hansson@arm.com */ 21011169Sandreas.hansson@arm.com void init() override; 21110466Sandreas.hansson@arm.com 21210466Sandreas.hansson@arm.com /** 2139293Sandreas.hansson@arm.com * See if this is a null memory that should never store data and 2149293Sandreas.hansson@arm.com * always return zero. 2159293Sandreas.hansson@arm.com * 2169293Sandreas.hansson@arm.com * @return true if null 2179293Sandreas.hansson@arm.com */ 2189293Sandreas.hansson@arm.com bool isNull() const { return params()->null; } 2199293Sandreas.hansson@arm.com 2209293Sandreas.hansson@arm.com /** 2219293Sandreas.hansson@arm.com * Set the host memory backing store to be used by this memory 2229293Sandreas.hansson@arm.com * controller. 2239293Sandreas.hansson@arm.com * 2249293Sandreas.hansson@arm.com * @param pmem_addr Pointer to a segment of host memory 2259293Sandreas.hansson@arm.com */ 2269293Sandreas.hansson@arm.com void setBackingStore(uint8_t* pmem_addr); 2279293Sandreas.hansson@arm.com 2289293Sandreas.hansson@arm.com /** 2299293Sandreas.hansson@arm.com * Get the list of locked addresses to allow checkpointing. 2309293Sandreas.hansson@arm.com */ 2319293Sandreas.hansson@arm.com const std::list<LockedAddr>& getLockedAddrList() const 2329293Sandreas.hansson@arm.com { return lockedAddrList; } 2339293Sandreas.hansson@arm.com 2349293Sandreas.hansson@arm.com /** 2359293Sandreas.hansson@arm.com * Add a locked address to allow for checkpointing. 2369293Sandreas.hansson@arm.com */ 2379293Sandreas.hansson@arm.com void addLockedAddr(LockedAddr addr) { lockedAddrList.push_back(addr); } 2382391SN/A 2399053Sdam.sunwoo@arm.com /** read the system pointer 2409053Sdam.sunwoo@arm.com * Implemented for completeness with the setter 2419053Sdam.sunwoo@arm.com * @return pointer to the system object */ 2429053Sdam.sunwoo@arm.com System* system() const { return _system; } 2439053Sdam.sunwoo@arm.com 2449053Sdam.sunwoo@arm.com /** Set the system pointer on this memory 2459053Sdam.sunwoo@arm.com * This can't be done via a python parameter because the system needs 2469053Sdam.sunwoo@arm.com * pointers to all the memories and the reverse would create a cycle in the 2479053Sdam.sunwoo@arm.com * object graph. An init() this is set. 2489053Sdam.sunwoo@arm.com * @param sys system pointer to set 2499053Sdam.sunwoo@arm.com */ 2509053Sdam.sunwoo@arm.com void system(System *sys) { _system = sys; } 2519053Sdam.sunwoo@arm.com 2524762SN/A const Params * 2534762SN/A params() const 2544762SN/A { 2554762SN/A return dynamic_cast<const Params *>(_params); 2564762SN/A } 2574762SN/A 2588931Sandreas.hansson@arm.com /** 2598931Sandreas.hansson@arm.com * Get the address range 2608931Sandreas.hansson@arm.com * 2618931Sandreas.hansson@arm.com * @return a single contigous address range 2628931Sandreas.hansson@arm.com */ 2639235Sandreas.hansson@arm.com AddrRange getAddrRange() const; 2642391SN/A 2658931Sandreas.hansson@arm.com /** 2668931Sandreas.hansson@arm.com * Get the memory size. 2678931Sandreas.hansson@arm.com * 2688931Sandreas.hansson@arm.com * @return the size of the memory 2698931Sandreas.hansson@arm.com */ 2709098Sandreas.hansson@arm.com uint64_t size() const { return range.size(); } 2718923SN/A 2728931Sandreas.hansson@arm.com /** 2738931Sandreas.hansson@arm.com * Get the start address. 2748931Sandreas.hansson@arm.com * 2758931Sandreas.hansson@arm.com * @return the start address of the memory 2768931Sandreas.hansson@arm.com */ 2779405Sandreas.hansson@arm.com Addr start() const { return range.start(); } 2788923SN/A 2798931Sandreas.hansson@arm.com /** 2808931Sandreas.hansson@arm.com * Should this memory be passed to the kernel and part of the OS 2818931Sandreas.hansson@arm.com * physical memory layout. 2828931Sandreas.hansson@arm.com * 2838931Sandreas.hansson@arm.com * @return if this memory is reported 2848931Sandreas.hansson@arm.com */ 2858931Sandreas.hansson@arm.com bool isConfReported() const { return confTableReported; } 2862391SN/A 2878931Sandreas.hansson@arm.com /** 2888931Sandreas.hansson@arm.com * Some memories are used as shadow memories or should for other 2898931Sandreas.hansson@arm.com * reasons not be part of the global address map. 2908931Sandreas.hansson@arm.com * 2918931Sandreas.hansson@arm.com * @return if this memory is part of the address map 2928931Sandreas.hansson@arm.com */ 2938931Sandreas.hansson@arm.com bool isInAddrMap() const { return inAddrMap; } 2948931Sandreas.hansson@arm.com 2958931Sandreas.hansson@arm.com /** 29611614Sdavid.j.hashe@gmail.com * When shadow memories are in use, KVM may want to make one or the other, 29711614Sdavid.j.hashe@gmail.com * but cannot map both into the guest address space. 29811614Sdavid.j.hashe@gmail.com * 29911614Sdavid.j.hashe@gmail.com * @return if this memory should be mapped into the KVM guest address space 30011614Sdavid.j.hashe@gmail.com */ 30111614Sdavid.j.hashe@gmail.com bool isKvmMap() const { return kvmMap; } 30211614Sdavid.j.hashe@gmail.com 30311614Sdavid.j.hashe@gmail.com /** 3048931Sandreas.hansson@arm.com * Perform an untimed memory access and update all the state 3058931Sandreas.hansson@arm.com * (e.g. locked addresses) and statistics accordingly. The packet 3068931Sandreas.hansson@arm.com * is turned into a response if required. 3078931Sandreas.hansson@arm.com * 3088931Sandreas.hansson@arm.com * @param pkt Packet performing the access 3098931Sandreas.hansson@arm.com */ 3108931Sandreas.hansson@arm.com void access(PacketPtr pkt); 3118931Sandreas.hansson@arm.com 3128931Sandreas.hansson@arm.com /** 3138931Sandreas.hansson@arm.com * Perform an untimed memory read or write without changing 3148931Sandreas.hansson@arm.com * anything but the memory itself. No stats are affected by this 3158931Sandreas.hansson@arm.com * access. In addition to normal accesses this also facilitates 3168931Sandreas.hansson@arm.com * print requests. 3178931Sandreas.hansson@arm.com * 3188931Sandreas.hansson@arm.com * @param pkt Packet performing the access 3198931Sandreas.hansson@arm.com */ 3208931Sandreas.hansson@arm.com void functionalAccess(PacketPtr pkt); 3218931Sandreas.hansson@arm.com 3228931Sandreas.hansson@arm.com /** 3238719SN/A * Register Statistics 3248719SN/A */ 32511169Sandreas.hansson@arm.com void regStats() override; 3268719SN/A 3272391SN/A}; 3282391SN/A 32912492Sodanrc@yahoo.com.br#endif //__MEM_ABSTRACT_MEMORY_HH__ 330