coherent_xbar.hh revision 8711
19241Sandreas.hansson@arm.com/* 211491Sandreas.hansson@arm.com * Copyright (c) 2011 ARM Limited 39241Sandreas.hansson@arm.com * All rights reserved 49241Sandreas.hansson@arm.com * 59241Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 69241Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 79241Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 89241Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 99241Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 109241Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 119241Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 129241Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 139241Sandreas.hansson@arm.com * 149241Sandreas.hansson@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 159241Sandreas.hansson@arm.com * All rights reserved. 169241Sandreas.hansson@arm.com * 179241Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 189241Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 199241Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 209241Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 219241Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 229241Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 239241Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 249241Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 259241Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 269241Sandreas.hansson@arm.com * this software without specific prior written permission. 279241Sandreas.hansson@arm.com * 289241Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 299241Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 309241Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 319241Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 329241Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 339241Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 349241Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 359241Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 369241Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 379241Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 389241Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 399241Sandreas.hansson@arm.com * 409241Sandreas.hansson@arm.com * Authors: Ron Dreslinski 4111540Sandreas.sandberg@arm.com * Ali Saidi 4211540Sandreas.sandberg@arm.com */ 4311540Sandreas.sandberg@arm.com 4411540Sandreas.sandberg@arm.com/** 459241Sandreas.hansson@arm.com * @file 469241Sandreas.hansson@arm.com * Declaration of a bus object. 479241Sandreas.hansson@arm.com */ 4810138Sneha.agarwal@arm.com 499241Sandreas.hansson@arm.com#ifndef __MEM_BUS_HH__ 509241Sandreas.hansson@arm.com#define __MEM_BUS_HH__ 519241Sandreas.hansson@arm.com 529241Sandreas.hansson@arm.com#include <list> 539241Sandreas.hansson@arm.com#include <set> 549241Sandreas.hansson@arm.com#include <string> 559241Sandreas.hansson@arm.com 569241Sandreas.hansson@arm.com#include "base/hashmap.hh" 579241Sandreas.hansson@arm.com#include "base/range.hh" 589241Sandreas.hansson@arm.com#include "base/range_map.hh" 599241Sandreas.hansson@arm.com#include "base/types.hh" 609241Sandreas.hansson@arm.com#include "mem/mem_object.hh" 619718Sandreas.hansson@arm.com#include "mem/packet.hh" 629720Sandreas.hansson@arm.com#include "mem/port.hh" 6311491Sandreas.hansson@arm.com#include "mem/request.hh" 6411491Sandreas.hansson@arm.com#include "params/Bus.hh" 659717Sandreas.hansson@arm.com#include "sim/eventq.hh" 669719Sandreas.hansson@arm.com 6710360Sandreas.hansson@arm.comclass Bus : public MemObject 689241Sandreas.hansson@arm.com{ 699719Sandreas.hansson@arm.com /** Declaration of the buses port type, one will be instantiated for each 709719Sandreas.hansson@arm.com of the interfaces connecting to the bus. */ 7111393Sandreas.hansson@arm.com class BusPort : public Port 7211393Sandreas.hansson@arm.com { 739241Sandreas.hansson@arm.com bool _onRetryList; 749241Sandreas.hansson@arm.com 759241Sandreas.hansson@arm.com /** A pointer to the bus to which this port belongs. */ 769241Sandreas.hansson@arm.com Bus *bus; 779241Sandreas.hansson@arm.com 789241Sandreas.hansson@arm.com /** A id to keep track of the intercafe ID this port is connected to. */ 799241Sandreas.hansson@arm.com int id; 809241Sandreas.hansson@arm.com 819241Sandreas.hansson@arm.com public: 829294Sandreas.hansson@arm.com 839294Sandreas.hansson@arm.com /** Constructor for the BusPort.*/ 849241Sandreas.hansson@arm.com BusPort(const std::string &_name, Bus *_bus, int _id) 859241Sandreas.hansson@arm.com : Port(_name, _bus), _onRetryList(false), bus(_bus), id(_id) 869241Sandreas.hansson@arm.com { } 879241Sandreas.hansson@arm.com 889241Sandreas.hansson@arm.com bool onRetryList() 899241Sandreas.hansson@arm.com { return _onRetryList; } 909241Sandreas.hansson@arm.com 919241Sandreas.hansson@arm.com void onRetryList(bool newVal) 929241Sandreas.hansson@arm.com { _onRetryList = newVal; } 939241Sandreas.hansson@arm.com 949241Sandreas.hansson@arm.com int getId() { return id; } 959241Sandreas.hansson@arm.com 969241Sandreas.hansson@arm.com /** 979241Sandreas.hansson@arm.com * Determine if this port should be considered a snooper. This 989241Sandreas.hansson@arm.com * is determined by the bus. 999524SAndreas.Sandberg@ARM.com * 1009241Sandreas.hansson@arm.com * @return a boolean that is true if this port is snooping 1019241Sandreas.hansson@arm.com */ 1029718Sandreas.hansson@arm.com virtual bool isSnooping() 1039718Sandreas.hansson@arm.com { return bus->isSnooping(id); } 1049241Sandreas.hansson@arm.com 1059717Sandreas.hansson@arm.com protected: 1069241Sandreas.hansson@arm.com 1079241Sandreas.hansson@arm.com /** When reciving a timing request from the peer port (at id), 1089241Sandreas.hansson@arm.com pass it to the bus. */ 1099241Sandreas.hansson@arm.com virtual bool recvTiming(PacketPtr pkt) 1109241Sandreas.hansson@arm.com { pkt->setSrc(id); return bus->recvTiming(pkt); } 1119241Sandreas.hansson@arm.com 1129241Sandreas.hansson@arm.com /** When reciving a Atomic requestfrom the peer port (at id), 1139241Sandreas.hansson@arm.com pass it to the bus. */ 1149241Sandreas.hansson@arm.com virtual Tick recvAtomic(PacketPtr pkt) 1159241Sandreas.hansson@arm.com { pkt->setSrc(id); return bus->recvAtomic(pkt); } 1169524SAndreas.Sandberg@ARM.com 1179719Sandreas.hansson@arm.com /** When reciving a Functional requestfrom the peer port (at id), 1189720Sandreas.hansson@arm.com pass it to the bus. */ 1199719Sandreas.hansson@arm.com virtual void recvFunctional(PacketPtr pkt) 1209241Sandreas.hansson@arm.com { pkt->setSrc(id); bus->recvFunctional(pkt); } 1219241Sandreas.hansson@arm.com 1229241Sandreas.hansson@arm.com /** When reciving a range change from the peer port (at id), 1239241Sandreas.hansson@arm.com pass it to the bus. */ 1249241Sandreas.hansson@arm.com virtual void recvRangeChange() 1259241Sandreas.hansson@arm.com { bus->recvRangeChange(id); } 12610913Sandreas.sandberg@arm.com 12710913Sandreas.sandberg@arm.com /** When reciving a retry from the peer port (at id), 1289241Sandreas.hansson@arm.com pass it to the bus. */ 12910051Srioshering@gmail.com virtual void recvRetry() 13010051Srioshering@gmail.com { bus->recvRetry(id); } 13110913Sandreas.sandberg@arm.com 13210051Srioshering@gmail.com // This should return all the 'owned' addresses that are 13310051Srioshering@gmail.com // downstream from this bus, yes? That is, the union of all 1349719Sandreas.hansson@arm.com // the 'owned' address ranges of all the other interfaces on 1359719Sandreas.hansson@arm.com // this bus... 1369719Sandreas.hansson@arm.com virtual AddrRangeList getAddrRanges() 1379719Sandreas.hansson@arm.com { return bus->getAddrRanges(id); } 1389719Sandreas.hansson@arm.com 13910913Sandreas.sandberg@arm.com // Ask the bus to ask everyone on the bus what their block size is and 1409719Sandreas.hansson@arm.com // take the max of it. This might need to be changed a bit if we ever 14110913Sandreas.sandberg@arm.com // support multiple block sizes. 1429719Sandreas.hansson@arm.com virtual unsigned deviceBlockSize() const 1439241Sandreas.hansson@arm.com { return bus->findBlockSize(id); } 1449241Sandreas.hansson@arm.com 1459241Sandreas.hansson@arm.com }; 14610905Sandreas.sandberg@arm.com 1479241Sandreas.hansson@arm.com class BusFreeEvent : public Event 1489241Sandreas.hansson@arm.com { 1499241Sandreas.hansson@arm.com Bus * bus; 1509241Sandreas.hansson@arm.com 1519719Sandreas.hansson@arm.com public: 1529241Sandreas.hansson@arm.com BusFreeEvent(Bus * _bus); 1539719Sandreas.hansson@arm.com void process(); 1549241Sandreas.hansson@arm.com const char *description() const; 1559717Sandreas.hansson@arm.com }; 1569241Sandreas.hansson@arm.com 1579241Sandreas.hansson@arm.com /** a globally unique id for this bus. */ 1589241Sandreas.hansson@arm.com int busId; 1599719Sandreas.hansson@arm.com /** the clock speed for the bus */ 1609719Sandreas.hansson@arm.com int clock; 1619719Sandreas.hansson@arm.com /** cycles of overhead per transaction */ 1629241Sandreas.hansson@arm.com int headerCycles; 1639241Sandreas.hansson@arm.com /** the width of the bus in bytes */ 1649241Sandreas.hansson@arm.com int width; 16510905Sandreas.sandberg@arm.com /** the next tick at which the bus will be idle */ 1669241Sandreas.hansson@arm.com Tick tickNextIdle; 1679241Sandreas.hansson@arm.com 1689717Sandreas.hansson@arm.com Event * drainEvent; 1699717Sandreas.hansson@arm.com 1709717Sandreas.hansson@arm.com 1719717Sandreas.hansson@arm.com static const int defaultId = -3; //Make it unique from Broadcast 1729241Sandreas.hansson@arm.com 1739241Sandreas.hansson@arm.com typedef range_map<Addr,int>::iterator PortIter; 1749241Sandreas.hansson@arm.com range_map<Addr, int> portMap; 1759719Sandreas.hansson@arm.com 1769719Sandreas.hansson@arm.com AddrRangeList defaultRange; 1779719Sandreas.hansson@arm.com 1789719Sandreas.hansson@arm.com typedef std::vector<BusPort*>::iterator SnoopIter; 1799719Sandreas.hansson@arm.com std::vector<BusPort*> snoopPorts; 1809720Sandreas.hansson@arm.com 1819719Sandreas.hansson@arm.com /** Function called by the port when the bus is recieving a Timing 1829241Sandreas.hansson@arm.com transaction.*/ 1839241Sandreas.hansson@arm.com bool recvTiming(PacketPtr pkt); 1849241Sandreas.hansson@arm.com 1859717Sandreas.hansson@arm.com /** Function called by the port when the bus is recieving a Atomic 1869241Sandreas.hansson@arm.com transaction.*/ 18711491Sandreas.hansson@arm.com Tick recvAtomic(PacketPtr pkt); 18811491Sandreas.hansson@arm.com 18911491Sandreas.hansson@arm.com /** Function called by the port when the bus is recieving a Functional 1909717Sandreas.hansson@arm.com transaction.*/ 1919717Sandreas.hansson@arm.com void recvFunctional(PacketPtr pkt); 1929717Sandreas.hansson@arm.com 1939717Sandreas.hansson@arm.com /** Timing function called by port when it is once again able to process 1949717Sandreas.hansson@arm.com * requests. */ 1959719Sandreas.hansson@arm.com void recvRetry(int id); 1969719Sandreas.hansson@arm.com 1979718Sandreas.hansson@arm.com /** Function called by the port when the bus is recieving a range change.*/ 19810266Sandreas.hansson@arm.com void recvRangeChange(int id); 19910266Sandreas.hansson@arm.com 20010266Sandreas.hansson@arm.com /** Find which port connected to this bus (if any) should be given a packet 20110266Sandreas.hansson@arm.com * with this address. 20210266Sandreas.hansson@arm.com * @param addr Address to find port for. 20310266Sandreas.hansson@arm.com * @return id of port that the packet should be sent out of. 20410266Sandreas.hansson@arm.com */ 20510266Sandreas.hansson@arm.com int findPort(Addr addr); 20610266Sandreas.hansson@arm.com 20710266Sandreas.hansson@arm.com // Cache for the findPort function storing recently used ports from portMap 20810266Sandreas.hansson@arm.com struct PortCache { 20910266Sandreas.hansson@arm.com bool valid; 21011393Sandreas.hansson@arm.com int id; 21111393Sandreas.hansson@arm.com Addr start; 21211393Sandreas.hansson@arm.com Addr end; 21311393Sandreas.hansson@arm.com }; 21411393Sandreas.hansson@arm.com 21511393Sandreas.hansson@arm.com PortCache portCache[3]; 21611222Sandreas.hansson@arm.com 21711222Sandreas.hansson@arm.com // Checks the cache and returns the id of the port that has the requested 21811222Sandreas.hansson@arm.com // address within its range 2199719Sandreas.hansson@arm.com inline int checkPortCache(Addr addr) { 2209719Sandreas.hansson@arm.com if (portCache[0].valid && addr >= portCache[0].start && 2219719Sandreas.hansson@arm.com addr < portCache[0].end) { 2229719Sandreas.hansson@arm.com return portCache[0].id; 2239719Sandreas.hansson@arm.com } 2249719Sandreas.hansson@arm.com if (portCache[1].valid && addr >= portCache[1].start && 2259719Sandreas.hansson@arm.com addr < portCache[1].end) { 2269719Sandreas.hansson@arm.com return portCache[1].id; 2279719Sandreas.hansson@arm.com } 2289720Sandreas.hansson@arm.com if (portCache[2].valid && addr >= portCache[2].start && 2299719Sandreas.hansson@arm.com addr < portCache[2].end) { 2309719Sandreas.hansson@arm.com return portCache[2].id; 2319719Sandreas.hansson@arm.com } 2329717Sandreas.hansson@arm.com 2339241Sandreas.hansson@arm.com return -1; 2349241Sandreas.hansson@arm.com } 23511540Sandreas.sandberg@arm.com 23611540Sandreas.sandberg@arm.com // Clears the earliest entry of the cache and inserts a new port entry 23711540Sandreas.sandberg@arm.com inline void updatePortCache(short id, Addr start, Addr end) { 23811540Sandreas.sandberg@arm.com portCache[2].valid = portCache[1].valid; 23911540Sandreas.sandberg@arm.com portCache[2].id = portCache[1].id; 24011540Sandreas.sandberg@arm.com portCache[2].start = portCache[1].start; 24111540Sandreas.sandberg@arm.com portCache[2].end = portCache[1].end; 24211540Sandreas.sandberg@arm.com 24311540Sandreas.sandberg@arm.com portCache[1].valid = portCache[0].valid; 24411540Sandreas.sandberg@arm.com portCache[1].id = portCache[0].id; 24511540Sandreas.sandberg@arm.com portCache[1].start = portCache[0].start; 24611540Sandreas.sandberg@arm.com portCache[1].end = portCache[0].end; 24711540Sandreas.sandberg@arm.com 24811540Sandreas.sandberg@arm.com portCache[0].valid = true; 24911540Sandreas.sandberg@arm.com portCache[0].id = id; 25011540Sandreas.sandberg@arm.com portCache[0].start = start; 25111540Sandreas.sandberg@arm.com portCache[0].end = end; 25211540Sandreas.sandberg@arm.com } 25311540Sandreas.sandberg@arm.com 25411540Sandreas.sandberg@arm.com // Clears the cache. Needs to be called in constructor. 25511540Sandreas.sandberg@arm.com inline void clearPortCache() { 2569241Sandreas.hansson@arm.com portCache[2].valid = false; 2579718Sandreas.hansson@arm.com portCache[1].valid = false; 2589241Sandreas.hansson@arm.com portCache[0].valid = false; 2599241Sandreas.hansson@arm.com } 2609241Sandreas.hansson@arm.com 2619241Sandreas.hansson@arm.com /** 2629241Sandreas.hansson@arm.com * Return the address ranges this port is responsible for. 2639241Sandreas.hansson@arm.com * 2649241Sandreas.hansson@arm.com * @param id id of the bus port that made the request 2659718Sandreas.hansson@arm.com * 2669241Sandreas.hansson@arm.com * @return a list of non-overlapping address ranges 2679241Sandreas.hansson@arm.com */ 2689718Sandreas.hansson@arm.com AddrRangeList getAddrRanges(int id); 2699241Sandreas.hansson@arm.com 2709241Sandreas.hansson@arm.com /** 27110128Sstan.czerniawski@arm.com * Determine if the bus port is snooping or not. 27210128Sstan.czerniawski@arm.com * 2739241Sandreas.hansson@arm.com * @param id id of the bus port that made the request 2749241Sandreas.hansson@arm.com * 2759241Sandreas.hansson@arm.com * @return a boolean indicating if this port is snooping or not 2769241Sandreas.hansson@arm.com */ 2779241Sandreas.hansson@arm.com bool isSnooping(int id); 2789241Sandreas.hansson@arm.com 2799241Sandreas.hansson@arm.com /** Calculate the timing parameters for the packet. Updates the 2809241Sandreas.hansson@arm.com * firstWordTime and finishTime fields of the packet object. 2819241Sandreas.hansson@arm.com * Returns the tick at which the packet header is completed (which 2829241Sandreas.hansson@arm.com * will be all that is sent if the target rejects the packet). 2839241Sandreas.hansson@arm.com */ 2849241Sandreas.hansson@arm.com Tick calcPacketTiming(PacketPtr pkt); 2859241Sandreas.hansson@arm.com 2869241Sandreas.hansson@arm.com /** Occupy the bus until until */ 2879241Sandreas.hansson@arm.com void occupyBus(Tick until); 2889241Sandreas.hansson@arm.com 2899241Sandreas.hansson@arm.com /** Ask everyone on the bus what their size is 2909241Sandreas.hansson@arm.com * @param id id of the busport that made the request 2919241Sandreas.hansson@arm.com * @return the max of all the sizes 2929241Sandreas.hansson@arm.com */ 2939241Sandreas.hansson@arm.com unsigned findBlockSize(int id); 2949241Sandreas.hansson@arm.com 2959241Sandreas.hansson@arm.com BusFreeEvent busIdle; 2969241Sandreas.hansson@arm.com 2979241Sandreas.hansson@arm.com bool inRetry; 2989241Sandreas.hansson@arm.com std::set<int> inRecvRangeChange; 2999241Sandreas.hansson@arm.com 30011540Sandreas.sandberg@arm.com /** max number of bus ids we've handed out so far */ 3019241Sandreas.hansson@arm.com short maxId; 3029718Sandreas.hansson@arm.com 3039241Sandreas.hansson@arm.com /** An array of pointers to the peer port interfaces 3049241Sandreas.hansson@arm.com connected to this bus.*/ 3059241Sandreas.hansson@arm.com m5::hash_map<short,BusPort*> interfaces; 3069718Sandreas.hansson@arm.com 3079241Sandreas.hansson@arm.com /** An array of pointers to ports that retry should be called on because the 30810138Sneha.agarwal@arm.com * original send failed for whatever reason.*/ 30910392Swendy.elsasser@arm.com std::list<BusPort*> retryList; 3109241Sandreas.hansson@arm.com 3119241Sandreas.hansson@arm.com void addToRetryList(BusPort * port) 3129241Sandreas.hansson@arm.com { 3139241Sandreas.hansson@arm.com if (!inRetry) { 3149241Sandreas.hansson@arm.com // The device wasn't retrying a packet, or wasn't at an appropriate 3159241Sandreas.hansson@arm.com // time. 3169241Sandreas.hansson@arm.com assert(!port->onRetryList()); 3179241Sandreas.hansson@arm.com port->onRetryList(true); 3189241Sandreas.hansson@arm.com retryList.push_back(port); 3199241Sandreas.hansson@arm.com } else { 3209241Sandreas.hansson@arm.com if (port->onRetryList()) { 3219241Sandreas.hansson@arm.com // The device was retrying a packet. It didn't work, so we'll leave 3229241Sandreas.hansson@arm.com // it at the head of the retry list. 3239241Sandreas.hansson@arm.com assert(port == retryList.front()); 3249241Sandreas.hansson@arm.com inRetry = false; 3259241Sandreas.hansson@arm.com } 3269718Sandreas.hansson@arm.com else { 3279814Sandreas.hansson@arm.com port->onRetryList(true); 3289718Sandreas.hansson@arm.com retryList.push_back(port); 32910138Sneha.agarwal@arm.com } 3309814Sandreas.hansson@arm.com } 3319718Sandreas.hansson@arm.com } 3329241Sandreas.hansson@arm.com 3339718Sandreas.hansson@arm.com /** Port that handles requests that don't match any of the interfaces.*/ 3349241Sandreas.hansson@arm.com BusPort *defaultPort; 3359722Ssascha.bischoff@arm.com 3369722Ssascha.bischoff@arm.com BusPort *funcPort; 3379722Ssascha.bischoff@arm.com int funcPortId; 3389241Sandreas.hansson@arm.com 3399718Sandreas.hansson@arm.com /** If true, use address range provided by default device. Any 3409241Sandreas.hansson@arm.com address not handled by another port and not in default device's 3419241Sandreas.hansson@arm.com range will cause a fatal error. If false, just send all 3429241Sandreas.hansson@arm.com addresses not handled by another port to default device. */ 3439241Sandreas.hansson@arm.com bool useDefaultRange; 3449241Sandreas.hansson@arm.com 3459241Sandreas.hansson@arm.com unsigned defaultBlockSize; 3469718Sandreas.hansson@arm.com unsigned cachedBlockSize; 3479241Sandreas.hansson@arm.com bool cachedBlockSizeValid; 3489241Sandreas.hansson@arm.com 3499241Sandreas.hansson@arm.com // Cache for the peer port interfaces 3509241Sandreas.hansson@arm.com struct BusCache { 3519241Sandreas.hansson@arm.com bool valid; 35210392Swendy.elsasser@arm.com short id; 35310138Sneha.agarwal@arm.com BusPort *port; 35410138Sneha.agarwal@arm.com }; 35510138Sneha.agarwal@arm.com 35610138Sneha.agarwal@arm.com BusCache busCache[3]; 35710138Sneha.agarwal@arm.com 35810138Sneha.agarwal@arm.com // Checks the peer port interfaces cache for the port id and returns 35910138Sneha.agarwal@arm.com // a pointer to the matching port 36010392Swendy.elsasser@arm.com inline BusPort* checkBusCache(short id) { 36110138Sneha.agarwal@arm.com if (busCache[0].valid && id == busCache[0].id) { 36210138Sneha.agarwal@arm.com return busCache[0].port; 36310392Swendy.elsasser@arm.com } 36410392Swendy.elsasser@arm.com if (busCache[1].valid && id == busCache[1].id) { 36510138Sneha.agarwal@arm.com return busCache[1].port; 36610138Sneha.agarwal@arm.com } 36710138Sneha.agarwal@arm.com if (busCache[2].valid && id == busCache[2].id) { 36810138Sneha.agarwal@arm.com return busCache[2].port; 36910138Sneha.agarwal@arm.com } 37010138Sneha.agarwal@arm.com 37110138Sneha.agarwal@arm.com return NULL; 37210746Swendy.elsasser@arm.com } 37310746Swendy.elsasser@arm.com 37410138Sneha.agarwal@arm.com // Replaces the earliest entry in the cache with a new entry 37510138Sneha.agarwal@arm.com inline void updateBusCache(short id, BusPort *port) { 37610138Sneha.agarwal@arm.com busCache[2].valid = busCache[1].valid; 37710138Sneha.agarwal@arm.com busCache[2].id = busCache[1].id; 37810138Sneha.agarwal@arm.com busCache[2].port = busCache[1].port; 37910138Sneha.agarwal@arm.com 38010138Sneha.agarwal@arm.com busCache[1].valid = busCache[0].valid; 38110138Sneha.agarwal@arm.com busCache[1].id = busCache[0].id; 38210138Sneha.agarwal@arm.com busCache[1].port = busCache[0].port; 38310138Sneha.agarwal@arm.com 38410138Sneha.agarwal@arm.com busCache[0].valid = true; 38510138Sneha.agarwal@arm.com busCache[0].id = id; 38610138Sneha.agarwal@arm.com busCache[0].port = port; 38710392Swendy.elsasser@arm.com } 38810392Swendy.elsasser@arm.com 38910392Swendy.elsasser@arm.com // Invalidates the cache. Needs to be called in constructor. 39010392Swendy.elsasser@arm.com inline void clearBusCache() { 39110392Swendy.elsasser@arm.com busCache[2].valid = false; 39210392Swendy.elsasser@arm.com busCache[1].valid = false; 39310392Swendy.elsasser@arm.com busCache[0].valid = false; 39410392Swendy.elsasser@arm.com } 39510392Swendy.elsasser@arm.com 39610392Swendy.elsasser@arm.com 39710392Swendy.elsasser@arm.com public: 39810392Swendy.elsasser@arm.com 39910392Swendy.elsasser@arm.com /** A function used to return the port associated with this bus object. */ 40010392Swendy.elsasser@arm.com virtual Port *getPort(const std::string &if_name, int idx = -1); 40110392Swendy.elsasser@arm.com 40210392Swendy.elsasser@arm.com virtual void init(); 40310392Swendy.elsasser@arm.com virtual void startup(); 40410392Swendy.elsasser@arm.com 40510392Swendy.elsasser@arm.com unsigned int drain(Event *de); 40610392Swendy.elsasser@arm.com 40710392Swendy.elsasser@arm.com Bus(const BusParams *p); 40810392Swendy.elsasser@arm.com}; 40910392Swendy.elsasser@arm.com 41010392Swendy.elsasser@arm.com#endif //__MEM_BUS_HH__ 41110392Swendy.elsasser@arm.com