abstract_mem.hh revision 13998
12440SN/A/* 22440SN/A * Copyright (c) 2012, 2019 ARM Limited 32440SN/A * All rights reserved 42440SN/A * 52440SN/A * The license below extends only to copyright in the software and shall 62440SN/A * not be construed as granting a license to any other intellectual 72440SN/A * property including but not limited to intellectual property relating 82440SN/A * to a hardware implementation of the functionality of the software 92440SN/A * licensed hereunder. You may use the software subject to the license 102440SN/A * terms below provided that you ensure that this notice is replicated 112440SN/A * unmodified and in its entirety in all distributions of the software, 122440SN/A * modified or unmodified, in source code or in binary form. 132440SN/A * 142440SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 152440SN/A * All rights reserved. 162440SN/A * 172440SN/A * Redistribution and use in source and binary forms, with or without 182440SN/A * modification, are permitted provided that the following conditions are 192440SN/A * met: redistributions of source code must retain the above copyright 202440SN/A * notice, this list of conditions and the following disclaimer; 212440SN/A * redistributions in binary form must reproduce the above copyright 222440SN/A * notice, this list of conditions and the following disclaimer in the 232440SN/A * documentation and/or other materials provided with the distribution; 242440SN/A * neither the name of the copyright holders nor the names of its 252440SN/A * contributors may be used to endorse or promote products derived from 262440SN/A * this software without specific prior written permission. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302440SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312440SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322440SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332440SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342440SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352440SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362972Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 376327Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382440SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 395569Snate@binkert.org * 403120Sgblack@eecs.umich.edu * Authors: Ron Dreslinski 412440SN/A * Andreas Hansson 425569Snate@binkert.org */ 435569Snate@binkert.org 445569Snate@binkert.org/** 455569Snate@binkert.org * @file 465569Snate@binkert.org * AbstractMemory declaration 475569Snate@binkert.org */ 482440SN/A 495569Snate@binkert.org#ifndef __MEM_ABSTRACT_MEMORY_HH__ 505569Snate@binkert.org#define __MEM_ABSTRACT_MEMORY_HH__ 514826Ssaidi@eecs.umich.edu 525569Snate@binkert.org#include "mem/backdoor.hh" 535569Snate@binkert.org#include "mem/port.hh" 545569Snate@binkert.org#include "params/AbstractMemory.hh" 555569Snate@binkert.org#include "sim/clocked_object.hh" 565570Snate@binkert.org#include "sim/stats.hh" 575569Snate@binkert.org 583577Sgblack@eecs.umich.edu 595569Snate@binkert.orgclass System; 605569Snate@binkert.org 615569Snate@binkert.org/** 625569Snate@binkert.org * Locked address class that represents a physical address and a 635570Snate@binkert.org * context id. 645569Snate@binkert.org */ 652440SN/Aclass LockedAddr { 665569Snate@binkert.org 675569Snate@binkert.org private: 685569Snate@binkert.org 695569Snate@binkert.org // on alpha, minimum LL/SC granularity is 16 bytes, so lower 705569Snate@binkert.org // bits need to masked off. 715569Snate@binkert.org static const Addr Addr_Mask = 0xf; 722440SN/A 735569Snate@binkert.org public: 745569Snate@binkert.org 755569Snate@binkert.org // locked address 765569Snate@binkert.org Addr addr; 775569Snate@binkert.org 785569Snate@binkert.org // locking hw context 792440SN/A const ContextID contextId; 805569Snate@binkert.org 815569Snate@binkert.org static Addr mask(Addr paddr) { return (paddr & ~Addr_Mask); } 825569Snate@binkert.org 835569Snate@binkert.org // check for matching execution context 845569Snate@binkert.org bool matchesContext(const RequestPtr &req) const 852440SN/A { 865569Snate@binkert.org assert(contextId != InvalidContextID); 875569Snate@binkert.org assert(req->hasContextId()); 885569Snate@binkert.org return (contextId == req->contextId()); 895569Snate@binkert.org } 905569Snate@binkert.org 915569Snate@binkert.org LockedAddr(const RequestPtr &req) : addr(mask(req->getPaddr())), 922440SN/A contextId(req->contextId()) 935569Snate@binkert.org {} 945569Snate@binkert.org 955569Snate@binkert.org // constructor for unserialization use 965569Snate@binkert.org LockedAddr(Addr _addr, int _cid) : addr(_addr), contextId(_cid) 975569Snate@binkert.org {} 982440SN/A}; 995569Snate@binkert.org 1005569Snate@binkert.org/** 1015569Snate@binkert.org * An abstract memory represents a contiguous block of physical 1025569Snate@binkert.org * memory, with an associated address range, and also provides basic 1035569Snate@binkert.org * functionality for reading and writing this memory without any 1045569Snate@binkert.org * timing information. It is a ClockedObject since subclasses may need timing 1055569Snate@binkert.org * information. 1062440SN/A */ 1075569Snate@binkert.orgclass AbstractMemory : public ClockedObject 1085569Snate@binkert.org{ 1095569Snate@binkert.org protected: 1105569Snate@binkert.org 1115569Snate@binkert.org // Address range of this memory 1125569Snate@binkert.org AddrRange range; 1132440SN/A 1145569Snate@binkert.org // Pointer to host memory used to implement this memory 1155569Snate@binkert.org uint8_t* pmemAddr; 1165569Snate@binkert.org 1175569Snate@binkert.org // Backdoor to access this memory. 1185569Snate@binkert.org MemBackdoor backdoor; 1195569Snate@binkert.org 1202440SN/A // Enable specific memories to be reported to the configuration table 1215569Snate@binkert.org const bool confTableReported; 1225569Snate@binkert.org 1235569Snate@binkert.org // Should the memory appear in the global address map 1242440SN/A const bool inAddrMap; 1255569Snate@binkert.org 1265569Snate@binkert.org // Should KVM map this memory for the guest 1275569Snate@binkert.org const bool kvmMap; 1285569Snate@binkert.org 1292440SN/A std::list<LockedAddr> lockedAddrList; 1305569Snate@binkert.org 1312440SN/A // helper function for checkLockedAddrs(): we really want to 1325569Snate@binkert.org // inline a quick check for an empty locked addr list (hopefully 1335569Snate@binkert.org // the common case), and do the full list search (if necessary) in 1342440SN/A // this out-of-line function 1355569Snate@binkert.org bool checkLockedAddrList(PacketPtr pkt); 1365569Snate@binkert.org 1375569Snate@binkert.org // Record the address of a load-locked operation so that we can 1382440SN/A // clear the execution context's lock flag if a matching store is 1395569Snate@binkert.org // performed 1405569Snate@binkert.org void trackLoadLocked(PacketPtr pkt); 1412440SN/A 1425569Snate@binkert.org // Compare a store address with any locked addresses so we can 1435569Snate@binkert.org // clear the lock flag appropriately. Return value set to 'false' 1445569Snate@binkert.org // if store operation should be suppressed (because it was a 1452440SN/A // conditional store and the address was no longer locked by the 1465569Snate@binkert.org // requesting execution context), 'true' otherwise. Note that 1475569Snate@binkert.org // this method must be called on *all* stores since even 1485569Snate@binkert.org // non-conditional stores must clear any matching lock addresses. 1492440SN/A bool writeOK(PacketPtr pkt) { 1505569Snate@binkert.org const RequestPtr &req = pkt->req; 1515569Snate@binkert.org if (lockedAddrList.empty()) { 1525569Snate@binkert.org // no locked addrs: nothing to check, store_conditional fails 1532440SN/A bool isLLSC = pkt->isLLSC(); 1545569Snate@binkert.org if (isLLSC) { 1555569Snate@binkert.org req->setExtraData(0); 1565569Snate@binkert.org } 1575569Snate@binkert.org return !isLLSC; // only do write if not an sc 1585569Snate@binkert.org } else { 1595569Snate@binkert.org // iterate over list... 1602440SN/A return checkLockedAddrList(pkt); 1612440SN/A } 1626329Sgblack@eecs.umich.edu } 1636329Sgblack@eecs.umich.edu 1646329Sgblack@eecs.umich.edu /** Number of total bytes read from this memory */ 1656329Sgblack@eecs.umich.edu Stats::Vector bytesRead; 1662440SN/A /** Number of instruction bytes read from this memory */ 1672440SN/A Stats::Vector bytesInstRead; 1685569Snate@binkert.org /** Number of bytes written to this memory */ 169 Stats::Vector bytesWritten; 170 /** Number of read requests */ 171 Stats::Vector numReads; 172 /** Number of write requests */ 173 Stats::Vector numWrites; 174 /** Number of other requests */ 175 Stats::Vector numOther; 176 /** Read bandwidth from this memory */ 177 Stats::Formula bwRead; 178 /** Read bandwidth from this memory */ 179 Stats::Formula bwInstRead; 180 /** Write bandwidth from this memory */ 181 Stats::Formula bwWrite; 182 /** Total bandwidth from this memory */ 183 Stats::Formula bwTotal; 184 185 /** Pointor to the System object. 186 * This is used for getting the number of masters in the system which is 187 * needed when registering stats 188 */ 189 System *_system; 190 191 192 private: 193 194 // Prevent copying 195 AbstractMemory(const AbstractMemory&); 196 197 // Prevent assignment 198 AbstractMemory& operator=(const AbstractMemory&); 199 200 public: 201 202 typedef AbstractMemoryParams Params; 203 204 AbstractMemory(const Params* p); 205 virtual ~AbstractMemory() {} 206 207 /** 208 * Initialise this memory. 209 */ 210 void init() override; 211 212 /** 213 * See if this is a null memory that should never store data and 214 * always return zero. 215 * 216 * @return true if null 217 */ 218 bool isNull() const { return params()->null; } 219 220 /** 221 * Set the host memory backing store to be used by this memory 222 * controller. 223 * 224 * @param pmem_addr Pointer to a segment of host memory 225 */ 226 void setBackingStore(uint8_t* pmem_addr); 227 228 /** 229 * Get the list of locked addresses to allow checkpointing. 230 */ 231 const std::list<LockedAddr>& getLockedAddrList() const 232 { return lockedAddrList; } 233 234 /** 235 * Add a locked address to allow for checkpointing. 236 */ 237 void addLockedAddr(LockedAddr addr) { lockedAddrList.push_back(addr); } 238 239 /** read the system pointer 240 * Implemented for completeness with the setter 241 * @return pointer to the system object */ 242 System* system() const { return _system; } 243 244 /** Set the system pointer on this memory 245 * This can't be done via a python parameter because the system needs 246 * pointers to all the memories and the reverse would create a cycle in the 247 * object graph. An init() this is set. 248 * @param sys system pointer to set 249 */ 250 void system(System *sys) { _system = sys; } 251 252 const Params * 253 params() const 254 { 255 return dynamic_cast<const Params *>(_params); 256 } 257 258 /** 259 * Get the address range 260 * 261 * @return a single contigous address range 262 */ 263 AddrRange getAddrRange() const; 264 265 /** 266 * Get the memory size. 267 * 268 * @return the size of the memory 269 */ 270 uint64_t size() const { return range.size(); } 271 272 /** 273 * Get the start address. 274 * 275 * @return the start address of the memory 276 */ 277 Addr start() const { return range.start(); } 278 279 /** 280 * Should this memory be passed to the kernel and part of the OS 281 * physical memory layout. 282 * 283 * @return if this memory is reported 284 */ 285 bool isConfReported() const { return confTableReported; } 286 287 /** 288 * Some memories are used as shadow memories or should for other 289 * reasons not be part of the global address map. 290 * 291 * @return if this memory is part of the address map 292 */ 293 bool isInAddrMap() const { return inAddrMap; } 294 295 /** 296 * When shadow memories are in use, KVM may want to make one or the other, 297 * but cannot map both into the guest address space. 298 * 299 * @return if this memory should be mapped into the KVM guest address space 300 */ 301 bool isKvmMap() const { return kvmMap; } 302 303 /** 304 * Perform an untimed memory access and update all the state 305 * (e.g. locked addresses) and statistics accordingly. The packet 306 * is turned into a response if required. 307 * 308 * @param pkt Packet performing the access 309 */ 310 void access(PacketPtr pkt); 311 312 /** 313 * Perform an untimed memory read or write without changing 314 * anything but the memory itself. No stats are affected by this 315 * access. In addition to normal accesses this also facilitates 316 * print requests. 317 * 318 * @param pkt Packet performing the access 319 */ 320 void functionalAccess(PacketPtr pkt); 321 322 /** 323 * Register Statistics 324 */ 325 void regStats() override; 326 327}; 328 329#endif //__MEM_ABSTRACT_MEMORY_HH__ 330