DMASequencer.hh revision 11108
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2008 Mark D. Hill and David A. Wood
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are
711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright
811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer;
911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright
1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the
1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution;
1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its
1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from
1411308Santhony.gutierrez@amd.com * this software without specific prior written permission.
1511308Santhony.gutierrez@amd.com *
1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711308Santhony.gutierrez@amd.com */
2811308Santhony.gutierrez@amd.com
2911308Santhony.gutierrez@amd.com#ifndef __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__
3011308Santhony.gutierrez@amd.com#define __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__
3111308Santhony.gutierrez@amd.com
3211308Santhony.gutierrez@amd.com#include <memory>
3311308Santhony.gutierrez@amd.com#include <ostream>
3411308Santhony.gutierrez@amd.com
3511308Santhony.gutierrez@amd.com#include "mem/mem_object.hh"
3611308Santhony.gutierrez@amd.com#include "mem/protocol/DMASequencerRequestType.hh"
3711308Santhony.gutierrez@amd.com#include "mem/protocol/RequestStatus.hh"
3811308Santhony.gutierrez@amd.com#include "mem/ruby/common/DataBlock.hh"
3911308Santhony.gutierrez@amd.com#include "mem/ruby/network/MessageBuffer.hh"
4011308Santhony.gutierrez@amd.com#include "mem/ruby/system/RubySystem.hh"
4111308Santhony.gutierrez@amd.com#include "mem/simple_mem.hh"
4211308Santhony.gutierrez@amd.com#include "mem/tport.hh"
4311308Santhony.gutierrez@amd.com#include "params/DMASequencer.hh"
4411308Santhony.gutierrez@amd.com
4511308Santhony.gutierrez@amd.comclass AbstractController;
4611308Santhony.gutierrez@amd.com
4711308Santhony.gutierrez@amd.comstruct DMARequest
4811308Santhony.gutierrez@amd.com{
4911308Santhony.gutierrez@amd.com    uint64_t start_paddr;
5011308Santhony.gutierrez@amd.com    int len;
5111308Santhony.gutierrez@amd.com    bool write;
5211308Santhony.gutierrez@amd.com    int bytes_completed;
5311308Santhony.gutierrez@amd.com    int bytes_issued;
5411308Santhony.gutierrez@amd.com    uint8_t *data;
5511308Santhony.gutierrez@amd.com    PacketPtr pkt;
5611308Santhony.gutierrez@amd.com};
5711308Santhony.gutierrez@amd.com
5811308Santhony.gutierrez@amd.comclass DMASequencer : public MemObject
5911308Santhony.gutierrez@amd.com{
6011308Santhony.gutierrez@amd.com  public:
6111308Santhony.gutierrez@amd.com    typedef DMASequencerParams Params;
6211308Santhony.gutierrez@amd.com    DMASequencer(const Params *);
6311308Santhony.gutierrez@amd.com    void init();
6411308Santhony.gutierrez@amd.com    RubySystem *m_ruby_system;
6511308Santhony.gutierrez@amd.com
6611308Santhony.gutierrez@amd.com  public:
6711308Santhony.gutierrez@amd.com    class MemSlavePort : public QueuedSlavePort
6811308Santhony.gutierrez@amd.com    {
6911308Santhony.gutierrez@amd.com      private:
7011308Santhony.gutierrez@amd.com        RespPacketQueue queue;
7111308Santhony.gutierrez@amd.com        RubySystem* m_ruby_system;
7211308Santhony.gutierrez@amd.com        bool access_backing_store;
7311308Santhony.gutierrez@amd.com
7411308Santhony.gutierrez@amd.com      public:
7511308Santhony.gutierrez@amd.com        MemSlavePort(const std::string &_name, DMASequencer *_port,
7611308Santhony.gutierrez@amd.com                     PortID id, RubySystem *_ruby_system,
7711308Santhony.gutierrez@amd.com                     bool _access_backing_store);
7811308Santhony.gutierrez@amd.com        void hitCallback(PacketPtr pkt);
7911308Santhony.gutierrez@amd.com        void evictionCallback(Addr address);
8011308Santhony.gutierrez@amd.com
8111308Santhony.gutierrez@amd.com      protected:
8211697Santhony.gutierrez@amd.com        bool recvTimingReq(PacketPtr pkt);
8311308Santhony.gutierrez@amd.com
8411308Santhony.gutierrez@amd.com        Tick recvAtomic(PacketPtr pkt)
8511308Santhony.gutierrez@amd.com        { panic("DMASequencer::MemSlavePort::recvAtomic() not implemented!\n"); }
8611308Santhony.gutierrez@amd.com
8711308Santhony.gutierrez@amd.com        void recvFunctional(PacketPtr pkt)
8811308Santhony.gutierrez@amd.com        { panic("DMASequencer::MemSlavePort::recvFunctional() not implemented!\n"); }
8911308Santhony.gutierrez@amd.com
9011308Santhony.gutierrez@amd.com        AddrRangeList getAddrRanges() const
9111308Santhony.gutierrez@amd.com        { AddrRangeList ranges; return ranges; }
9211308Santhony.gutierrez@amd.com
9311308Santhony.gutierrez@amd.com      private:
9411851Sbrandon.potter@amd.com        bool isPhysMemAddress(Addr addr) const;
9511308Santhony.gutierrez@amd.com    };
9611308Santhony.gutierrez@amd.com
9711308Santhony.gutierrez@amd.com    BaseSlavePort &getSlavePort(const std::string &if_name,
9811308Santhony.gutierrez@amd.com                                PortID idx = InvalidPortID);
9911308Santhony.gutierrez@amd.com
10011308Santhony.gutierrez@amd.com    /* external interface */
10111308Santhony.gutierrez@amd.com    RequestStatus makeRequest(PacketPtr pkt);
10211308Santhony.gutierrez@amd.com    bool busy() { return m_is_busy;}
10311308Santhony.gutierrez@amd.com    int outstandingCount() const { return (m_is_busy ? 1 : 0); }
10411851Sbrandon.potter@amd.com    bool isDeadlockEventScheduled() const { return false; }
10511308Santhony.gutierrez@amd.com    void descheduleDeadlockEvent() {}
10611308Santhony.gutierrez@amd.com
10711308Santhony.gutierrez@amd.com    // Called by the controller to give the sequencer a pointer.
10811308Santhony.gutierrez@amd.com    // A pointer to the controller is needed for atomic support.
10911308Santhony.gutierrez@amd.com    void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
11011308Santhony.gutierrez@amd.com    uint32_t getId() { return m_version; }
11111308Santhony.gutierrez@amd.com    DrainState drain() M5_ATTR_OVERRIDE;
11211308Santhony.gutierrez@amd.com
11311308Santhony.gutierrez@amd.com    /* SLICC callback */
11411308Santhony.gutierrez@amd.com    void dataCallback(const DataBlock & dblk);
11511308Santhony.gutierrez@amd.com    void ackCallback();
11611308Santhony.gutierrez@amd.com
11711308Santhony.gutierrez@amd.com    void recordRequestType(DMASequencerRequestType requestType);
11811308Santhony.gutierrez@amd.com
11911308Santhony.gutierrez@amd.com  private:
12011308Santhony.gutierrez@amd.com    void issueNext();
12111308Santhony.gutierrez@amd.com    void ruby_hit_callback(PacketPtr pkt);
12211308Santhony.gutierrez@amd.com    void testDrainComplete();
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.com    /**
12511308Santhony.gutierrez@amd.com     * Called by the PIO port when receiving a timing response.
12611308Santhony.gutierrez@amd.com     *
12711308Santhony.gutierrez@amd.com     * @param pkt Response packet
12811308Santhony.gutierrez@amd.com     * @param master_port_id Port id of the PIO port
12911308Santhony.gutierrez@amd.com     *
13011308Santhony.gutierrez@amd.com     * @return Whether successfully sent
13111308Santhony.gutierrez@amd.com     */
13211308Santhony.gutierrez@amd.com    bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
13311697Santhony.gutierrez@amd.com    unsigned int getChildDrainCount();
13411697Santhony.gutierrez@amd.com
13511308Santhony.gutierrez@amd.com  private:
13611308Santhony.gutierrez@amd.com    uint32_t m_version;
13711308Santhony.gutierrez@amd.com    AbstractController* m_controller;
13811308Santhony.gutierrez@amd.com    MessageBuffer* m_mandatory_q_ptr;
13911308Santhony.gutierrez@amd.com    bool m_usingRubyTester;
14011308Santhony.gutierrez@amd.com
14111308Santhony.gutierrez@amd.com    MemSlavePort slave_port;
14211308Santhony.gutierrez@amd.com
14311308Santhony.gutierrez@amd.com    System* system;
14411308Santhony.gutierrez@amd.com
14511308Santhony.gutierrez@amd.com    bool retry;
14611308Santhony.gutierrez@amd.com    bool m_is_busy;
14711308Santhony.gutierrez@amd.com    uint64_t m_data_block_mask;
14811308Santhony.gutierrez@amd.com    DMARequest active_request;
14911308Santhony.gutierrez@amd.com};
15011308Santhony.gutierrez@amd.com
15111308Santhony.gutierrez@amd.com#endif // __MEM_RUBY_SYSTEM_DMASEQUENCER_HH__
15211308Santhony.gutierrez@amd.com