Sequencer.cc revision 9171:ae88ecf37145
16019Shines@cs.fsu.edu/*
211861Snikos.nikoleris@arm.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
37093Sgblack@eecs.umich.edu * All rights reserved.
47093Sgblack@eecs.umich.edu *
57093Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67093Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77093Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97093Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107093Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117093Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127093Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137093Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
146019Shines@cs.fsu.edu * this software without specific prior written permission.
156019Shines@cs.fsu.edu *
166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276019Shines@cs.fsu.edu */
286019Shines@cs.fsu.edu
296019Shines@cs.fsu.edu#include "base/misc.hh"
306019Shines@cs.fsu.edu#include "base/str.hh"
316019Shines@cs.fsu.edu#include "config/the_isa.hh"
326019Shines@cs.fsu.edu#if THE_ISA == X86_ISA
336019Shines@cs.fsu.edu#include "arch/x86/insts/microldstop.hh"
346019Shines@cs.fsu.edu#endif // X86_ISA
356019Shines@cs.fsu.edu#include "cpu/testers/rubytest/RubyTester.hh"
366019Shines@cs.fsu.edu#include "debug/MemoryAccess.hh"
376019Shines@cs.fsu.edu#include "debug/ProtocolTrace.hh"
386019Shines@cs.fsu.edu#include "debug/RubySequencer.hh"
396019Shines@cs.fsu.edu#include "debug/RubyStats.hh"
407399SAli.Saidi@ARM.com#include "mem/protocol/PrefetchBit.hh"
417399SAli.Saidi@ARM.com#include "mem/protocol/RubyAccessMode.hh"
426019Shines@cs.fsu.edu#include "mem/ruby/buffers/MessageBuffer.hh"
436019Shines@cs.fsu.edu#include "mem/ruby/common/Global.hh"
446019Shines@cs.fsu.edu#include "mem/ruby/profiler/Profiler.hh"
4510873Sandreas.sandberg@arm.com#include "mem/ruby/slicc_interface/RubyRequest.hh"
4610873Sandreas.sandberg@arm.com#include "mem/ruby/system/Sequencer.hh"
4710474Sandreas.hansson@arm.com#include "mem/ruby/system/System.hh"
486019Shines@cs.fsu.edu#include "mem/packet.hh"
496019Shines@cs.fsu.edu
506019Shines@cs.fsu.eduusing namespace std;
516116Snate@binkert.org
526019Shines@cs.fsu.eduSequencer *
5311793Sbrandon.potter@amd.comRubySequencerParams::create()
5411793Sbrandon.potter@amd.com{
558782Sgblack@eecs.umich.edu    return new Sequencer(this);
568756Sgblack@eecs.umich.edu}
576019Shines@cs.fsu.edu
5812005Sandreas.sandberg@arm.comSequencer::Sequencer(const Params *p)
596019Shines@cs.fsu.edu    : RubyPort(p), deadlockCheckEvent(this)
606019Shines@cs.fsu.edu{
616019Shines@cs.fsu.edu    m_store_waiting_on_load_cycles = 0;
6210024Sdam.sunwoo@arm.com    m_store_waiting_on_store_cycles = 0;
636019Shines@cs.fsu.edu    m_load_waiting_on_store_cycles = 0;
648232Snate@binkert.org    m_load_waiting_on_load_cycles = 0;
658232Snate@binkert.org
668232Snate@binkert.org    m_outstanding_count = 0;
676116Snate@binkert.org
6811608Snikos.nikoleris@arm.com    m_instCache_ptr = p->icache;
696116Snate@binkert.org    m_dataCache_ptr = p->dcache;
708756Sgblack@eecs.umich.edu    m_max_outstanding_requests = p->max_outstanding_requests;
716019Shines@cs.fsu.edu    m_deadlock_threshold = p->deadlock_threshold;
726019Shines@cs.fsu.edu
736019Shines@cs.fsu.edu    assert(m_max_outstanding_requests > 0);
746019Shines@cs.fsu.edu    assert(m_deadlock_threshold > 0);
756019Shines@cs.fsu.edu    assert(m_instCache_ptr != NULL);
7610037SARM gem5 Developers    assert(m_dataCache_ptr != NULL);
7710037SARM gem5 Developers
7810418Sandreas.hansson@arm.com    m_usingNetworkTester = p->using_network_tester;
7910418Sandreas.hansson@arm.com}
8011395Sandreas.sandberg@arm.com
8110537Sandreas.hansson@arm.comSequencer::~Sequencer()
8210537Sandreas.hansson@arm.com{
8311152Smitch.hayenga@arm.com}
846019Shines@cs.fsu.edu
8512005Sandreas.sandberg@arm.comvoid
8612005Sandreas.sandberg@arm.comSequencer::wakeup()
8710037SARM gem5 Developers{
887399SAli.Saidi@ARM.com    // Check for deadlock of any of the requests
8910037SARM gem5 Developers    Time current_time = g_system_ptr->getTime();
9010037SARM gem5 Developers
9110037SARM gem5 Developers    // Check across all outstanding requests
9210037SARM gem5 Developers    int total_outstanding = 0;
9312005Sandreas.sandberg@arm.com
9412005Sandreas.sandberg@arm.com    RequestTable::iterator read = m_readRequestTable.begin();
9512005Sandreas.sandberg@arm.com    RequestTable::iterator read_end = m_readRequestTable.end();
966019Shines@cs.fsu.edu    for (; read != read_end; ++read) {
976019Shines@cs.fsu.edu        SequencerRequest* request = read->second;
986019Shines@cs.fsu.edu        if (current_time - request->issue_time < m_deadlock_threshold)
996019Shines@cs.fsu.edu            continue;
10010037SARM gem5 Developers
10110037SARM gem5 Developers        panic("Possible Deadlock detected. Aborting!\n"
10210037SARM gem5 Developers             "version: %d request.paddr: 0x%x m_readRequestTable: %d "
10310037SARM gem5 Developers             "current time: %u issue_time: %d difference: %d\n", m_version,
10410037SARM gem5 Developers             Address(request->pkt->getAddr()), m_readRequestTable.size(),
10510037SARM gem5 Developers             current_time, request->issue_time,
10610037SARM gem5 Developers             current_time - request->issue_time);
10710037SARM gem5 Developers    }
10810037SARM gem5 Developers
10910037SARM gem5 Developers    RequestTable::iterator write = m_writeRequestTable.begin();
11010037SARM gem5 Developers    RequestTable::iterator write_end = m_writeRequestTable.end();
11110717Sandreas.hansson@arm.com    for (; write != write_end; ++write) {
11210037SARM gem5 Developers        SequencerRequest* request = write->second;
11310037SARM gem5 Developers        if (current_time - request->issue_time < m_deadlock_threshold)
11410717Sandreas.hansson@arm.com            continue;
1156019Shines@cs.fsu.edu
1166019Shines@cs.fsu.edu        panic("Possible Deadlock detected. Aborting!\n"
1177694SAli.Saidi@ARM.com             "version: %d request.paddr: 0x%x m_writeRequestTable: %d "
1187694SAli.Saidi@ARM.com             "current time: %u issue_time: %d difference: %d\n", m_version,
1197694SAli.Saidi@ARM.com             Address(request->pkt->getAddr()), m_writeRequestTable.size(),
12010037SARM gem5 Developers             current_time, request->issue_time,
12110037SARM gem5 Developers             current_time - request->issue_time);
12210037SARM gem5 Developers    }
12310037SARM gem5 Developers
12410037SARM gem5 Developers    total_outstanding += m_writeRequestTable.size();
12510037SARM gem5 Developers    total_outstanding += m_readRequestTable.size();
12610037SARM gem5 Developers
12710037SARM gem5 Developers    assert(m_outstanding_count == total_outstanding);
12810037SARM gem5 Developers
1297694SAli.Saidi@ARM.com    if (m_outstanding_count > 0) {
1307694SAli.Saidi@ARM.com        // If there are still outstanding requests, keep checking
1317694SAli.Saidi@ARM.com        schedule(deadlockCheckEvent,
1327694SAli.Saidi@ARM.com                 m_deadlock_threshold * g_system_ptr->getClock() +
1337694SAli.Saidi@ARM.com                 curTick());
1347694SAli.Saidi@ARM.com    }
1359738Sandreas@sandberg.pp.se}
1369738Sandreas@sandberg.pp.se
1379738Sandreas@sandberg.pp.sevoid
13812005Sandreas.sandberg@arm.comSequencer::printStats(ostream & out) const
13912005Sandreas.sandberg@arm.com{
14012005Sandreas.sandberg@arm.com    out << "Sequencer: " << m_name << endl
14112005Sandreas.sandberg@arm.com        << "  store_waiting_on_load_cycles: "
14212005Sandreas.sandberg@arm.com        << m_store_waiting_on_load_cycles << endl
14312005Sandreas.sandberg@arm.com        << "  store_waiting_on_store_cycles: "
14412005Sandreas.sandberg@arm.com        << m_store_waiting_on_store_cycles << endl
14512005Sandreas.sandberg@arm.com        << "  load_waiting_on_load_cycles: "
14612005Sandreas.sandberg@arm.com        << m_load_waiting_on_load_cycles << endl
1479738Sandreas@sandberg.pp.se        << "  load_waiting_on_store_cycles: "
1489738Sandreas@sandberg.pp.se        << m_load_waiting_on_store_cycles << endl;
1499738Sandreas@sandberg.pp.se}
1507404SAli.Saidi@ARM.com
15110037SARM gem5 Developersvoid
15210037SARM gem5 DevelopersSequencer::printProgress(ostream& out) const
1536019Shines@cs.fsu.edu{
1547404SAli.Saidi@ARM.com#if 0
1557404SAli.Saidi@ARM.com    int total_demand = 0;
1567404SAli.Saidi@ARM.com    out << "Sequencer Stats Version " << m_version << endl;
15710037SARM gem5 Developers    out << "Current time = " << g_system_ptr->getTime() << endl;
1587404SAli.Saidi@ARM.com    out << "---------------" << endl;
1597404SAli.Saidi@ARM.com    out << "outstanding requests" << endl;
16010037SARM gem5 Developers
16110037SARM gem5 Developers    out << "proc " << m_Read
16210037SARM gem5 Developers        << " version Requests = " << m_readRequestTable.size() << endl;
16310037SARM gem5 Developers
16410037SARM gem5 Developers    // print the request table
1659535Smrinmoy.ghosh@arm.com    RequestTable::iterator read = m_readRequestTable.begin();
1667697SAli.Saidi@ARM.com    RequestTable::iterator read_end = m_readRequestTable.end();
16711321Ssteve.reinhardt@amd.com    for (; read != read_end; ++read) {
16810037SARM gem5 Developers        SequencerRequest* request = read->second;
1697697SAli.Saidi@ARM.com        out << "\tRequest[ " << i << " ] = " << request->type
1707697SAli.Saidi@ARM.com            << " Address " << rkeys[i]
1717697SAli.Saidi@ARM.com            << " Posted " << request->issue_time
1727697SAli.Saidi@ARM.com            << " PF " << PrefetchBit_No << endl;
1737697SAli.Saidi@ARM.com        total_demand++;
1747404SAli.Saidi@ARM.com    }
1757404SAli.Saidi@ARM.com
17610037SARM gem5 Developers    out << "proc " << m_version
1777404SAli.Saidi@ARM.com        << " Write Requests = " << m_writeRequestTable.size << endl;
1787404SAli.Saidi@ARM.com
17910037SARM gem5 Developers    // print the request table
18010037SARM gem5 Developers    RequestTable::iterator write = m_writeRequestTable.begin();
18110037SARM gem5 Developers    RequestTable::iterator write_end = m_writeRequestTable.end();
18210037SARM gem5 Developers    for (; write != write_end; ++write) {
18310037SARM gem5 Developers        SequencerRequest* request = write->second;
18410037SARM gem5 Developers        out << "\tRequest[ " << i << " ] = " << request.getType()
18510037SARM gem5 Developers            << " Address " << wkeys[i]
18610037SARM gem5 Developers            << " Posted " << request.getTime()
18710367SAndrew.Bardsley@arm.com            << " PF " << request.getPrefetch() << endl;
18810037SARM gem5 Developers        if (request.getPrefetch() == PrefetchBit_No) {
1897404SAli.Saidi@ARM.com            total_demand++;
1906019Shines@cs.fsu.edu        }
1916019Shines@cs.fsu.edu    }
1926019Shines@cs.fsu.edu
1936019Shines@cs.fsu.edu    out << endl;
1947404SAli.Saidi@ARM.com
1956019Shines@cs.fsu.edu    out << "Total Number Outstanding: " << m_outstanding_count << endl
1967404SAli.Saidi@ARM.com        << "Total Number Demand     : " << total_demand << endl
19710037SARM gem5 Developers        << "Total Number Prefetches : " << m_outstanding_count - total_demand
19810037SARM gem5 Developers        << endl << endl << endl;
19910037SARM gem5 Developers#endif
20010037SARM gem5 Developers}
20110037SARM gem5 Developers
20210037SARM gem5 Developers// Insert the request on the correct request table.  Return true if
2037404SAli.Saidi@ARM.com// the entry was already present.
20410037SARM gem5 DevelopersRequestStatus
20510037SARM gem5 DevelopersSequencer::insertRequest(PacketPtr pkt, RubyRequestType request_type)
20610037SARM gem5 Developers{
2077697SAli.Saidi@ARM.com    assert(m_outstanding_count ==
20810037SARM gem5 Developers        (m_writeRequestTable.size() + m_readRequestTable.size()));
20910037SARM gem5 Developers
21010037SARM gem5 Developers    // See if we should schedule a deadlock check
21110037SARM gem5 Developers    if (deadlockCheckEvent.scheduled() == false) {
2127404SAli.Saidi@ARM.com        schedule(deadlockCheckEvent,
2137697SAli.Saidi@ARM.com                 m_deadlock_threshold * g_system_ptr->getClock()
2147404SAli.Saidi@ARM.com                 + curTick());
21510037SARM gem5 Developers    }
21610037SARM gem5 Developers
2177697SAli.Saidi@ARM.com    Address line_addr(pkt->getAddr());
2187734SAli.Saidi@ARM.com    line_addr.makeLineAddress();
2197734SAli.Saidi@ARM.com    if ((request_type == RubyRequestType_ST) ||
22010463SAndreas.Sandberg@ARM.com        (request_type == RubyRequestType_RMW_Read) ||
2216019Shines@cs.fsu.edu        (request_type == RubyRequestType_RMW_Write) ||
2226019Shines@cs.fsu.edu        (request_type == RubyRequestType_Load_Linked) ||
2236019Shines@cs.fsu.edu        (request_type == RubyRequestType_Store_Conditional) ||
22410037SARM gem5 Developers        (request_type == RubyRequestType_Locked_RMW_Read) ||
2257404SAli.Saidi@ARM.com        (request_type == RubyRequestType_Locked_RMW_Write) ||
2267404SAli.Saidi@ARM.com        (request_type == RubyRequestType_FLUSH)) {
2277404SAli.Saidi@ARM.com
2287404SAli.Saidi@ARM.com        // Check if there is any outstanding read request for the same
2297404SAli.Saidi@ARM.com        // cache line.
23010037SARM gem5 Developers        if (m_readRequestTable.count(line_addr) > 0) {
23110037SARM gem5 Developers            m_store_waiting_on_load_cycles++;
23210037SARM gem5 Developers            return RequestStatus_Aliased;
23310037SARM gem5 Developers        }
2347404SAli.Saidi@ARM.com
2357404SAli.Saidi@ARM.com        pair<RequestTable::iterator, bool> r =
2367404SAli.Saidi@ARM.com            m_writeRequestTable.insert(RequestTable::value_type(line_addr, 0));
2377404SAli.Saidi@ARM.com        if (r.second) {
23810037SARM gem5 Developers            RequestTable::iterator i = r.first;
2396019Shines@cs.fsu.edu            i->second = new SequencerRequest(pkt, request_type,
24010037SARM gem5 Developers                                             g_system_ptr->getTime());
24110037SARM gem5 Developers            m_outstanding_count++;
2427404SAli.Saidi@ARM.com        } else {
2437404SAli.Saidi@ARM.com          // There is an outstanding write request for the cache line
2447404SAli.Saidi@ARM.com          m_store_waiting_on_store_cycles++;
24510037SARM gem5 Developers          return RequestStatus_Aliased;
24610037SARM gem5 Developers        }
24710037SARM gem5 Developers    } else {
24810037SARM gem5 Developers        // Check if there is any outstanding write request for the same
24910037SARM gem5 Developers        // cache line.
25010037SARM gem5 Developers        if (m_writeRequestTable.count(line_addr) > 0) {
25110037SARM gem5 Developers            m_load_waiting_on_store_cycles++;
25210037SARM gem5 Developers            return RequestStatus_Aliased;
25310037SARM gem5 Developers        }
25410037SARM gem5 Developers
2557404SAli.Saidi@ARM.com        pair<RequestTable::iterator, bool> r =
2567404SAli.Saidi@ARM.com            m_readRequestTable.insert(RequestTable::value_type(line_addr, 0));
25710037SARM gem5 Developers
25810037SARM gem5 Developers        if (r.second) {
25910037SARM gem5 Developers            RequestTable::iterator i = r.first;
26010037SARM gem5 Developers            i->second = new SequencerRequest(pkt, request_type,
26110037SARM gem5 Developers                                             g_system_ptr->getTime());
26210037SARM gem5 Developers            m_outstanding_count++;
26310037SARM gem5 Developers        } else {
26410037SARM gem5 Developers            // There is an outstanding read request for the cache line
26510037SARM gem5 Developers            m_load_waiting_on_load_cycles++;
26610037SARM gem5 Developers            return RequestStatus_Aliased;
26710037SARM gem5 Developers        }
26810037SARM gem5 Developers    }
26910037SARM gem5 Developers
27010037SARM gem5 Developers    g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count);
27110037SARM gem5 Developers    assert(m_outstanding_count ==
27210037SARM gem5 Developers        (m_writeRequestTable.size() + m_readRequestTable.size()));
27310037SARM gem5 Developers
27410037SARM gem5 Developers    return RequestStatus_Ready;
27510037SARM gem5 Developers}
27610037SARM gem5 Developers
27710037SARM gem5 Developersvoid
27810037SARM gem5 DevelopersSequencer::markRemoved()
27910037SARM gem5 Developers{
28010037SARM gem5 Developers    m_outstanding_count--;
28110037SARM gem5 Developers    assert(m_outstanding_count ==
28210037SARM gem5 Developers           m_writeRequestTable.size() + m_readRequestTable.size());
28310037SARM gem5 Developers}
2847734SAli.Saidi@ARM.com
2857734SAli.Saidi@ARM.comvoid
28610037SARM gem5 DevelopersSequencer::removeRequest(SequencerRequest* srequest)
28710037SARM gem5 Developers{
28810037SARM gem5 Developers    assert(m_outstanding_count ==
28910037SARM gem5 Developers           m_writeRequestTable.size() + m_readRequestTable.size());
29010037SARM gem5 Developers
2916019Shines@cs.fsu.edu    Address line_addr(srequest->pkt->getAddr());
2926019Shines@cs.fsu.edu    line_addr.makeLineAddress();
2937404SAli.Saidi@ARM.com    if ((srequest->m_type == RubyRequestType_ST) ||
29410037SARM gem5 Developers        (srequest->m_type == RubyRequestType_RMW_Read) ||
2957404SAli.Saidi@ARM.com        (srequest->m_type == RubyRequestType_RMW_Write) ||
29610037SARM gem5 Developers        (srequest->m_type == RubyRequestType_Load_Linked) ||
29710037SARM gem5 Developers        (srequest->m_type == RubyRequestType_Store_Conditional) ||
29810037SARM gem5 Developers        (srequest->m_type == RubyRequestType_Locked_RMW_Read) ||
29910037SARM gem5 Developers        (srequest->m_type == RubyRequestType_Locked_RMW_Write)) {
3007734SAli.Saidi@ARM.com        m_writeRequestTable.erase(line_addr);
3017404SAli.Saidi@ARM.com    } else {
3027404SAli.Saidi@ARM.com        m_readRequestTable.erase(line_addr);
3037404SAli.Saidi@ARM.com    }
30410037SARM gem5 Developers
3057404SAli.Saidi@ARM.com    markRemoved();
30610037SARM gem5 Developers}
30710037SARM gem5 Developers
3087404SAli.Saidi@ARM.combool
30910037SARM gem5 DevelopersSequencer::handleLlsc(const Address& address, SequencerRequest* request)
3107404SAli.Saidi@ARM.com{
3117404SAli.Saidi@ARM.com    //
3127404SAli.Saidi@ARM.com    // The success flag indicates whether the LLSC operation was successful.
3137404SAli.Saidi@ARM.com    // LL ops will always succeed, but SC may fail if the cache line is no
31410037SARM gem5 Developers    // longer locked.
31510037SARM gem5 Developers    //
31610037SARM gem5 Developers    bool success = true;
31710037SARM gem5 Developers    if (request->m_type == RubyRequestType_Store_Conditional) {
3187404SAli.Saidi@ARM.com        if (!m_dataCache_ptr->isLocked(address, m_version)) {
31910037SARM gem5 Developers            //
3207734SAli.Saidi@ARM.com            // For failed SC requests, indicate the failure to the cpu by
3217404SAli.Saidi@ARM.com            // setting the extra data to zero.
32210037SARM gem5 Developers            //
3237404SAli.Saidi@ARM.com            request->pkt->req->setExtraData(0);
3247734SAli.Saidi@ARM.com            success = false;
3257404SAli.Saidi@ARM.com        } else {
3267404SAli.Saidi@ARM.com            //
3277404SAli.Saidi@ARM.com            // For successful SC requests, indicate the success to the cpu by
32810037SARM gem5 Developers            // setting the extra data to one.
3297404SAli.Saidi@ARM.com            //
33010037SARM gem5 Developers            request->pkt->req->setExtraData(1);
33110037SARM gem5 Developers        }
33210037SARM gem5 Developers        //
33310037SARM gem5 Developers        // Independent of success, all SC operations must clear the lock
33410037SARM gem5 Developers        //
3357404SAli.Saidi@ARM.com        m_dataCache_ptr->clearLocked(address);
33610037SARM gem5 Developers    } else if (request->m_type == RubyRequestType_Load_Linked) {
33710037SARM gem5 Developers        //
33810037SARM gem5 Developers        // Note: To fully follow Alpha LLSC semantics, should the LL clear any
33910037SARM gem5 Developers        // previously locked cache lines?
3407404SAli.Saidi@ARM.com        //
34110037SARM gem5 Developers        m_dataCache_ptr->setLocked(address, m_version);
34210037SARM gem5 Developers    } else if ((m_dataCache_ptr->isTagPresent(address)) &&
34310037SARM gem5 Developers               (m_dataCache_ptr->isLocked(address, m_version))) {
34410037SARM gem5 Developers        //
34510037SARM gem5 Developers        // Normal writes should clear the locked address
34610037SARM gem5 Developers        //
34710037SARM gem5 Developers        m_dataCache_ptr->clearLocked(address);
3487404SAli.Saidi@ARM.com    }
3497734SAli.Saidi@ARM.com    return success;
3507404SAli.Saidi@ARM.com}
35110037SARM gem5 Developers
35210037SARM gem5 Developersvoid
3537404SAli.Saidi@ARM.comSequencer::writeCallback(const Address& address, DataBlock& data)
35410037SARM gem5 Developers{
35510037SARM gem5 Developers    writeCallback(address, GenericMachineType_NULL, data);
35611584SDylan.Johnson@ARM.com}
35711584SDylan.Johnson@ARM.com
35811584SDylan.Johnson@ARM.comvoid
35911584SDylan.Johnson@ARM.comSequencer::writeCallback(const Address& address,
36011584SDylan.Johnson@ARM.com                         GenericMachineType mach,
36111584SDylan.Johnson@ARM.com                         DataBlock& data)
36211584SDylan.Johnson@ARM.com{
36310037SARM gem5 Developers    writeCallback(address, mach, data, 0, 0, 0);
36410037SARM gem5 Developers}
36510037SARM gem5 Developers
36610037SARM gem5 Developersvoid
36710037SARM gem5 DevelopersSequencer::writeCallback(const Address& address,
36810037SARM gem5 Developers                         GenericMachineType mach,
36910037SARM gem5 Developers                         DataBlock& data,
37010037SARM gem5 Developers                         Time initialRequestTime,
37110037SARM gem5 Developers                         Time forwardRequestTime,
37210037SARM gem5 Developers                         Time firstResponseTime)
37310037SARM gem5 Developers{
37410037SARM gem5 Developers    assert(address == line_address(address));
3757404SAli.Saidi@ARM.com    assert(m_writeRequestTable.count(line_address(address)));
3767404SAli.Saidi@ARM.com
3776019Shines@cs.fsu.edu    RequestTable::iterator i = m_writeRequestTable.find(address);
3789439SAndreas.Sandberg@ARM.com    assert(i != m_writeRequestTable.end());
3799439SAndreas.Sandberg@ARM.com    SequencerRequest* request = i->second;
3809439SAndreas.Sandberg@ARM.com
3819439SAndreas.Sandberg@ARM.com    m_writeRequestTable.erase(i);
3829439SAndreas.Sandberg@ARM.com    markRemoved();
3839439SAndreas.Sandberg@ARM.com
3849439SAndreas.Sandberg@ARM.com    assert((request->m_type == RubyRequestType_ST) ||
3859439SAndreas.Sandberg@ARM.com           (request->m_type == RubyRequestType_ATOMIC) ||
38610194SGeoffrey.Blake@arm.com           (request->m_type == RubyRequestType_RMW_Read) ||
38710194SGeoffrey.Blake@arm.com           (request->m_type == RubyRequestType_RMW_Write) ||
38810194SGeoffrey.Blake@arm.com           (request->m_type == RubyRequestType_Load_Linked) ||
38910194SGeoffrey.Blake@arm.com           (request->m_type == RubyRequestType_Store_Conditional) ||
39010194SGeoffrey.Blake@arm.com           (request->m_type == RubyRequestType_Locked_RMW_Read) ||
39110194SGeoffrey.Blake@arm.com           (request->m_type == RubyRequestType_Locked_RMW_Write) ||
39210194SGeoffrey.Blake@arm.com           (request->m_type == RubyRequestType_FLUSH));
39310194SGeoffrey.Blake@arm.com
39410194SGeoffrey.Blake@arm.com
39510194SGeoffrey.Blake@arm.com    //
39610194SGeoffrey.Blake@arm.com    // For Alpha, properly handle LL, SC, and write requests with respect to
39710194SGeoffrey.Blake@arm.com    // locked cache blocks.
39810194SGeoffrey.Blake@arm.com    //
39910194SGeoffrey.Blake@arm.com    // Not valid for Network_test protocl
40010194SGeoffrey.Blake@arm.com    //
40110194SGeoffrey.Blake@arm.com    bool success = true;
40210194SGeoffrey.Blake@arm.com    if(!m_usingNetworkTester)
40310194SGeoffrey.Blake@arm.com        success = handleLlsc(address, request);
40410194SGeoffrey.Blake@arm.com
40510194SGeoffrey.Blake@arm.com    if (request->m_type == RubyRequestType_Locked_RMW_Read) {
40610194SGeoffrey.Blake@arm.com        m_controller->blockOnQueue(address, m_mandatory_q_ptr);
40710194SGeoffrey.Blake@arm.com    } else if (request->m_type == RubyRequestType_Locked_RMW_Write) {
40810194SGeoffrey.Blake@arm.com        m_controller->unblock(address);
40910905Sandreas.sandberg@arm.com    }
4106019Shines@cs.fsu.edu
4117733SAli.Saidi@ARM.com    hitCallback(request, mach, data, success,
4127733SAli.Saidi@ARM.com                initialRequestTime, forwardRequestTime, firstResponseTime);
4137733SAli.Saidi@ARM.com}
41410037SARM gem5 Developers
41510037SARM gem5 Developersvoid
41610037SARM gem5 DevelopersSequencer::readCallback(const Address& address, DataBlock& data)
4178353SAli.Saidi@ARM.com{
4188353SAli.Saidi@ARM.com    readCallback(address, GenericMachineType_NULL, data);
4198353SAli.Saidi@ARM.com}
42011321Ssteve.reinhardt@amd.com
42110905Sandreas.sandberg@arm.comvoid
4226019Shines@cs.fsu.eduSequencer::readCallback(const Address& address,
4236019Shines@cs.fsu.edu                        GenericMachineType mach,
4246019Shines@cs.fsu.edu                        DataBlock& data)
42510905Sandreas.sandberg@arm.com{
4266019Shines@cs.fsu.edu    readCallback(address, mach, data, 0, 0, 0);
4277733SAli.Saidi@ARM.com}
4286019Shines@cs.fsu.edu
4297733SAli.Saidi@ARM.comvoid
43010037SARM gem5 DevelopersSequencer::readCallback(const Address& address,
43110037SARM gem5 Developers                        GenericMachineType mach,
43210037SARM gem5 Developers                        DataBlock& data,
43310037SARM gem5 Developers                        Time initialRequestTime,
4348353SAli.Saidi@ARM.com                        Time forwardRequestTime,
4358353SAli.Saidi@ARM.com                        Time firstResponseTime)
43611321Ssteve.reinhardt@amd.com{
43710905Sandreas.sandberg@arm.com    assert(address == line_address(address));
4386019Shines@cs.fsu.edu    assert(m_readRequestTable.count(line_address(address)));
4396019Shines@cs.fsu.edu
4406019Shines@cs.fsu.edu    RequestTable::iterator i = m_readRequestTable.find(address);
4416019Shines@cs.fsu.edu    assert(i != m_readRequestTable.end());
4426019Shines@cs.fsu.edu    SequencerRequest* request = i->second;
44311522Sstephan.diestelhorst@arm.com
4447734SAli.Saidi@ARM.com    m_readRequestTable.erase(i);
4457734SAli.Saidi@ARM.com    markRemoved();
4467734SAli.Saidi@ARM.com
4477734SAli.Saidi@ARM.com    assert((request->m_type == RubyRequestType_LD) ||
4487734SAli.Saidi@ARM.com           (request->m_type == RubyRequestType_IFETCH));
4497734SAli.Saidi@ARM.com
4507734SAli.Saidi@ARM.com    hitCallback(request, mach, data, true,
4517734SAli.Saidi@ARM.com                initialRequestTime, forwardRequestTime, firstResponseTime);
4527734SAli.Saidi@ARM.com}
4537734SAli.Saidi@ARM.com
4547734SAli.Saidi@ARM.comvoid
4557734SAli.Saidi@ARM.comSequencer::hitCallback(SequencerRequest* srequest,
4567734SAli.Saidi@ARM.com                       GenericMachineType mach,
4577734SAli.Saidi@ARM.com                       DataBlock& data,
4587734SAli.Saidi@ARM.com                       bool success,
4597734SAli.Saidi@ARM.com                       Time initialRequestTime,
4606019Shines@cs.fsu.edu                       Time forwardRequestTime,
4616019Shines@cs.fsu.edu                       Time firstResponseTime)
4626019Shines@cs.fsu.edu{
4636019Shines@cs.fsu.edu    PacketPtr pkt = srequest->pkt;
4647734SAli.Saidi@ARM.com    Address request_address(pkt->getAddr());
4656019Shines@cs.fsu.edu    Address request_line_address(pkt->getAddr());
4666019Shines@cs.fsu.edu    request_line_address.makeLineAddress();
4676019Shines@cs.fsu.edu    RubyRequestType type = srequest->m_type;
4686019Shines@cs.fsu.edu    Time issued_time = srequest->issue_time;
4697734SAli.Saidi@ARM.com
4706019Shines@cs.fsu.edu    // Set this cache entry to the most recently used
4716019Shines@cs.fsu.edu    if (type == RubyRequestType_IFETCH) {
4726019Shines@cs.fsu.edu        m_instCache_ptr->setMRU(request_line_address);
4736019Shines@cs.fsu.edu    } else {
4747734SAli.Saidi@ARM.com        m_dataCache_ptr->setMRU(request_line_address);
4756019Shines@cs.fsu.edu    }
4766019Shines@cs.fsu.edu
4776019Shines@cs.fsu.edu    assert(g_system_ptr->getTime() >= issued_time);
4786019Shines@cs.fsu.edu    Time miss_latency = g_system_ptr->getTime() - issued_time;
4797734SAli.Saidi@ARM.com
4806019Shines@cs.fsu.edu    // Profile the miss latency for all non-zero demand misses
4816019Shines@cs.fsu.edu    if (miss_latency != 0) {
4826019Shines@cs.fsu.edu        g_system_ptr->getProfiler()->missLatency(miss_latency, type, mach);
4836019Shines@cs.fsu.edu
4847734SAli.Saidi@ARM.com        if (mach == GenericMachineType_L1Cache_wCC) {
4856019Shines@cs.fsu.edu            g_system_ptr->getProfiler()->missLatencyWcc(issued_time,
4866019Shines@cs.fsu.edu                                                   initialRequestTime,
4876019Shines@cs.fsu.edu                                                   forwardRequestTime,
4886019Shines@cs.fsu.edu                                                   firstResponseTime,
4896019Shines@cs.fsu.edu                                                   g_system_ptr->getTime());
4906019Shines@cs.fsu.edu        }
4916019Shines@cs.fsu.edu
4926019Shines@cs.fsu.edu        if (mach == GenericMachineType_Directory) {
4936019Shines@cs.fsu.edu            g_system_ptr->getProfiler()->missLatencyDir(issued_time,
4946019Shines@cs.fsu.edu                                                   initialRequestTime,
4956019Shines@cs.fsu.edu                                                   forwardRequestTime,
4966019Shines@cs.fsu.edu                                                   firstResponseTime,
4976019Shines@cs.fsu.edu                                                   g_system_ptr->getTime());
4986019Shines@cs.fsu.edu        }
4996019Shines@cs.fsu.edu
5006019Shines@cs.fsu.edu        DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %d cycles\n",
5016019Shines@cs.fsu.edu                 curTick(), m_version, "Seq",
5026019Shines@cs.fsu.edu                 success ? "Done" : "SC_Failed", "", "",
5036019Shines@cs.fsu.edu                 request_address, miss_latency);
5047734SAli.Saidi@ARM.com    }
5057734SAli.Saidi@ARM.com
5067734SAli.Saidi@ARM.com    // update the data
5077734SAli.Saidi@ARM.com    if (g_system_ptr->m_warmup_enabled) {
5087734SAli.Saidi@ARM.com        assert(pkt->getPtr<uint8_t>(false) != NULL);
5097734SAli.Saidi@ARM.com        data.setData(pkt->getPtr<uint8_t>(false),
5107734SAli.Saidi@ARM.com                     request_address.getOffset(), pkt->getSize());
5117734SAli.Saidi@ARM.com    } else if (pkt->getPtr<uint8_t>(true) != NULL) {
5127734SAli.Saidi@ARM.com        if ((type == RubyRequestType_LD) ||
5137734SAli.Saidi@ARM.com            (type == RubyRequestType_IFETCH) ||
5147734SAli.Saidi@ARM.com            (type == RubyRequestType_RMW_Read) ||
5157734SAli.Saidi@ARM.com            (type == RubyRequestType_Locked_RMW_Read) ||
5167734SAli.Saidi@ARM.com            (type == RubyRequestType_Load_Linked)) {
5177734SAli.Saidi@ARM.com            memcpy(pkt->getPtr<uint8_t>(true),
5187734SAli.Saidi@ARM.com                   data.getData(request_address.getOffset(), pkt->getSize()),
5197734SAli.Saidi@ARM.com                   pkt->getSize());
5207734SAli.Saidi@ARM.com        } else {
5217734SAli.Saidi@ARM.com            data.setData(pkt->getPtr<uint8_t>(true),
5227734SAli.Saidi@ARM.com                         request_address.getOffset(), pkt->getSize());
5237734SAli.Saidi@ARM.com        }
5247734SAli.Saidi@ARM.com    } else {
5257734SAli.Saidi@ARM.com        DPRINTF(MemoryAccess,
5267734SAli.Saidi@ARM.com                "WARNING.  Data not transfered from Ruby to M5 for type %s\n",
5277734SAli.Saidi@ARM.com                RubyRequestType_to_string(type));
5287734SAli.Saidi@ARM.com    }
5297734SAli.Saidi@ARM.com
5307734SAli.Saidi@ARM.com    // If using the RubyTester, update the RubyTester sender state's
5317734SAli.Saidi@ARM.com    // subBlock with the recieved data.  The tester will later access
5327734SAli.Saidi@ARM.com    // this state.
5337734SAli.Saidi@ARM.com    // Note: RubyPort will access it's sender state before the
5347734SAli.Saidi@ARM.com    // RubyTester.
5357734SAli.Saidi@ARM.com    if (m_usingRubyTester) {
5367734SAli.Saidi@ARM.com        RubyPort::SenderState *requestSenderState =
5377734SAli.Saidi@ARM.com            safe_cast<RubyPort::SenderState*>(pkt->senderState);
5387734SAli.Saidi@ARM.com        RubyTester::SenderState* testerSenderState =
5397734SAli.Saidi@ARM.com            safe_cast<RubyTester::SenderState*>(requestSenderState->saved);
5407734SAli.Saidi@ARM.com        testerSenderState->subBlock->mergeFrom(data);
5417734SAli.Saidi@ARM.com    }
5427734SAli.Saidi@ARM.com
5437734SAli.Saidi@ARM.com    delete srequest;
5447734SAli.Saidi@ARM.com
5457734SAli.Saidi@ARM.com    if (g_system_ptr->m_warmup_enabled) {
5467734SAli.Saidi@ARM.com        delete pkt;
5477734SAli.Saidi@ARM.com        g_system_ptr->m_cache_recorder->enqueueNextFetchRequest();
5487734SAli.Saidi@ARM.com    } else if (g_system_ptr->m_cooldown_enabled) {
5497734SAli.Saidi@ARM.com        delete pkt;
5507734SAli.Saidi@ARM.com        g_system_ptr->m_cache_recorder->enqueueNextFlushRequest();
5517734SAli.Saidi@ARM.com    } else {
5527734SAli.Saidi@ARM.com        ruby_hit_callback(pkt);
5537734SAli.Saidi@ARM.com    }
5547734SAli.Saidi@ARM.com}
5556019Shines@cs.fsu.edu
5566019Shines@cs.fsu.edubool
55710463SAndreas.Sandberg@ARM.comSequencer::empty() const
55810463SAndreas.Sandberg@ARM.com{
55910463SAndreas.Sandberg@ARM.com    return m_writeRequestTable.empty() && m_readRequestTable.empty();
56010463SAndreas.Sandberg@ARM.com}
56110463SAndreas.Sandberg@ARM.com
56210463SAndreas.Sandberg@ARM.comRequestStatus
5637404SAli.Saidi@ARM.comSequencer::makeRequest(PacketPtr pkt)
5647404SAli.Saidi@ARM.com{
56510037SARM gem5 Developers    if (m_outstanding_count >= m_max_outstanding_requests) {
5667404SAli.Saidi@ARM.com        return RequestStatus_BufferFull;
56710037SARM gem5 Developers    }
56810037SARM gem5 Developers
56910037SARM gem5 Developers    RubyRequestType primary_type = RubyRequestType_NULL;
57010037SARM gem5 Developers    RubyRequestType secondary_type = RubyRequestType_NULL;
57110854SNathanael.Premillieu@arm.com
57210037SARM gem5 Developers    if (pkt->isLLSC()) {
57310037SARM gem5 Developers        //
57411608Snikos.nikoleris@arm.com        // Alpha LL/SC instructions need to be handled carefully by the cache
5757294Sgblack@eecs.umich.edu        // coherence protocol to ensure they follow the proper semantics. In
5767404SAli.Saidi@ARM.com        // particular, by identifying the operations as atomic, the protocol
5777404SAli.Saidi@ARM.com        // should understand that migratory sharing optimizations should not
5787404SAli.Saidi@ARM.com        // be performed (i.e. a load between the LL and SC should not steal
5797404SAli.Saidi@ARM.com        // away exclusive permission).
5807294Sgblack@eecs.umich.edu        //
5817404SAli.Saidi@ARM.com        if (pkt->isWrite()) {
58210037SARM gem5 Developers            DPRINTF(RubySequencer, "Issuing SC\n");
58310037SARM gem5 Developers            primary_type = RubyRequestType_Store_Conditional;
58410474Sandreas.hansson@arm.com        } else {
58510474Sandreas.hansson@arm.com            DPRINTF(RubySequencer, "Issuing LL\n");
58610474Sandreas.hansson@arm.com            assert(pkt->isRead());
58710474Sandreas.hansson@arm.com            primary_type = RubyRequestType_Load_Linked;
58810474Sandreas.hansson@arm.com        }
5897294Sgblack@eecs.umich.edu        secondary_type = RubyRequestType_ATOMIC;
5907294Sgblack@eecs.umich.edu    } else if (pkt->req->isLocked()) {
5917294Sgblack@eecs.umich.edu        //
5926019Shines@cs.fsu.edu        // x86 locked instructions are translated to store cache coherence
5937093Sgblack@eecs.umich.edu        // requests because these requests should always be treated as read
5947404SAli.Saidi@ARM.com        // exclusive operations and should leverage any migratory sharing
5957404SAli.Saidi@ARM.com        // optimization built into the protocol.
5967093Sgblack@eecs.umich.edu        //
59710474Sandreas.hansson@arm.com        if (pkt->isWrite()) {
5987093Sgblack@eecs.umich.edu            DPRINTF(RubySequencer, "Issuing Locked RMW Write\n");
5996019Shines@cs.fsu.edu            primary_type = RubyRequestType_Locked_RMW_Write;
60012005Sandreas.sandberg@arm.com        } else {
6017404SAli.Saidi@ARM.com            DPRINTF(RubySequencer, "Issuing Locked RMW Read\n");
6027404SAli.Saidi@ARM.com            assert(pkt->isRead());
6037404SAli.Saidi@ARM.com            primary_type = RubyRequestType_Locked_RMW_Read;
60410037SARM gem5 Developers        }
60510037SARM gem5 Developers        secondary_type = RubyRequestType_ST;
60610037SARM gem5 Developers    } else {
60711608Snikos.nikoleris@arm.com        if (pkt->isRead()) {
60810037SARM gem5 Developers            if (pkt->req->isInstFetch()) {
60910037SARM gem5 Developers                primary_type = secondary_type = RubyRequestType_IFETCH;
61010037SARM gem5 Developers            } else {
61110037SARM gem5 Developers#if THE_ISA == X86_ISA
61210037SARM gem5 Developers                uint32_t flags = pkt->req->getFlags();
61310037SARM gem5 Developers                bool storeCheck = flags &
61410037SARM gem5 Developers                        (TheISA::StoreCheck << TheISA::FlagShift);
61510037SARM gem5 Developers#else
61610037SARM gem5 Developers                bool storeCheck = false;
61710037SARM gem5 Developers#endif // X86_ISA
61810037SARM gem5 Developers                if (storeCheck) {
61910037SARM gem5 Developers                    primary_type = RubyRequestType_RMW_Read;
62010037SARM gem5 Developers                    secondary_type = RubyRequestType_ST;
62110037SARM gem5 Developers                } else {
62210474Sandreas.hansson@arm.com                    primary_type = secondary_type = RubyRequestType_LD;
62310474Sandreas.hansson@arm.com                }
62410474Sandreas.hansson@arm.com            }
62510474Sandreas.hansson@arm.com        } else if (pkt->isWrite()) {
62610037SARM gem5 Developers            //
62710037SARM gem5 Developers            // Note: M5 packets do not differentiate ST from RMW_Write
62810037SARM gem5 Developers            //
62910037SARM gem5 Developers            primary_type = secondary_type = RubyRequestType_ST;
63010037SARM gem5 Developers        } else if (pkt->isFlush()) {
63110037SARM gem5 Developers          primary_type = secondary_type = RubyRequestType_FLUSH;
63210037SARM gem5 Developers        } else {
63310037SARM gem5 Developers            panic("Unsupported ruby packet type\n");
63410474Sandreas.hansson@arm.com        }
63510474Sandreas.hansson@arm.com    }
63610474Sandreas.hansson@arm.com
63710474Sandreas.hansson@arm.com    RequestStatus status = insertRequest(pkt, primary_type);
63810037SARM gem5 Developers    if (status != RequestStatus_Ready)
63910037SARM gem5 Developers        return status;
64010037SARM gem5 Developers
64110037SARM gem5 Developers    issueRequest(pkt, secondary_type);
64210037SARM gem5 Developers
64310037SARM gem5 Developers    // TODO: issue hardware prefetches here
64410037SARM gem5 Developers    return RequestStatus_Issued;
64510037SARM gem5 Developers}
64610037SARM gem5 Developers
64710474Sandreas.hansson@arm.comvoid
64810474Sandreas.hansson@arm.comSequencer::issueRequest(PacketPtr pkt, RubyRequestType secondary_type)
64910474Sandreas.hansson@arm.com{
65010037SARM gem5 Developers    int proc_id = -1;
65110037SARM gem5 Developers    if (pkt != NULL && pkt->req->hasContextId()) {
65210037SARM gem5 Developers        proc_id = pkt->req->contextId();
65310037SARM gem5 Developers    }
65410037SARM gem5 Developers
65510037SARM gem5 Developers    // If valid, copy the pc to the ruby request
65610037SARM gem5 Developers    Addr pc = 0;
65710037SARM gem5 Developers    if (pkt->req->hasPC()) {
65810037SARM gem5 Developers        pc = pkt->req->getPC();
65910037SARM gem5 Developers    }
66011861Snikos.nikoleris@arm.com
66111861Snikos.nikoleris@arm.com    RubyRequest *msg = new RubyRequest(pkt->getAddr(),
66211861Snikos.nikoleris@arm.com                                       pkt->getPtr<uint8_t>(true),
66311861Snikos.nikoleris@arm.com                                       pkt->getSize(), pc, secondary_type,
66410474Sandreas.hansson@arm.com                                       RubyAccessMode_Supervisor, pkt,
66511861Snikos.nikoleris@arm.com                                       PrefetchBit_No, proc_id);
66610474Sandreas.hansson@arm.com
66710474Sandreas.hansson@arm.com    DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %s\n",
66811861Snikos.nikoleris@arm.com            curTick(), m_version, "Seq", "Begin", "", "",
66910474Sandreas.hansson@arm.com            msg->getPhysicalAddress(),
67010474Sandreas.hansson@arm.com            RubyRequestType_to_string(secondary_type));
67110474Sandreas.hansson@arm.com
67210474Sandreas.hansson@arm.com    Time latency = 0;  // initialzed to an null value
67310037SARM gem5 Developers
67410037SARM gem5 Developers    if (secondary_type == RubyRequestType_IFETCH)
67510037SARM gem5 Developers        latency = m_instCache_ptr->getLatency();
67610037SARM gem5 Developers    else
67710037SARM gem5 Developers        latency = m_dataCache_ptr->getLatency();
67810037SARM gem5 Developers
67910037SARM gem5 Developers    // Send the message to the cache controller
68010037SARM gem5 Developers    assert(latency > 0);
68110037SARM gem5 Developers
68210037SARM gem5 Developers    assert(m_mandatory_q_ptr != NULL);
68310037SARM gem5 Developers    m_mandatory_q_ptr->enqueue(msg, latency);
68410037SARM gem5 Developers}
68510037SARM gem5 Developers
68610037SARM gem5 Developerstemplate <class KEY, class VALUE>
68710037SARM gem5 Developersstd::ostream &
68810037SARM gem5 Developersoperator<<(ostream &out, const m5::hash_map<KEY, VALUE> &map)
68910037SARM gem5 Developers{
69010037SARM gem5 Developers    typename m5::hash_map<KEY, VALUE>::const_iterator i = map.begin();
69110037SARM gem5 Developers    typename m5::hash_map<KEY, VALUE>::const_iterator end = map.end();
69210037SARM gem5 Developers
69310037SARM gem5 Developers    out << "[";
69410037SARM gem5 Developers    for (; i != end; ++i)
69510037SARM gem5 Developers        out << " " << i->first << "=" << i->second;
69610037SARM gem5 Developers    out << " ]";
69710037SARM gem5 Developers
69810037SARM gem5 Developers    return out;
69910037SARM gem5 Developers}
70010037SARM gem5 Developers
70110037SARM gem5 Developersvoid
70210037SARM gem5 DevelopersSequencer::print(ostream& out) const
70310037SARM gem5 Developers{
70410037SARM gem5 Developers    out << "[Sequencer: " << m_version
70510037SARM gem5 Developers        << ", outstanding requests: " << m_outstanding_count
70610037SARM gem5 Developers        << ", read request table: " << m_readRequestTable
70710037SARM gem5 Developers        << ", write request table: " << m_writeRequestTable
70810037SARM gem5 Developers        << "]";
70910037SARM gem5 Developers}
71010037SARM gem5 Developers
71110037SARM gem5 Developers// this can be called from setState whenever coherence permissions are
71210037SARM gem5 Developers// upgraded when invoked, coherence violations will be checked for the
71310037SARM gem5 Developers// given block
71410037SARM gem5 Developersvoid
71510037SARM gem5 DevelopersSequencer::checkCoherence(const Address& addr)
71610037SARM gem5 Developers{
71710037SARM gem5 Developers#ifdef CHECK_COHERENCE
71810037SARM gem5 Developers    g_system_ptr->checkGlobalCoherenceInvariant(addr);
71910037SARM gem5 Developers#endif
72010037SARM gem5 Developers}
72110037SARM gem5 Developers
72210037SARM gem5 Developersvoid
72310037SARM gem5 DevelopersSequencer::recordRequestType(SequencerRequestType requestType) {
72410037SARM gem5 Developers    DPRINTF(RubyStats, "Recorded statistic: %s\n",
72510037SARM gem5 Developers            SequencerRequestType_to_string(requestType));
72610037SARM gem5 Developers}
72710037SARM gem5 Developers
72810037SARM gem5 Developers
72910037SARM gem5 Developersvoid
73010037SARM gem5 DevelopersSequencer::evictionCallback(const Address& address)
73110037SARM gem5 Developers{
73210037SARM gem5 Developers    ruby_eviction_callback(address);
73310037SARM gem5 Developers}
73410037SARM gem5 Developers