112338Sjason@lowepower.com/* 212338Sjason@lowepower.com * Copyright (c) 2017 Jason Lowe-Power 312338Sjason@lowepower.com * All rights reserved. 412338Sjason@lowepower.com * 512338Sjason@lowepower.com * Redistribution and use in source and binary forms, with or without 612338Sjason@lowepower.com * modification, are permitted provided that the following conditions are 712338Sjason@lowepower.com * met: redistributions of source code must retain the above copyright 812338Sjason@lowepower.com * notice, this list of conditions and the following disclaimer; 912338Sjason@lowepower.com * redistributions in binary form must reproduce the above copyright 1012338Sjason@lowepower.com * notice, this list of conditions and the following disclaimer in the 1112338Sjason@lowepower.com * documentation and/or other materials provided with the distribution; 1212338Sjason@lowepower.com * neither the name of the copyright holders nor the names of its 1312338Sjason@lowepower.com * contributors may be used to endorse or promote products derived from 1412338Sjason@lowepower.com * this software without specific prior written permission. 1512338Sjason@lowepower.com * 1612338Sjason@lowepower.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712338Sjason@lowepower.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812338Sjason@lowepower.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912338Sjason@lowepower.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012338Sjason@lowepower.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112338Sjason@lowepower.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212338Sjason@lowepower.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312338Sjason@lowepower.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412338Sjason@lowepower.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512338Sjason@lowepower.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612338Sjason@lowepower.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712338Sjason@lowepower.com * 2812338Sjason@lowepower.com * Authors: Jason Lowe-Power 2912338Sjason@lowepower.com */ 3012338Sjason@lowepower.com 3112338Sjason@lowepower.com#ifndef __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ 3212338Sjason@lowepower.com#define __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ 3312338Sjason@lowepower.com 3414252Sgabeblack@google.com#include "mem/port.hh" 3512338Sjason@lowepower.com#include "params/SimpleMemobj.hh" 3614252Sgabeblack@google.com#include "sim/sim_object.hh" 3712338Sjason@lowepower.com 3812338Sjason@lowepower.com/** 3912338Sjason@lowepower.com * A very simple memory object. Current implementation doesn't even cache 4012338Sjason@lowepower.com * anything it just forwards requests and responses. 4112338Sjason@lowepower.com * This memobj is fully blocking (not non-blocking). Only a single request can 4212338Sjason@lowepower.com * be outstanding at a time. 4312338Sjason@lowepower.com */ 4414252Sgabeblack@google.comclass SimpleMemobj : public SimObject 4512338Sjason@lowepower.com{ 4612338Sjason@lowepower.com private: 4712338Sjason@lowepower.com 4812338Sjason@lowepower.com /** 4912338Sjason@lowepower.com * Port on the CPU-side that receives requests. 5012338Sjason@lowepower.com * Mostly just forwards requests to the owner. 5112338Sjason@lowepower.com * Part of a vector of ports. One for each CPU port (e.g., data, inst) 5212338Sjason@lowepower.com */ 5312338Sjason@lowepower.com class CPUSidePort : public SlavePort 5412338Sjason@lowepower.com { 5512338Sjason@lowepower.com private: 5612338Sjason@lowepower.com /// The object that owns this object (SimpleMemobj) 5712338Sjason@lowepower.com SimpleMemobj *owner; 5812338Sjason@lowepower.com 5912338Sjason@lowepower.com /// True if the port needs to send a retry req. 6012338Sjason@lowepower.com bool needRetry; 6112338Sjason@lowepower.com 6212338Sjason@lowepower.com /// If we tried to send a packet and it was blocked, store it here 6312338Sjason@lowepower.com PacketPtr blockedPacket; 6412338Sjason@lowepower.com 6512338Sjason@lowepower.com public: 6612338Sjason@lowepower.com /** 6712338Sjason@lowepower.com * Constructor. Just calls the superclass constructor. 6812338Sjason@lowepower.com */ 6912338Sjason@lowepower.com CPUSidePort(const std::string& name, SimpleMemobj *owner) : 7012338Sjason@lowepower.com SlavePort(name, owner), owner(owner), needRetry(false), 7112338Sjason@lowepower.com blockedPacket(nullptr) 7212338Sjason@lowepower.com { } 7312338Sjason@lowepower.com 7412338Sjason@lowepower.com /** 7512338Sjason@lowepower.com * Send a packet across this port. This is called by the owner and 7612338Sjason@lowepower.com * all of the flow control is hanled in this function. 7712338Sjason@lowepower.com * 7812338Sjason@lowepower.com * @param packet to send. 7912338Sjason@lowepower.com */ 8012338Sjason@lowepower.com void sendPacket(PacketPtr pkt); 8112338Sjason@lowepower.com 8212338Sjason@lowepower.com /** 8312338Sjason@lowepower.com * Get a list of the non-overlapping address ranges the owner is 8412338Sjason@lowepower.com * responsible for. All slave ports must override this function 8512338Sjason@lowepower.com * and return a populated list with at least one item. 8612338Sjason@lowepower.com * 8712338Sjason@lowepower.com * @return a list of ranges responded to 8812338Sjason@lowepower.com */ 8912338Sjason@lowepower.com AddrRangeList getAddrRanges() const override; 9012338Sjason@lowepower.com 9112338Sjason@lowepower.com /** 9212338Sjason@lowepower.com * Send a retry to the peer port only if it is needed. This is called 9312338Sjason@lowepower.com * from the SimpleMemobj whenever it is unblocked. 9412338Sjason@lowepower.com */ 9512338Sjason@lowepower.com void trySendRetry(); 9612338Sjason@lowepower.com 9712338Sjason@lowepower.com protected: 9812338Sjason@lowepower.com /** 9912338Sjason@lowepower.com * Receive an atomic request packet from the master port. 10012338Sjason@lowepower.com * No need to implement in this simple memobj. 10112338Sjason@lowepower.com */ 10212338Sjason@lowepower.com Tick recvAtomic(PacketPtr pkt) override 10312338Sjason@lowepower.com { panic("recvAtomic unimpl."); } 10412338Sjason@lowepower.com 10512338Sjason@lowepower.com /** 10612338Sjason@lowepower.com * Receive a functional request packet from the master port. 10712338Sjason@lowepower.com * Performs a "debug" access updating/reading the data in place. 10812338Sjason@lowepower.com * 10912338Sjason@lowepower.com * @param packet the requestor sent. 11012338Sjason@lowepower.com */ 11112338Sjason@lowepower.com void recvFunctional(PacketPtr pkt) override; 11212338Sjason@lowepower.com 11312338Sjason@lowepower.com /** 11412338Sjason@lowepower.com * Receive a timing request from the master port. 11512338Sjason@lowepower.com * 11612338Sjason@lowepower.com * @param the packet that the requestor sent 11712338Sjason@lowepower.com * @return whether this object can consume the packet. If false, we 11812338Sjason@lowepower.com * will call sendRetry() when we can try to receive this 11912338Sjason@lowepower.com * request again. 12012338Sjason@lowepower.com */ 12112338Sjason@lowepower.com bool recvTimingReq(PacketPtr pkt) override; 12212338Sjason@lowepower.com 12312338Sjason@lowepower.com /** 12412338Sjason@lowepower.com * Called by the master port if sendTimingResp was called on this 12512338Sjason@lowepower.com * slave port (causing recvTimingResp to be called on the master 12612338Sjason@lowepower.com * port) and was unsuccesful. 12712338Sjason@lowepower.com */ 12812338Sjason@lowepower.com void recvRespRetry() override; 12912338Sjason@lowepower.com }; 13012338Sjason@lowepower.com 13112338Sjason@lowepower.com /** 13212338Sjason@lowepower.com * Port on the memory-side that receives responses. 13312338Sjason@lowepower.com * Mostly just forwards requests to the owner 13412338Sjason@lowepower.com */ 13512338Sjason@lowepower.com class MemSidePort : public MasterPort 13612338Sjason@lowepower.com { 13712338Sjason@lowepower.com private: 13812338Sjason@lowepower.com /// The object that owns this object (SimpleMemobj) 13912338Sjason@lowepower.com SimpleMemobj *owner; 14012338Sjason@lowepower.com 14112338Sjason@lowepower.com /// If we tried to send a packet and it was blocked, store it here 14212338Sjason@lowepower.com PacketPtr blockedPacket; 14312338Sjason@lowepower.com 14412338Sjason@lowepower.com public: 14512338Sjason@lowepower.com /** 14612338Sjason@lowepower.com * Constructor. Just calls the superclass constructor. 14712338Sjason@lowepower.com */ 14812338Sjason@lowepower.com MemSidePort(const std::string& name, SimpleMemobj *owner) : 14912338Sjason@lowepower.com MasterPort(name, owner), owner(owner), blockedPacket(nullptr) 15012338Sjason@lowepower.com { } 15112338Sjason@lowepower.com 15212338Sjason@lowepower.com /** 15312338Sjason@lowepower.com * Send a packet across this port. This is called by the owner and 15412338Sjason@lowepower.com * all of the flow control is hanled in this function. 15512338Sjason@lowepower.com * 15612338Sjason@lowepower.com * @param packet to send. 15712338Sjason@lowepower.com */ 15812338Sjason@lowepower.com void sendPacket(PacketPtr pkt); 15912338Sjason@lowepower.com 16012338Sjason@lowepower.com protected: 16112338Sjason@lowepower.com /** 16212338Sjason@lowepower.com * Receive a timing response from the slave port. 16312338Sjason@lowepower.com */ 16412338Sjason@lowepower.com bool recvTimingResp(PacketPtr pkt) override; 16512338Sjason@lowepower.com 16612338Sjason@lowepower.com /** 16712338Sjason@lowepower.com * Called by the slave port if sendTimingReq was called on this 16812338Sjason@lowepower.com * master port (causing recvTimingReq to be called on the slave 16912338Sjason@lowepower.com * port) and was unsuccesful. 17012338Sjason@lowepower.com */ 17112338Sjason@lowepower.com void recvReqRetry() override; 17212338Sjason@lowepower.com 17312338Sjason@lowepower.com /** 17412338Sjason@lowepower.com * Called to receive an address range change from the peer slave 17512338Sjason@lowepower.com * port. The default implementation ignores the change and does 17612338Sjason@lowepower.com * nothing. Override this function in a derived class if the owner 17712338Sjason@lowepower.com * needs to be aware of the address ranges, e.g. in an 17812338Sjason@lowepower.com * interconnect component like a bus. 17912338Sjason@lowepower.com */ 18012338Sjason@lowepower.com void recvRangeChange() override; 18112338Sjason@lowepower.com }; 18212338Sjason@lowepower.com 18312338Sjason@lowepower.com /** 18412338Sjason@lowepower.com * Handle the request from the CPU side 18512338Sjason@lowepower.com * 18612338Sjason@lowepower.com * @param requesting packet 18712338Sjason@lowepower.com * @return true if we can handle the request this cycle, false if the 18812338Sjason@lowepower.com * requestor needs to retry later 18912338Sjason@lowepower.com */ 19012338Sjason@lowepower.com bool handleRequest(PacketPtr pkt); 19112338Sjason@lowepower.com 19212338Sjason@lowepower.com /** 19312338Sjason@lowepower.com * Handle the respone from the memory side 19412338Sjason@lowepower.com * 19512338Sjason@lowepower.com * @param responding packet 19612338Sjason@lowepower.com * @return true if we can handle the response this cycle, false if the 19712338Sjason@lowepower.com * responder needs to retry later 19812338Sjason@lowepower.com */ 19912338Sjason@lowepower.com bool handleResponse(PacketPtr pkt); 20012338Sjason@lowepower.com 20112338Sjason@lowepower.com /** 20212338Sjason@lowepower.com * Handle a packet functionally. Update the data on a write and get the 20312338Sjason@lowepower.com * data on a read. 20412338Sjason@lowepower.com * 20512338Sjason@lowepower.com * @param packet to functionally handle 20612338Sjason@lowepower.com */ 20712338Sjason@lowepower.com void handleFunctional(PacketPtr pkt); 20812338Sjason@lowepower.com 20912338Sjason@lowepower.com /** 21012338Sjason@lowepower.com * Return the address ranges this memobj is responsible for. Just use the 21112338Sjason@lowepower.com * same as the next upper level of the hierarchy. 21212338Sjason@lowepower.com * 21312338Sjason@lowepower.com * @return the address ranges this memobj is responsible for 21412338Sjason@lowepower.com */ 21512338Sjason@lowepower.com AddrRangeList getAddrRanges() const; 21612338Sjason@lowepower.com 21712338Sjason@lowepower.com /** 21812338Sjason@lowepower.com * Tell the CPU side to ask for our memory ranges. 21912338Sjason@lowepower.com */ 22012338Sjason@lowepower.com void sendRangeChange(); 22112338Sjason@lowepower.com 22212338Sjason@lowepower.com /// Instantiation of the CPU-side ports 22312338Sjason@lowepower.com CPUSidePort instPort; 22412338Sjason@lowepower.com CPUSidePort dataPort; 22512338Sjason@lowepower.com 22612338Sjason@lowepower.com /// Instantiation of the memory-side port 22712338Sjason@lowepower.com MemSidePort memPort; 22812338Sjason@lowepower.com 22912338Sjason@lowepower.com /// True if this is currently blocked waiting for a response. 23012338Sjason@lowepower.com bool blocked; 23112338Sjason@lowepower.com 23212338Sjason@lowepower.com public: 23312338Sjason@lowepower.com 23412338Sjason@lowepower.com /** constructor 23512338Sjason@lowepower.com */ 23612338Sjason@lowepower.com SimpleMemobj(SimpleMemobjParams *params); 23712338Sjason@lowepower.com 23812338Sjason@lowepower.com /** 23913784Sgabeblack@google.com * Get a port with a given name and index. This is used at 24012338Sjason@lowepower.com * binding time and returns a reference to a protocol-agnostic 24113784Sgabeblack@google.com * port. 24212338Sjason@lowepower.com * 24312338Sjason@lowepower.com * @param if_name Port name 24412338Sjason@lowepower.com * @param idx Index in the case of a VectorPort 24512338Sjason@lowepower.com * 24612338Sjason@lowepower.com * @return A reference to the given port 24712338Sjason@lowepower.com */ 24813784Sgabeblack@google.com Port &getPort(const std::string &if_name, 24913784Sgabeblack@google.com PortID idx=InvalidPortID) override; 25012338Sjason@lowepower.com}; 25112338Sjason@lowepower.com 25212338Sjason@lowepower.com 25312338Sjason@lowepower.com#endif // __LEARNING_GEM5_PART2_SIMPLE_MEMOBJ_HH__ 254