Sequencer.cc revision 6151
16145Snate@binkert.org
26145Snate@binkert.org/*
36145Snate@binkert.org * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
46145Snate@binkert.org * All rights reserved.
56145Snate@binkert.org *
66145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
76145Snate@binkert.org * modification, are permitted provided that the following conditions are
86145Snate@binkert.org * met: redistributions of source code must retain the above copyright
96145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
106145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
116145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
126145Snate@binkert.org * documentation and/or other materials provided with the distribution;
136145Snate@binkert.org * neither the name of the copyright holders nor the names of its
146145Snate@binkert.org * contributors may be used to endorse or promote products derived from
156145Snate@binkert.org * this software without specific prior written permission.
166145Snate@binkert.org *
176145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286145Snate@binkert.org */
296145Snate@binkert.org
306145Snate@binkert.org/*
316145Snate@binkert.org * $Id: Sequencer.C 1.131 2006/11/06 17:41:01-06:00 bobba@gratiano.cs.wisc.edu $
326145Snate@binkert.org *
336145Snate@binkert.org */
346145Snate@binkert.org
356145Snate@binkert.org#include "Global.hh"
366145Snate@binkert.org#include "Sequencer.hh"
376145Snate@binkert.org#include "System.hh"
386145Snate@binkert.org#include "Protocol.hh"
396145Snate@binkert.org#include "Profiler.hh"
406145Snate@binkert.org#include "CacheMemory.hh"
416145Snate@binkert.org#include "RubyConfig.hh"
426145Snate@binkert.org//#include "Tracer.hh"
436145Snate@binkert.org#include "AbstractChip.hh"
446145Snate@binkert.org#include "Chip.hh"
456145Snate@binkert.org#include "Tester.hh"
466145Snate@binkert.org#include "SubBlock.hh"
476145Snate@binkert.org#include "Protocol.hh"
486145Snate@binkert.org#include "Map.hh"
496145Snate@binkert.org#include "interface.hh"
506145Snate@binkert.org//#include "XactCommitArbiter.hh"
516145Snate@binkert.org// #include "TransactionInterfaceManager.hh"
526145Snate@binkert.org//#include "TransactionVersionManager.hh"
536145Snate@binkert.org//#include "LazyTransactionVersionManager.hh"
546145Snate@binkert.org
556145Snate@binkert.org//#define XACT_MGR g_system_ptr->getChip(m_chip_ptr->getID())->getTransactionInterfaceManager(m_version)
566145Snate@binkert.org
576145Snate@binkert.orgSequencer::Sequencer(AbstractChip* chip_ptr, int version) {
586145Snate@binkert.org  m_chip_ptr = chip_ptr;
596145Snate@binkert.org  m_version = version;
606145Snate@binkert.org
616145Snate@binkert.org  m_deadlock_check_scheduled = false;
626145Snate@binkert.org  m_outstanding_count = 0;
636145Snate@binkert.org
646145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
656145Snate@binkert.org  m_writeRequestTable_ptr = new Map<Address, CacheMsg>*[smt_threads];
666145Snate@binkert.org  m_readRequestTable_ptr = new Map<Address, CacheMsg>*[smt_threads];
676145Snate@binkert.org
686145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
696145Snate@binkert.org    m_writeRequestTable_ptr[p] = new Map<Address, CacheMsg>;
706145Snate@binkert.org    m_readRequestTable_ptr[p] = new Map<Address, CacheMsg>;
716145Snate@binkert.org  }
726145Snate@binkert.org
736145Snate@binkert.org}
746145Snate@binkert.org
756145Snate@binkert.orgSequencer::~Sequencer() {
766145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
776145Snate@binkert.org  for(int i=0; i < smt_threads; ++i){
786145Snate@binkert.org    if(m_writeRequestTable_ptr[i]){
796145Snate@binkert.org      delete m_writeRequestTable_ptr[i];
806145Snate@binkert.org    }
816145Snate@binkert.org    if(m_readRequestTable_ptr[i]){
826145Snate@binkert.org      delete m_readRequestTable_ptr[i];
836145Snate@binkert.org    }
846145Snate@binkert.org  }
856145Snate@binkert.org  if(m_writeRequestTable_ptr){
866145Snate@binkert.org    delete [] m_writeRequestTable_ptr;
876145Snate@binkert.org  }
886145Snate@binkert.org  if(m_readRequestTable_ptr){
896145Snate@binkert.org    delete [] m_readRequestTable_ptr;
906145Snate@binkert.org  }
916145Snate@binkert.org}
926145Snate@binkert.org
936145Snate@binkert.orgvoid Sequencer::wakeup() {
946145Snate@binkert.org  // Check for deadlock of any of the requests
956145Snate@binkert.org  Time current_time = g_eventQueue_ptr->getTime();
966145Snate@binkert.org  bool deadlock = false;
976145Snate@binkert.org
986145Snate@binkert.org  // Check across all outstanding requests
996145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
1006145Snate@binkert.org  int total_outstanding = 0;
1016145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
1026145Snate@binkert.org    Vector<Address> keys = m_readRequestTable_ptr[p]->keys();
1036145Snate@binkert.org    for (int i=0; i<keys.size(); i++) {
1046145Snate@binkert.org      CacheMsg& request = m_readRequestTable_ptr[p]->lookup(keys[i]);
1056145Snate@binkert.org      if (current_time - request.getTime() >= g_DEADLOCK_THRESHOLD) {
1066145Snate@binkert.org        WARN_MSG("Possible Deadlock detected");
1076145Snate@binkert.org        WARN_EXPR(request);
1086145Snate@binkert.org        WARN_EXPR(m_chip_ptr->getID());
1096145Snate@binkert.org        WARN_EXPR(m_version);
1106145Snate@binkert.org        WARN_EXPR(keys.size());
1116145Snate@binkert.org        WARN_EXPR(current_time);
1126145Snate@binkert.org        WARN_EXPR(request.getTime());
1136145Snate@binkert.org        WARN_EXPR(current_time - request.getTime());
1146145Snate@binkert.org        WARN_EXPR(*m_readRequestTable_ptr[p]);
1156145Snate@binkert.org        ERROR_MSG("Aborting");
1166145Snate@binkert.org        deadlock = true;
1176145Snate@binkert.org      }
1186145Snate@binkert.org    }
1196145Snate@binkert.org
1206145Snate@binkert.org    keys = m_writeRequestTable_ptr[p]->keys();
1216145Snate@binkert.org    for (int i=0; i<keys.size(); i++) {
1226145Snate@binkert.org      CacheMsg& request = m_writeRequestTable_ptr[p]->lookup(keys[i]);
1236145Snate@binkert.org      if (current_time - request.getTime() >= g_DEADLOCK_THRESHOLD) {
1246145Snate@binkert.org        WARN_MSG("Possible Deadlock detected");
1256145Snate@binkert.org        WARN_EXPR(request);
1266145Snate@binkert.org        WARN_EXPR(m_chip_ptr->getID());
1276145Snate@binkert.org        WARN_EXPR(m_version);
1286145Snate@binkert.org        WARN_EXPR(current_time);
1296145Snate@binkert.org        WARN_EXPR(request.getTime());
1306145Snate@binkert.org        WARN_EXPR(current_time - request.getTime());
1316145Snate@binkert.org        WARN_EXPR(keys.size());
1326145Snate@binkert.org        WARN_EXPR(*m_writeRequestTable_ptr[p]);
1336145Snate@binkert.org        ERROR_MSG("Aborting");
1346145Snate@binkert.org        deadlock = true;
1356145Snate@binkert.org      }
1366145Snate@binkert.org    }
1376145Snate@binkert.org    total_outstanding += m_writeRequestTable_ptr[p]->size() + m_readRequestTable_ptr[p]->size();
1386145Snate@binkert.org  }  // across all request tables
1396145Snate@binkert.org  assert(m_outstanding_count == total_outstanding);
1406145Snate@binkert.org
1416145Snate@binkert.org  if (m_outstanding_count > 0) { // If there are still outstanding requests, keep checking
1426145Snate@binkert.org    g_eventQueue_ptr->scheduleEvent(this, g_DEADLOCK_THRESHOLD);
1436145Snate@binkert.org  } else {
1446145Snate@binkert.org    m_deadlock_check_scheduled = false;
1456145Snate@binkert.org  }
1466145Snate@binkert.org}
1476145Snate@binkert.org
1486145Snate@binkert.org//returns the total number of requests
1496145Snate@binkert.orgint Sequencer::getNumberOutstanding(){
1506145Snate@binkert.org  return m_outstanding_count;
1516145Snate@binkert.org}
1526145Snate@binkert.org
1536145Snate@binkert.org// returns the total number of demand requests
1546145Snate@binkert.orgint Sequencer::getNumberOutstandingDemand(){
1556145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
1566145Snate@binkert.org  int total_demand = 0;
1576145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
1586145Snate@binkert.org    Vector<Address> keys = m_readRequestTable_ptr[p]->keys();
1596145Snate@binkert.org    for (int i=0; i< keys.size(); i++) {
1606145Snate@binkert.org      CacheMsg& request = m_readRequestTable_ptr[p]->lookup(keys[i]);
1616145Snate@binkert.org      // don't count transactional begin/commit requests
1626145Snate@binkert.org      if(request.getType() != CacheRequestType_BEGIN_XACT && request.getType() != CacheRequestType_COMMIT_XACT){
1636145Snate@binkert.org        if(request.getPrefetch() == PrefetchBit_No){
1646145Snate@binkert.org          total_demand++;
1656145Snate@binkert.org        }
1666145Snate@binkert.org      }
1676145Snate@binkert.org    }
1686145Snate@binkert.org
1696145Snate@binkert.org    keys = m_writeRequestTable_ptr[p]->keys();
1706145Snate@binkert.org    for (int i=0; i< keys.size(); i++) {
1716145Snate@binkert.org      CacheMsg& request = m_writeRequestTable_ptr[p]->lookup(keys[i]);
1726145Snate@binkert.org      if(request.getPrefetch() == PrefetchBit_No){
1736145Snate@binkert.org        total_demand++;
1746145Snate@binkert.org      }
1756145Snate@binkert.org    }
1766145Snate@binkert.org  }
1776145Snate@binkert.org
1786145Snate@binkert.org  return total_demand;
1796145Snate@binkert.org}
1806145Snate@binkert.org
1816145Snate@binkert.orgint Sequencer::getNumberOutstandingPrefetch(){
1826145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
1836145Snate@binkert.org  int total_prefetch = 0;
1846145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
1856145Snate@binkert.org    Vector<Address> keys = m_readRequestTable_ptr[p]->keys();
1866145Snate@binkert.org    for (int i=0; i< keys.size(); i++) {
1876145Snate@binkert.org      CacheMsg& request = m_readRequestTable_ptr[p]->lookup(keys[i]);
1886145Snate@binkert.org      if(request.getPrefetch() == PrefetchBit_Yes){
1896145Snate@binkert.org        total_prefetch++;
1906145Snate@binkert.org      }
1916145Snate@binkert.org    }
1926145Snate@binkert.org
1936145Snate@binkert.org    keys = m_writeRequestTable_ptr[p]->keys();
1946145Snate@binkert.org    for (int i=0; i< keys.size(); i++) {
1956145Snate@binkert.org      CacheMsg& request = m_writeRequestTable_ptr[p]->lookup(keys[i]);
1966145Snate@binkert.org      if(request.getPrefetch() == PrefetchBit_Yes){
1976145Snate@binkert.org        total_prefetch++;
1986145Snate@binkert.org      }
1996145Snate@binkert.org    }
2006145Snate@binkert.org  }
2016145Snate@binkert.org
2026145Snate@binkert.org  return total_prefetch;
2036145Snate@binkert.org}
2046145Snate@binkert.org
2056145Snate@binkert.orgbool Sequencer::isPrefetchRequest(const Address & lineaddr){
2066145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
2076145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
2086145Snate@binkert.org    // check load requests
2096145Snate@binkert.org    Vector<Address> keys = m_readRequestTable_ptr[p]->keys();
2106145Snate@binkert.org    for (int i=0; i< keys.size(); i++) {
2116145Snate@binkert.org      CacheMsg& request = m_readRequestTable_ptr[p]->lookup(keys[i]);
2126145Snate@binkert.org      if(line_address(request.getAddress()) == lineaddr){
2136145Snate@binkert.org        if(request.getPrefetch() == PrefetchBit_Yes){
2146145Snate@binkert.org          return true;
2156145Snate@binkert.org        }
2166145Snate@binkert.org        else{
2176145Snate@binkert.org          return false;
2186145Snate@binkert.org        }
2196145Snate@binkert.org      }
2206145Snate@binkert.org    }
2216145Snate@binkert.org
2226145Snate@binkert.org    // check store requests
2236145Snate@binkert.org    keys = m_writeRequestTable_ptr[p]->keys();
2246145Snate@binkert.org    for (int i=0; i< keys.size(); i++) {
2256145Snate@binkert.org      CacheMsg& request = m_writeRequestTable_ptr[p]->lookup(keys[i]);
2266145Snate@binkert.org      if(line_address(request.getAddress()) == lineaddr){
2276145Snate@binkert.org        if(request.getPrefetch() == PrefetchBit_Yes){
2286145Snate@binkert.org          return true;
2296145Snate@binkert.org        }
2306145Snate@binkert.org        else{
2316145Snate@binkert.org          return false;
2326145Snate@binkert.org        }
2336145Snate@binkert.org      }
2346145Snate@binkert.org    }
2356145Snate@binkert.org  }
2366145Snate@binkert.org  // we should've found a matching request
2376145Snate@binkert.org  cout << "isRequestPrefetch() ERROR request NOT FOUND : " << lineaddr << endl;
2386145Snate@binkert.org  printProgress(cout);
2396145Snate@binkert.org  assert(0);
2406145Snate@binkert.org}
2416145Snate@binkert.org
2426145Snate@binkert.orgAccessModeType Sequencer::getAccessModeOfRequest(Address addr, int thread){
2436145Snate@binkert.org  if(m_readRequestTable_ptr[thread]->exist(line_address(addr))){
2446145Snate@binkert.org    CacheMsg& request = m_readRequestTable_ptr[thread]->lookup(addr);
2456145Snate@binkert.org    return request.getAccessMode();
2466145Snate@binkert.org  } else if(m_writeRequestTable_ptr[thread]->exist(line_address(addr))){
2476145Snate@binkert.org    CacheMsg& request = m_writeRequestTable_ptr[thread]->lookup(addr);
2486145Snate@binkert.org    return request.getAccessMode();
2496145Snate@binkert.org  } else {
2506145Snate@binkert.org    printProgress(cout);
2516145Snate@binkert.org    ERROR_MSG("Request not found in RequestTables");
2526145Snate@binkert.org  }
2536145Snate@binkert.org}
2546145Snate@binkert.org
2556145Snate@binkert.orgAddress Sequencer::getLogicalAddressOfRequest(Address addr, int thread){
2566145Snate@binkert.org  assert(thread >= 0);
2576145Snate@binkert.org  if(m_readRequestTable_ptr[thread]->exist(line_address(addr))){
2586145Snate@binkert.org    CacheMsg& request = m_readRequestTable_ptr[thread]->lookup(addr);
2596145Snate@binkert.org    return request.getLogicalAddress();
2606145Snate@binkert.org  } else if(m_writeRequestTable_ptr[thread]->exist(line_address(addr))){
2616145Snate@binkert.org    CacheMsg& request = m_writeRequestTable_ptr[thread]->lookup(addr);
2626145Snate@binkert.org    return request.getLogicalAddress();
2636145Snate@binkert.org  } else {
2646145Snate@binkert.org    printProgress(cout);
2656145Snate@binkert.org    WARN_MSG("Request not found in RequestTables");
2666145Snate@binkert.org    WARN_MSG(addr);
2676145Snate@binkert.org    WARN_MSG(thread);
2686145Snate@binkert.org    ASSERT(0);
2696145Snate@binkert.org  }
2706145Snate@binkert.org}
2716145Snate@binkert.org
2726145Snate@binkert.org// returns the ThreadID of the request
2736145Snate@binkert.orgint Sequencer::getRequestThreadID(const Address & addr){
2746145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
2756145Snate@binkert.org  int thread = -1;
2766145Snate@binkert.org  int num_found = 0;
2776145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
2786145Snate@binkert.org    if(m_readRequestTable_ptr[p]->exist(addr)){
2796145Snate@binkert.org      num_found++;
2806145Snate@binkert.org      thread = p;
2816145Snate@binkert.org    }
2826145Snate@binkert.org    if(m_writeRequestTable_ptr[p]->exist(addr)){
2836145Snate@binkert.org      num_found++;
2846145Snate@binkert.org      thread = p;
2856145Snate@binkert.org    }
2866145Snate@binkert.org  }
2876145Snate@binkert.org  if(num_found != 1){
2886145Snate@binkert.org    cout << "getRequestThreadID ERROR too many matching requests addr = " << addr << endl;
2896145Snate@binkert.org    printProgress(cout);
2906145Snate@binkert.org  }
2916145Snate@binkert.org  ASSERT(num_found == 1);
2926145Snate@binkert.org  ASSERT(thread != -1);
2936145Snate@binkert.org
2946145Snate@binkert.org  return thread;
2956145Snate@binkert.org}
2966145Snate@binkert.org
2976145Snate@binkert.org// given a line address, return the request's physical address
2986145Snate@binkert.orgAddress Sequencer::getRequestPhysicalAddress(const Address & lineaddr){
2996145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
3006145Snate@binkert.org  Address physaddr;
3016145Snate@binkert.org  int num_found = 0;
3026145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
3036145Snate@binkert.org    if(m_readRequestTable_ptr[p]->exist(lineaddr)){
3046145Snate@binkert.org      num_found++;
3056145Snate@binkert.org      physaddr = (m_readRequestTable_ptr[p]->lookup(lineaddr)).getAddress();
3066145Snate@binkert.org    }
3076145Snate@binkert.org    if(m_writeRequestTable_ptr[p]->exist(lineaddr)){
3086145Snate@binkert.org      num_found++;
3096145Snate@binkert.org      physaddr = (m_writeRequestTable_ptr[p]->lookup(lineaddr)).getAddress();
3106145Snate@binkert.org    }
3116145Snate@binkert.org  }
3126145Snate@binkert.org  if(num_found != 1){
3136145Snate@binkert.org    cout << "getRequestPhysicalAddress ERROR too many matching requests addr = " << lineaddr << endl;
3146145Snate@binkert.org    printProgress(cout);
3156145Snate@binkert.org  }
3166145Snate@binkert.org  ASSERT(num_found == 1);
3176145Snate@binkert.org
3186145Snate@binkert.org  return physaddr;
3196145Snate@binkert.org}
3206145Snate@binkert.org
3216145Snate@binkert.orgvoid Sequencer::printProgress(ostream& out) const{
3226145Snate@binkert.org
3236145Snate@binkert.org  int total_demand = 0;
3246145Snate@binkert.org  out << "Sequencer Stats Version " << m_version << endl;
3256145Snate@binkert.org  out << "Current time = " << g_eventQueue_ptr->getTime() << endl;
3266145Snate@binkert.org  out << "---------------" << endl;
3276145Snate@binkert.org  out << "outstanding requests" << endl;
3286145Snate@binkert.org
3296145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
3306145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
3316145Snate@binkert.org    Vector<Address> rkeys = m_readRequestTable_ptr[p]->keys();
3326145Snate@binkert.org    int read_size = rkeys.size();
3336145Snate@binkert.org    out << "proc " << m_chip_ptr->getID() << " thread " << p << " Read Requests = " << read_size << endl;
3346145Snate@binkert.org    // print the request table
3356145Snate@binkert.org    for(int i=0; i < read_size; ++i){
3366145Snate@binkert.org      CacheMsg & request = m_readRequestTable_ptr[p]->lookup(rkeys[i]);
3376145Snate@binkert.org      out << "\tRequest[ " << i << " ] = " << request.getType() << " Address " << rkeys[i]  << " Posted " << request.getTime() << " PF " << request.getPrefetch() << endl;
3386145Snate@binkert.org      if( request.getPrefetch() == PrefetchBit_No ){
3396145Snate@binkert.org        total_demand++;
3406145Snate@binkert.org      }
3416145Snate@binkert.org    }
3426145Snate@binkert.org
3436145Snate@binkert.org    Vector<Address> wkeys = m_writeRequestTable_ptr[p]->keys();
3446145Snate@binkert.org    int write_size = wkeys.size();
3456145Snate@binkert.org    out << "proc " << m_chip_ptr->getID() << " thread " << p << " Write Requests = " << write_size << endl;
3466145Snate@binkert.org    // print the request table
3476145Snate@binkert.org    for(int i=0; i < write_size; ++i){
3486145Snate@binkert.org      CacheMsg & request = m_writeRequestTable_ptr[p]->lookup(wkeys[i]);
3496145Snate@binkert.org      out << "\tRequest[ " << i << " ] = " << request.getType() << " Address " << wkeys[i]  << " Posted " << request.getTime() << " PF " << request.getPrefetch() << endl;
3506145Snate@binkert.org      if( request.getPrefetch() == PrefetchBit_No ){
3516145Snate@binkert.org        total_demand++;
3526145Snate@binkert.org      }
3536145Snate@binkert.org    }
3546145Snate@binkert.org
3556145Snate@binkert.org    out << endl;
3566145Snate@binkert.org  }
3576145Snate@binkert.org  out << "Total Number Outstanding: " << m_outstanding_count << endl;
3586145Snate@binkert.org  out << "Total Number Demand     : " << total_demand << endl;
3596145Snate@binkert.org  out << "Total Number Prefetches : " << m_outstanding_count - total_demand << endl;
3606145Snate@binkert.org  out << endl;
3616145Snate@binkert.org  out << endl;
3626145Snate@binkert.org
3636145Snate@binkert.org}
3646145Snate@binkert.org
3656145Snate@binkert.orgvoid Sequencer::printConfig(ostream& out) {
3666145Snate@binkert.org  if (TSO) {
3676145Snate@binkert.org    out << "sequencer: Sequencer - TSO" << endl;
3686145Snate@binkert.org  } else {
3696145Snate@binkert.org    out << "sequencer: Sequencer - SC" << endl;
3706145Snate@binkert.org  }
3716145Snate@binkert.org  out << "  max_outstanding_requests: " << g_SEQUENCER_OUTSTANDING_REQUESTS << endl;
3726145Snate@binkert.org}
3736145Snate@binkert.org
3746145Snate@binkert.orgbool Sequencer::empty() const {
3756145Snate@binkert.org  return m_outstanding_count == 0;
3766145Snate@binkert.org}
3776145Snate@binkert.org
3786145Snate@binkert.org// Insert the request on the correct request table.  Return true if
3796145Snate@binkert.org// the entry was already present.
3806145Snate@binkert.orgbool Sequencer::insertRequest(const CacheMsg& request) {
3816145Snate@binkert.org  int thread = request.getThreadID();
3826145Snate@binkert.org  assert(thread >= 0);
3836145Snate@binkert.org  int total_outstanding = 0;
3846145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
3856145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
3866145Snate@binkert.org    total_outstanding += m_writeRequestTable_ptr[p]->size() + m_readRequestTable_ptr[p]->size();
3876145Snate@binkert.org  }
3886145Snate@binkert.org  assert(m_outstanding_count == total_outstanding);
3896145Snate@binkert.org
3906145Snate@binkert.org  // See if we should schedule a deadlock check
3916145Snate@binkert.org  if (m_deadlock_check_scheduled == false) {
3926145Snate@binkert.org    g_eventQueue_ptr->scheduleEvent(this, g_DEADLOCK_THRESHOLD);
3936145Snate@binkert.org    m_deadlock_check_scheduled = true;
3946145Snate@binkert.org  }
3956145Snate@binkert.org
3966145Snate@binkert.org  if ((request.getType() == CacheRequestType_ST) ||
3976145Snate@binkert.org      (request.getType() == CacheRequestType_ST_XACT) ||
3986145Snate@binkert.org      (request.getType() == CacheRequestType_LDX_XACT) ||
3996145Snate@binkert.org      (request.getType() == CacheRequestType_ATOMIC)) {
4006145Snate@binkert.org    if (m_writeRequestTable_ptr[thread]->exist(line_address(request.getAddress()))) {
4016145Snate@binkert.org      m_writeRequestTable_ptr[thread]->lookup(line_address(request.getAddress())) = request;
4026145Snate@binkert.org      return true;
4036145Snate@binkert.org    }
4046145Snate@binkert.org    m_writeRequestTable_ptr[thread]->allocate(line_address(request.getAddress()));
4056145Snate@binkert.org    m_writeRequestTable_ptr[thread]->lookup(line_address(request.getAddress())) = request;
4066145Snate@binkert.org    m_outstanding_count++;
4076145Snate@binkert.org  } else {
4086145Snate@binkert.org    if (m_readRequestTable_ptr[thread]->exist(line_address(request.getAddress()))) {
4096145Snate@binkert.org      m_readRequestTable_ptr[thread]->lookup(line_address(request.getAddress())) = request;
4106145Snate@binkert.org      return true;
4116145Snate@binkert.org    }
4126145Snate@binkert.org    m_readRequestTable_ptr[thread]->allocate(line_address(request.getAddress()));
4136145Snate@binkert.org    m_readRequestTable_ptr[thread]->lookup(line_address(request.getAddress())) = request;
4146145Snate@binkert.org    m_outstanding_count++;
4156145Snate@binkert.org  }
4166145Snate@binkert.org
4176145Snate@binkert.org  g_system_ptr->getProfiler()->sequencerRequests(m_outstanding_count);
4186145Snate@binkert.org
4196145Snate@binkert.org  total_outstanding = 0;
4206145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
4216145Snate@binkert.org    total_outstanding += m_writeRequestTable_ptr[p]->size() + m_readRequestTable_ptr[p]->size();
4226145Snate@binkert.org  }
4236145Snate@binkert.org
4246145Snate@binkert.org  assert(m_outstanding_count == total_outstanding);
4256145Snate@binkert.org  return false;
4266145Snate@binkert.org}
4276145Snate@binkert.org
4286145Snate@binkert.orgvoid Sequencer::removeRequest(const CacheMsg& request) {
4296145Snate@binkert.org  int thread = request.getThreadID();
4306145Snate@binkert.org  assert(thread >= 0);
4316145Snate@binkert.org  int total_outstanding = 0;
4326145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
4336145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
4346145Snate@binkert.org    total_outstanding += m_writeRequestTable_ptr[p]->size() + m_readRequestTable_ptr[p]->size();
4356145Snate@binkert.org  }
4366145Snate@binkert.org  assert(m_outstanding_count == total_outstanding);
4376145Snate@binkert.org
4386145Snate@binkert.org  if ((request.getType() == CacheRequestType_ST) ||
4396145Snate@binkert.org      (request.getType() == CacheRequestType_ST_XACT) ||
4406145Snate@binkert.org      (request.getType() == CacheRequestType_LDX_XACT) ||
4416145Snate@binkert.org      (request.getType() == CacheRequestType_ATOMIC)) {
4426145Snate@binkert.org    m_writeRequestTable_ptr[thread]->deallocate(line_address(request.getAddress()));
4436145Snate@binkert.org  } else {
4446145Snate@binkert.org    m_readRequestTable_ptr[thread]->deallocate(line_address(request.getAddress()));
4456145Snate@binkert.org  }
4466145Snate@binkert.org  m_outstanding_count--;
4476145Snate@binkert.org
4486145Snate@binkert.org  total_outstanding = 0;
4496145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
4506145Snate@binkert.org    total_outstanding += m_writeRequestTable_ptr[p]->size() + m_readRequestTable_ptr[p]->size();
4516145Snate@binkert.org  }
4526145Snate@binkert.org  assert(m_outstanding_count == total_outstanding);
4536145Snate@binkert.org}
4546145Snate@binkert.org
4556145Snate@binkert.orgvoid Sequencer::writeCallback(const Address& address) {
4566145Snate@binkert.org  DataBlock data;
4576145Snate@binkert.org  writeCallback(address, data);
4586145Snate@binkert.org}
4596145Snate@binkert.org
4606145Snate@binkert.orgvoid Sequencer::writeCallback(const Address& address, DataBlock& data) {
4616145Snate@binkert.org  // process oldest thread first
4626145Snate@binkert.org  int thread = -1;
4636145Snate@binkert.org  Time oldest_time = 0;
4646145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
4656145Snate@binkert.org  for(int t=0; t < smt_threads; ++t){
4666145Snate@binkert.org    if(m_writeRequestTable_ptr[t]->exist(address)){
4676145Snate@binkert.org      CacheMsg & request = m_writeRequestTable_ptr[t]->lookup(address);
4686145Snate@binkert.org      if(thread == -1 || (request.getTime() < oldest_time) ){
4696145Snate@binkert.org        thread = t;
4706145Snate@binkert.org        oldest_time = request.getTime();
4716145Snate@binkert.org      }
4726145Snate@binkert.org    }
4736145Snate@binkert.org  }
4746145Snate@binkert.org  // make sure we found an oldest thread
4756145Snate@binkert.org  ASSERT(thread != -1);
4766145Snate@binkert.org
4776145Snate@binkert.org  CacheMsg & request = m_writeRequestTable_ptr[thread]->lookup(address);
4786145Snate@binkert.org
4796145Snate@binkert.org  writeCallback(address, data, GenericMachineType_NULL, PrefetchBit_No, thread);
4806145Snate@binkert.org}
4816145Snate@binkert.org
4826145Snate@binkert.orgvoid Sequencer::writeCallback(const Address& address, DataBlock& data, GenericMachineType respondingMach, PrefetchBit pf, int thread) {
4836145Snate@binkert.org
4846145Snate@binkert.org  assert(address == line_address(address));
4856145Snate@binkert.org  assert(thread >= 0);
4866145Snate@binkert.org  assert(m_writeRequestTable_ptr[thread]->exist(line_address(address)));
4876145Snate@binkert.org
4886145Snate@binkert.org  writeCallback(address, data, respondingMach, thread);
4896145Snate@binkert.org
4906145Snate@binkert.org}
4916145Snate@binkert.org
4926145Snate@binkert.orgvoid Sequencer::writeCallback(const Address& address, DataBlock& data, GenericMachineType respondingMach, int thread) {
4936145Snate@binkert.org  assert(address == line_address(address));
4946145Snate@binkert.org  assert(m_writeRequestTable_ptr[thread]->exist(line_address(address)));
4956145Snate@binkert.org  CacheMsg request = m_writeRequestTable_ptr[thread]->lookup(address);
4966145Snate@binkert.org  assert( request.getThreadID() == thread);
4976145Snate@binkert.org  removeRequest(request);
4986145Snate@binkert.org
4996145Snate@binkert.org  assert((request.getType() == CacheRequestType_ST) ||
5006145Snate@binkert.org         (request.getType() == CacheRequestType_ST_XACT) ||
5016145Snate@binkert.org         (request.getType() == CacheRequestType_LDX_XACT) ||
5026145Snate@binkert.org         (request.getType() == CacheRequestType_ATOMIC));
5036145Snate@binkert.org
5046145Snate@binkert.org  hitCallback(request, data, respondingMach, thread);
5056145Snate@binkert.org
5066145Snate@binkert.org}
5076145Snate@binkert.org
5086145Snate@binkert.orgvoid Sequencer::readCallback(const Address& address) {
5096145Snate@binkert.org  DataBlock data;
5106145Snate@binkert.org  readCallback(address, data);
5116145Snate@binkert.org}
5126145Snate@binkert.org
5136145Snate@binkert.orgvoid Sequencer::readCallback(const Address& address, DataBlock& data) {
5146145Snate@binkert.org  // process oldest thread first
5156145Snate@binkert.org  int thread = -1;
5166145Snate@binkert.org  Time oldest_time = 0;
5176145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
5186145Snate@binkert.org  for(int t=0; t < smt_threads; ++t){
5196145Snate@binkert.org    if(m_readRequestTable_ptr[t]->exist(address)){
5206145Snate@binkert.org      CacheMsg & request = m_readRequestTable_ptr[t]->lookup(address);
5216145Snate@binkert.org      if(thread == -1 || (request.getTime() < oldest_time) ){
5226145Snate@binkert.org        thread = t;
5236145Snate@binkert.org        oldest_time = request.getTime();
5246145Snate@binkert.org      }
5256145Snate@binkert.org    }
5266145Snate@binkert.org  }
5276145Snate@binkert.org  // make sure we found an oldest thread
5286145Snate@binkert.org  ASSERT(thread != -1);
5296145Snate@binkert.org
5306145Snate@binkert.org  CacheMsg & request = m_readRequestTable_ptr[thread]->lookup(address);
5316145Snate@binkert.org
5326145Snate@binkert.org  readCallback(address, data, GenericMachineType_NULL, PrefetchBit_No, thread);
5336145Snate@binkert.org}
5346145Snate@binkert.org
5356145Snate@binkert.orgvoid Sequencer::readCallback(const Address& address, DataBlock& data, GenericMachineType respondingMach, PrefetchBit pf, int thread) {
5366145Snate@binkert.org
5376145Snate@binkert.org  assert(address == line_address(address));
5386145Snate@binkert.org  assert(m_readRequestTable_ptr[thread]->exist(line_address(address)));
5396145Snate@binkert.org
5406145Snate@binkert.org  readCallback(address, data, respondingMach, thread);
5416145Snate@binkert.org}
5426145Snate@binkert.org
5436145Snate@binkert.orgvoid Sequencer::readCallback(const Address& address, DataBlock& data, GenericMachineType respondingMach, int thread) {
5446145Snate@binkert.org  assert(address == line_address(address));
5456145Snate@binkert.org  assert(m_readRequestTable_ptr[thread]->exist(line_address(address)));
5466145Snate@binkert.org
5476145Snate@binkert.org  CacheMsg request = m_readRequestTable_ptr[thread]->lookup(address);
5486145Snate@binkert.org  assert( request.getThreadID() == thread );
5496145Snate@binkert.org  removeRequest(request);
5506145Snate@binkert.org
5516145Snate@binkert.org  assert((request.getType() == CacheRequestType_LD) ||
5526145Snate@binkert.org         (request.getType() == CacheRequestType_LD_XACT) ||
5536145Snate@binkert.org         (request.getType() == CacheRequestType_IFETCH)
5546145Snate@binkert.org         );
5556145Snate@binkert.org
5566145Snate@binkert.org  hitCallback(request, data, respondingMach, thread);
5576145Snate@binkert.org}
5586145Snate@binkert.org
5596145Snate@binkert.orgvoid Sequencer::hitCallback(const CacheMsg& request, DataBlock& data, GenericMachineType respondingMach, int thread) {
5606145Snate@binkert.org  int size = request.getSize();
5616145Snate@binkert.org  Address request_address = request.getAddress();
5626145Snate@binkert.org  Address request_logical_address = request.getLogicalAddress();
5636145Snate@binkert.org  Address request_line_address = line_address(request_address);
5646145Snate@binkert.org  CacheRequestType type = request.getType();
5656145Snate@binkert.org  int threadID = request.getThreadID();
5666145Snate@binkert.org  Time issued_time = request.getTime();
5676145Snate@binkert.org  int logical_proc_no = ((m_chip_ptr->getID() * RubyConfig::numberOfProcsPerChip()) + m_version) * RubyConfig::numberofSMTThreads() + threadID;
5686145Snate@binkert.org
5696145Snate@binkert.org  DEBUG_MSG(SEQUENCER_COMP, MedPrio, size);
5706145Snate@binkert.org
5716145Snate@binkert.org  // Set this cache entry to the most recently used
5726145Snate@binkert.org  if (type == CacheRequestType_IFETCH) {
5736145Snate@binkert.org    if (Protocol::m_TwoLevelCache) {
5746145Snate@binkert.org      if (m_chip_ptr->m_L1Cache_L1IcacheMemory_vec[m_version]->isTagPresent(request_line_address)) {
5756145Snate@binkert.org        m_chip_ptr->m_L1Cache_L1IcacheMemory_vec[m_version]->setMRU(request_line_address);
5766145Snate@binkert.org      }
5776145Snate@binkert.org    }
5786145Snate@binkert.org    else {
5796145Snate@binkert.org      if (m_chip_ptr->m_L1Cache_cacheMemory_vec[m_version]->isTagPresent(request_line_address)) {
5806145Snate@binkert.org        m_chip_ptr->m_L1Cache_cacheMemory_vec[m_version]->setMRU(request_line_address);
5816145Snate@binkert.org      }
5826145Snate@binkert.org    }
5836145Snate@binkert.org  } else {
5846145Snate@binkert.org    if (Protocol::m_TwoLevelCache) {
5856145Snate@binkert.org      if (m_chip_ptr->m_L1Cache_L1DcacheMemory_vec[m_version]->isTagPresent(request_line_address)) {
5866145Snate@binkert.org        m_chip_ptr->m_L1Cache_L1DcacheMemory_vec[m_version]->setMRU(request_line_address);
5876145Snate@binkert.org      }
5886145Snate@binkert.org    }
5896145Snate@binkert.org    else {
5906145Snate@binkert.org      if (m_chip_ptr->m_L1Cache_cacheMemory_vec[m_version]->isTagPresent(request_line_address)) {
5916145Snate@binkert.org        m_chip_ptr->m_L1Cache_cacheMemory_vec[m_version]->setMRU(request_line_address);
5926145Snate@binkert.org      }
5936145Snate@binkert.org    }
5946145Snate@binkert.org  }
5956145Snate@binkert.org
5966145Snate@binkert.org  assert(g_eventQueue_ptr->getTime() >= issued_time);
5976145Snate@binkert.org  Time miss_latency = g_eventQueue_ptr->getTime() - issued_time;
5986145Snate@binkert.org
5996145Snate@binkert.org  if (PROTOCOL_DEBUG_TRACE) {
6006145Snate@binkert.org    g_system_ptr->getProfiler()->profileTransition("Seq", (m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version), -1, request.getAddress(), "", "Done", "",
6016145Snate@binkert.org                                                   int_to_string(miss_latency)+" cycles "+GenericMachineType_to_string(respondingMach)+" "+CacheRequestType_to_string(request.getType())+" "+PrefetchBit_to_string(request.getPrefetch()));
6026145Snate@binkert.org  }
6036145Snate@binkert.org
6046145Snate@binkert.org  DEBUG_MSG(SEQUENCER_COMP, MedPrio, request_address);
6056145Snate@binkert.org  DEBUG_MSG(SEQUENCER_COMP, MedPrio, request.getPrefetch());
6066145Snate@binkert.org  if (request.getPrefetch() == PrefetchBit_Yes) {
6076145Snate@binkert.org    DEBUG_MSG(SEQUENCER_COMP, MedPrio, "return");
6086145Snate@binkert.org    g_system_ptr->getProfiler()->swPrefetchLatency(miss_latency, type, respondingMach);
6096145Snate@binkert.org    return; // Ignore the software prefetch, don't callback the driver
6106145Snate@binkert.org  }
6116145Snate@binkert.org
6126145Snate@binkert.org  // Profile the miss latency for all non-zero demand misses
6136145Snate@binkert.org  if (miss_latency != 0) {
6146145Snate@binkert.org    g_system_ptr->getProfiler()->missLatency(miss_latency, type, respondingMach);
6156145Snate@binkert.org
6166151Sdrh5@cs.wisc.edu#if 0
6176151Sdrh5@cs.wisc.edu    uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick"));
6186151Sdrh5@cs.wisc.edu    uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr"));
6196151Sdrh5@cs.wisc.edu    uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick"));
6206151Sdrh5@cs.wisc.edu    uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr"));
6216151Sdrh5@cs.wisc.edu    cout << "END PROC " << m_version << hex << " tick = " << tick << " tick_cmpr = " << tick_cmpr << " stick = " << stick << " stick_cmpr = " << stick_cmpr << " cycle = "<< g_eventQueue_ptr->getTime() << dec << endl;
6226151Sdrh5@cs.wisc.edu#endif
6236145Snate@binkert.org
6246145Snate@binkert.org  }
6256145Snate@binkert.org
6266145Snate@binkert.org  bool write =
6276145Snate@binkert.org    (type == CacheRequestType_ST) ||
6286145Snate@binkert.org    (type == CacheRequestType_ST_XACT) ||
6296145Snate@binkert.org    (type == CacheRequestType_LDX_XACT) ||
6306145Snate@binkert.org    (type == CacheRequestType_ATOMIC);
6316145Snate@binkert.org
6326145Snate@binkert.org  if (TSO && write) {
6336145Snate@binkert.org    m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->callBack(line_address(request.getAddress()), data);
6346145Snate@binkert.org  } else {
6356145Snate@binkert.org
6366145Snate@binkert.org    // Copy the correct bytes out of the cache line into the subblock
6376145Snate@binkert.org    SubBlock subblock(request_address, request_logical_address, size);
6386145Snate@binkert.org    subblock.mergeFrom(data);  // copy the correct bytes from DataBlock in the SubBlock
6396145Snate@binkert.org
6406145Snate@binkert.org    // Scan the store buffer to see if there are any outstanding stores we need to collect
6416145Snate@binkert.org    if (TSO) {
6426145Snate@binkert.org      m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->updateSubBlock(subblock);
6436145Snate@binkert.org    }
6446145Snate@binkert.org
6456145Snate@binkert.org    // Call into the Driver (Tester or Simics) and let it read and/or modify the sub-block
6466145Snate@binkert.org    g_system_ptr->getDriver()->hitCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID);
6476145Snate@binkert.org
6486145Snate@binkert.org    // If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock
6496145Snate@binkert.org    // (This is only triggered for the non-TSO case)
6506145Snate@binkert.org    if (write) {
6516145Snate@binkert.org      assert(!TSO);
6526145Snate@binkert.org      subblock.mergeTo(data);    // copy the correct bytes from SubBlock into the DataBlock
6536145Snate@binkert.org    }
6546145Snate@binkert.org  }
6556145Snate@binkert.org}
6566145Snate@binkert.org
6576145Snate@binkert.orgvoid Sequencer::readConflictCallback(const Address& address) {
6586145Snate@binkert.org  // process oldest thread first
6596145Snate@binkert.org  int thread = -1;
6606145Snate@binkert.org  Time oldest_time = 0;
6616145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
6626145Snate@binkert.org  for(int t=0; t < smt_threads; ++t){
6636145Snate@binkert.org    if(m_readRequestTable_ptr[t]->exist(address)){
6646145Snate@binkert.org      CacheMsg & request = m_readRequestTable_ptr[t]->lookup(address);
6656145Snate@binkert.org      if(thread == -1 || (request.getTime() < oldest_time) ){
6666145Snate@binkert.org        thread = t;
6676145Snate@binkert.org        oldest_time = request.getTime();
6686145Snate@binkert.org      }
6696145Snate@binkert.org    }
6706145Snate@binkert.org  }
6716145Snate@binkert.org  // make sure we found an oldest thread
6726145Snate@binkert.org  ASSERT(thread != -1);
6736145Snate@binkert.org
6746145Snate@binkert.org  CacheMsg & request = m_readRequestTable_ptr[thread]->lookup(address);
6756145Snate@binkert.org
6766145Snate@binkert.org  readConflictCallback(address, GenericMachineType_NULL, thread);
6776145Snate@binkert.org}
6786145Snate@binkert.org
6796145Snate@binkert.orgvoid Sequencer::readConflictCallback(const Address& address, GenericMachineType respondingMach, int thread) {
6806145Snate@binkert.org  assert(address == line_address(address));
6816145Snate@binkert.org  assert(m_readRequestTable_ptr[thread]->exist(line_address(address)));
6826145Snate@binkert.org
6836145Snate@binkert.org  CacheMsg request = m_readRequestTable_ptr[thread]->lookup(address);
6846145Snate@binkert.org  assert( request.getThreadID() == thread );
6856145Snate@binkert.org  removeRequest(request);
6866145Snate@binkert.org
6876145Snate@binkert.org  assert((request.getType() == CacheRequestType_LD) ||
6886145Snate@binkert.org         (request.getType() == CacheRequestType_LD_XACT) ||
6896145Snate@binkert.org         (request.getType() == CacheRequestType_IFETCH)
6906145Snate@binkert.org         );
6916145Snate@binkert.org
6926145Snate@binkert.org  conflictCallback(request, respondingMach, thread);
6936145Snate@binkert.org}
6946145Snate@binkert.org
6956145Snate@binkert.orgvoid Sequencer::writeConflictCallback(const Address& address) {
6966145Snate@binkert.org  // process oldest thread first
6976145Snate@binkert.org  int thread = -1;
6986145Snate@binkert.org  Time oldest_time = 0;
6996145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
7006145Snate@binkert.org  for(int t=0; t < smt_threads; ++t){
7016145Snate@binkert.org    if(m_writeRequestTable_ptr[t]->exist(address)){
7026145Snate@binkert.org      CacheMsg & request = m_writeRequestTable_ptr[t]->lookup(address);
7036145Snate@binkert.org      if(thread == -1 || (request.getTime() < oldest_time) ){
7046145Snate@binkert.org        thread = t;
7056145Snate@binkert.org        oldest_time = request.getTime();
7066145Snate@binkert.org      }
7076145Snate@binkert.org    }
7086145Snate@binkert.org  }
7096145Snate@binkert.org  // make sure we found an oldest thread
7106145Snate@binkert.org  ASSERT(thread != -1);
7116145Snate@binkert.org
7126145Snate@binkert.org  CacheMsg & request = m_writeRequestTable_ptr[thread]->lookup(address);
7136145Snate@binkert.org
7146145Snate@binkert.org  writeConflictCallback(address, GenericMachineType_NULL, thread);
7156145Snate@binkert.org}
7166145Snate@binkert.org
7176145Snate@binkert.orgvoid Sequencer::writeConflictCallback(const Address& address, GenericMachineType respondingMach, int thread) {
7186145Snate@binkert.org  assert(address == line_address(address));
7196145Snate@binkert.org  assert(m_writeRequestTable_ptr[thread]->exist(line_address(address)));
7206145Snate@binkert.org  CacheMsg request = m_writeRequestTable_ptr[thread]->lookup(address);
7216145Snate@binkert.org  assert( request.getThreadID() == thread);
7226145Snate@binkert.org  removeRequest(request);
7236145Snate@binkert.org
7246145Snate@binkert.org  assert((request.getType() == CacheRequestType_ST) ||
7256145Snate@binkert.org         (request.getType() == CacheRequestType_ST_XACT) ||
7266145Snate@binkert.org         (request.getType() == CacheRequestType_LDX_XACT) ||
7276145Snate@binkert.org         (request.getType() == CacheRequestType_ATOMIC));
7286145Snate@binkert.org
7296145Snate@binkert.org  conflictCallback(request, respondingMach, thread);
7306145Snate@binkert.org
7316145Snate@binkert.org}
7326145Snate@binkert.org
7336145Snate@binkert.orgvoid Sequencer::conflictCallback(const CacheMsg& request, GenericMachineType respondingMach, int thread) {
7346145Snate@binkert.org  assert(XACT_MEMORY);
7356145Snate@binkert.org  int size = request.getSize();
7366145Snate@binkert.org  Address request_address = request.getAddress();
7376145Snate@binkert.org  Address request_logical_address = request.getLogicalAddress();
7386145Snate@binkert.org  Address request_line_address = line_address(request_address);
7396145Snate@binkert.org  CacheRequestType type = request.getType();
7406145Snate@binkert.org  int threadID = request.getThreadID();
7416145Snate@binkert.org  Time issued_time = request.getTime();
7426145Snate@binkert.org  int logical_proc_no = ((m_chip_ptr->getID() * RubyConfig::numberOfProcsPerChip()) + m_version) * RubyConfig::numberofSMTThreads() + threadID;
7436145Snate@binkert.org
7446145Snate@binkert.org  DEBUG_MSG(SEQUENCER_COMP, MedPrio, size);
7456145Snate@binkert.org
7466145Snate@binkert.org  assert(g_eventQueue_ptr->getTime() >= issued_time);
7476145Snate@binkert.org  Time miss_latency = g_eventQueue_ptr->getTime() - issued_time;
7486145Snate@binkert.org
7496145Snate@binkert.org  if (PROTOCOL_DEBUG_TRACE) {
7506145Snate@binkert.org    g_system_ptr->getProfiler()->profileTransition("Seq", (m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version), -1, request.getAddress(), "", "Conflict", "",
7516145Snate@binkert.org                                                   int_to_string(miss_latency)+" cycles "+GenericMachineType_to_string(respondingMach)+" "+CacheRequestType_to_string(request.getType())+" "+PrefetchBit_to_string(request.getPrefetch()));
7526145Snate@binkert.org  }
7536145Snate@binkert.org
7546145Snate@binkert.org  DEBUG_MSG(SEQUENCER_COMP, MedPrio, request_address);
7556145Snate@binkert.org  DEBUG_MSG(SEQUENCER_COMP, MedPrio, request.getPrefetch());
7566145Snate@binkert.org  if (request.getPrefetch() == PrefetchBit_Yes) {
7576145Snate@binkert.org    DEBUG_MSG(SEQUENCER_COMP, MedPrio, "return");
7586145Snate@binkert.org    g_system_ptr->getProfiler()->swPrefetchLatency(miss_latency, type, respondingMach);
7596145Snate@binkert.org    return; // Ignore the software prefetch, don't callback the driver
7606145Snate@binkert.org  }
7616145Snate@binkert.org
7626145Snate@binkert.org  bool write =
7636145Snate@binkert.org    (type == CacheRequestType_ST) ||
7646145Snate@binkert.org    (type == CacheRequestType_ST_XACT) ||
7656145Snate@binkert.org    (type == CacheRequestType_LDX_XACT) ||
7666145Snate@binkert.org    (type == CacheRequestType_ATOMIC);
7676145Snate@binkert.org
7686145Snate@binkert.org  // Copy the correct bytes out of the cache line into the subblock
7696145Snate@binkert.org  SubBlock subblock(request_address, request_logical_address, size);
7706145Snate@binkert.org
7716145Snate@binkert.org  // Call into the Driver (Tester or Simics)
7726145Snate@binkert.org  g_system_ptr->getDriver()->conflictCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID);
7736145Snate@binkert.org
7746145Snate@binkert.org  // If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock
7756145Snate@binkert.org  // (This is only triggered for the non-TSO case)
7766145Snate@binkert.org  if (write) {
7776145Snate@binkert.org    assert(!TSO);
7786145Snate@binkert.org  }
7796145Snate@binkert.org}
7806145Snate@binkert.org
7816145Snate@binkert.orgvoid Sequencer::printDebug(){
7826145Snate@binkert.org  //notify driver of debug
7836145Snate@binkert.org  g_system_ptr->getDriver()->printDebug();
7846145Snate@binkert.org}
7856145Snate@binkert.org
7866145Snate@binkert.org// Returns true if the sequencer already has a load or store outstanding
7876151Sdrh5@cs.wisc.edubool
7886151Sdrh5@cs.wisc.eduSequencer::isReady(const Packet* pkt) const
7896151Sdrh5@cs.wisc.edu{
7906145Snate@binkert.org
7916151Sdrh5@cs.wisc.edu  int cpu_number = pkt->req->contextId();
7926151Sdrh5@cs.wisc.edu  la_t logical_addr = pkt->req->getVaddr();
7936151Sdrh5@cs.wisc.edu  pa_t physical_addr = pkt->req->getPaddr();
7946151Sdrh5@cs.wisc.edu  CacheRequestType type_of_request;
7956151Sdrh5@cs.wisc.edu  if ( pkt->req->isInstFetch() ) {
7966151Sdrh5@cs.wisc.edu    type_of_request = CacheRequestType_IFETCH;
7976151Sdrh5@cs.wisc.edu  } else if ( pkt->req->isLocked() || pkt->req->isSwap() ) {
7986151Sdrh5@cs.wisc.edu    type_of_request = CacheRequestType_ATOMIC;
7996151Sdrh5@cs.wisc.edu  } else if ( pkt->isRead() ) {
8006151Sdrh5@cs.wisc.edu    type_of_request = CacheRequestType_LD;
8016151Sdrh5@cs.wisc.edu  } else if ( pkt->isWrite() ) {
8026151Sdrh5@cs.wisc.edu    type_of_request = CacheRequestType_ST;
8036151Sdrh5@cs.wisc.edu  } else {
8046151Sdrh5@cs.wisc.edu    assert(false);
8056151Sdrh5@cs.wisc.edu  }
8066151Sdrh5@cs.wisc.edu  int thread = pkt->req->threadId();
8076151Sdrh5@cs.wisc.edu
8086151Sdrh5@cs.wisc.edu  CacheMsg request(Address( physical_addr ),
8096151Sdrh5@cs.wisc.edu                   Address( physical_addr ),
8106151Sdrh5@cs.wisc.edu                   type_of_request,
8116151Sdrh5@cs.wisc.edu                   Address(0),
8126151Sdrh5@cs.wisc.edu                   AccessModeType_UserMode,   // User/supervisor mode
8136151Sdrh5@cs.wisc.edu                   0,   // Size in bytes of request
8146151Sdrh5@cs.wisc.edu                   PrefetchBit_No,  // Not a prefetch
8156151Sdrh5@cs.wisc.edu                   0,              // Version number
8166151Sdrh5@cs.wisc.edu                   Address(logical_addr),   // Virtual Address
8176151Sdrh5@cs.wisc.edu                   thread,              // SMT thread
8186151Sdrh5@cs.wisc.edu                   0,          // TM specific - timestamp of memory request
8196151Sdrh5@cs.wisc.edu                   false      // TM specific - whether request is part of escape action
8206151Sdrh5@cs.wisc.edu                   );
8216151Sdrh5@cs.wisc.edu  isReady(request);
8226151Sdrh5@cs.wisc.edu}
8236151Sdrh5@cs.wisc.edu
8246151Sdrh5@cs.wisc.edubool
8256151Sdrh5@cs.wisc.eduSequencer::isReady(const CacheMsg& request) const
8266151Sdrh5@cs.wisc.edu{
8276145Snate@binkert.org  if (m_outstanding_count >= g_SEQUENCER_OUTSTANDING_REQUESTS) {
8286145Snate@binkert.org    //cout << "TOO MANY OUTSTANDING: " << m_outstanding_count << " " << g_SEQUENCER_OUTSTANDING_REQUESTS << " VER " << m_version << endl;
8296145Snate@binkert.org    //printProgress(cout);
8306145Snate@binkert.org    return false;
8316145Snate@binkert.org  }
8326145Snate@binkert.org
8336145Snate@binkert.org  // This code allows reads to be performed even when we have a write
8346145Snate@binkert.org  // request outstanding for the line
8356145Snate@binkert.org  bool write =
8366145Snate@binkert.org    (request.getType() == CacheRequestType_ST) ||
8376145Snate@binkert.org    (request.getType() == CacheRequestType_ST_XACT) ||
8386145Snate@binkert.org    (request.getType() == CacheRequestType_LDX_XACT) ||
8396145Snate@binkert.org    (request.getType() == CacheRequestType_ATOMIC);
8406145Snate@binkert.org
8416145Snate@binkert.org  // LUKE - disallow more than one request type per address
8426145Snate@binkert.org  //     INVARIANT: at most one request type per address, per processor
8436145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
8446145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
8456145Snate@binkert.org    if( m_writeRequestTable_ptr[p]->exist(line_address(request.getAddress())) ||
8466145Snate@binkert.org        m_readRequestTable_ptr[p]->exist(line_address(request.getAddress())) ){
8476145Snate@binkert.org      //cout << "OUTSTANDING REQUEST EXISTS " << p << " VER " << m_version << endl;
8486145Snate@binkert.org      //printProgress(cout);
8496145Snate@binkert.org      return false;
8506145Snate@binkert.org    }
8516145Snate@binkert.org  }
8526145Snate@binkert.org
8536145Snate@binkert.org  if (TSO) {
8546145Snate@binkert.org    return m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady();
8556145Snate@binkert.org  }
8566145Snate@binkert.org  return true;
8576145Snate@binkert.org}
8586145Snate@binkert.org
8596145Snate@binkert.org// Called by Driver (Simics or Tester).
8606151Sdrh5@cs.wisc.eduvoid
8616151Sdrh5@cs.wisc.eduSequencer::makeRequest(const Packet* pkt, void* data)
8626151Sdrh5@cs.wisc.edu{
8636151Sdrh5@cs.wisc.edu  int cpu_number = pkt->req->contextId();
8646151Sdrh5@cs.wisc.edu  la_t logical_addr = pkt->req->getVaddr();
8656151Sdrh5@cs.wisc.edu  pa_t physical_addr = pkt->req->getPaddr();
8666151Sdrh5@cs.wisc.edu  int request_size = pkt->getSize();
8676151Sdrh5@cs.wisc.edu  CacheRequestType type_of_request;
8686151Sdrh5@cs.wisc.edu  if ( pkt->req->isInstFetch() ) {
8696151Sdrh5@cs.wisc.edu    type_of_request = CacheRequestType_IFETCH;
8706151Sdrh5@cs.wisc.edu  } else if ( pkt->req->isLocked() || pkt->req->isSwap() ) {
8716151Sdrh5@cs.wisc.edu    type_of_request = CacheRequestType_ATOMIC;
8726151Sdrh5@cs.wisc.edu  } else if ( pkt->isRead() ) {
8736151Sdrh5@cs.wisc.edu    type_of_request = CacheRequestType_LD;
8746151Sdrh5@cs.wisc.edu  } else if ( pkt->isWrite() ) {
8756151Sdrh5@cs.wisc.edu    type_of_request = CacheRequestType_ST;
8766151Sdrh5@cs.wisc.edu  } else {
8776151Sdrh5@cs.wisc.edu    assert(false);
8786151Sdrh5@cs.wisc.edu  }
8796151Sdrh5@cs.wisc.edu  la_t virtual_pc = pkt->req->getPC();
8806151Sdrh5@cs.wisc.edu  int isPriv = false;  // TODO: get permission data
8816151Sdrh5@cs.wisc.edu  int thread = pkt->req->threadId();
8826151Sdrh5@cs.wisc.edu
8836151Sdrh5@cs.wisc.edu  AccessModeType access_mode = AccessModeType_UserMode; // TODO: get actual permission
8846151Sdrh5@cs.wisc.edu
8856151Sdrh5@cs.wisc.edu  CacheMsg request(Address( physical_addr ),
8866151Sdrh5@cs.wisc.edu                   Address( physical_addr ),
8876151Sdrh5@cs.wisc.edu                   type_of_request,
8886151Sdrh5@cs.wisc.edu                   Address(virtual_pc),
8896151Sdrh5@cs.wisc.edu                   access_mode,   // User/supervisor mode
8906151Sdrh5@cs.wisc.edu                   request_size,   // Size in bytes of request
8916151Sdrh5@cs.wisc.edu                   PrefetchBit_No, // Not a prefetch
8926151Sdrh5@cs.wisc.edu                   0,              // Version number
8936151Sdrh5@cs.wisc.edu                   Address(logical_addr),   // Virtual Address
8946151Sdrh5@cs.wisc.edu                   thread,         // SMT thread
8956151Sdrh5@cs.wisc.edu                   0,              // TM specific - timestamp of memory request
8966151Sdrh5@cs.wisc.edu                   false           // TM specific - whether request is part of escape action
8976151Sdrh5@cs.wisc.edu                   );
8986151Sdrh5@cs.wisc.edu  makeRequest(request);
8996151Sdrh5@cs.wisc.edu}
9006151Sdrh5@cs.wisc.edu
9016151Sdrh5@cs.wisc.eduvoid
9026151Sdrh5@cs.wisc.eduSequencer::makeRequest(const CacheMsg& request)
9036151Sdrh5@cs.wisc.edu{
9046145Snate@binkert.org  bool write = (request.getType() == CacheRequestType_ST) ||
9056145Snate@binkert.org    (request.getType() == CacheRequestType_ST_XACT) ||
9066145Snate@binkert.org    (request.getType() == CacheRequestType_LDX_XACT) ||
9076145Snate@binkert.org    (request.getType() == CacheRequestType_ATOMIC);
9086145Snate@binkert.org
9096145Snate@binkert.org  if (TSO && (request.getPrefetch() == PrefetchBit_No) && write) {
9106145Snate@binkert.org    assert(m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady());
9116145Snate@binkert.org    m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->insertStore(request);
9126145Snate@binkert.org    return;
9136145Snate@binkert.org  }
9146145Snate@binkert.org
9156145Snate@binkert.org  bool hit = doRequest(request);
9166145Snate@binkert.org
9176145Snate@binkert.org}
9186145Snate@binkert.org
9196145Snate@binkert.orgbool Sequencer::doRequest(const CacheMsg& request) {
9206145Snate@binkert.org  bool hit = false;
9216145Snate@binkert.org  // Check the fast path
9226145Snate@binkert.org  DataBlock* data_ptr;
9236145Snate@binkert.org
9246145Snate@binkert.org  int thread = request.getThreadID();
9256145Snate@binkert.org
9266145Snate@binkert.org  hit = tryCacheAccess(line_address(request.getAddress()),
9276145Snate@binkert.org                       request.getType(),
9286145Snate@binkert.org                       request.getProgramCounter(),
9296145Snate@binkert.org                       request.getAccessMode(),
9306145Snate@binkert.org                       request.getSize(),
9316145Snate@binkert.org                       data_ptr);
9326145Snate@binkert.org
9336145Snate@binkert.org  if (hit && (request.getType() == CacheRequestType_IFETCH || !REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH) ) {
9346145Snate@binkert.org    DEBUG_MSG(SEQUENCER_COMP, MedPrio, "Fast path hit");
9356145Snate@binkert.org    hitCallback(request, *data_ptr, GenericMachineType_L1Cache, thread);
9366145Snate@binkert.org    return true;
9376145Snate@binkert.org  }
9386145Snate@binkert.org
9396151Sdrh5@cs.wisc.edu#if 0
9406145Snate@binkert.org  uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick"));
9416145Snate@binkert.org  uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr"));
9426145Snate@binkert.org  uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick"));
9436145Snate@binkert.org  uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr"));
9446145Snate@binkert.org  cout << "START PROC " << m_version << hex << " tick = " << tick << " tick_cmpr = " << tick_cmpr << " stick = " << stick << " stick_cmpr = " << stick_cmpr << " cycle = "<< g_eventQueue_ptr->getTime() << dec << endl;;
9456151Sdrh5@cs.wisc.edu#endif
9466145Snate@binkert.org
9476145Snate@binkert.org  if (TSO && (request.getType() == CacheRequestType_LD || request.getType() == CacheRequestType_IFETCH)) {
9486145Snate@binkert.org
9496145Snate@binkert.org    // See if we can satisfy the load entirely from the store buffer
9506145Snate@binkert.org    SubBlock subblock(line_address(request.getAddress()), request.getSize());
9516145Snate@binkert.org    if (m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->trySubBlock(subblock)) {
9526145Snate@binkert.org      DataBlock dummy;
9536145Snate@binkert.org      hitCallback(request, dummy, GenericMachineType_NULL, thread);  // Call with an 'empty' datablock, since the data is in the store buffer
9546145Snate@binkert.org      return true;
9556145Snate@binkert.org    }
9566145Snate@binkert.org  }
9576145Snate@binkert.org
9586145Snate@binkert.org  DEBUG_MSG(SEQUENCER_COMP, MedPrio, "Fast path miss");
9596145Snate@binkert.org  issueRequest(request);
9606145Snate@binkert.org  return hit;
9616145Snate@binkert.org}
9626145Snate@binkert.org
9636145Snate@binkert.orgvoid Sequencer::issueRequest(const CacheMsg& request) {
9646145Snate@binkert.org  bool found = insertRequest(request);
9656145Snate@binkert.org
9666145Snate@binkert.org  if (!found) {
9676145Snate@binkert.org    CacheMsg msg = request;
9686145Snate@binkert.org    msg.getAddress() = line_address(request.getAddress()); // Make line address
9696145Snate@binkert.org
9706145Snate@binkert.org    // Fast Path L1 misses are profiled here - all non-fast path misses are profiled within the generated protocol code
9716145Snate@binkert.org    if (!REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH) {
9726145Snate@binkert.org      g_system_ptr->getProfiler()->addPrimaryStatSample(msg, m_chip_ptr->getID());
9736145Snate@binkert.org    }
9746145Snate@binkert.org
9756145Snate@binkert.org    if (PROTOCOL_DEBUG_TRACE) {
9766145Snate@binkert.org      g_system_ptr->getProfiler()->profileTransition("Seq", (m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip() + m_version), -1, msg.getAddress(),"", "Begin", "", CacheRequestType_to_string(request.getType()));
9776145Snate@binkert.org    }
9786145Snate@binkert.org
9796145Snate@binkert.org#if 0
9806145Snate@binkert.org    // Commented out by nate binkert because I removed the trace stuff
9816145Snate@binkert.org    if (g_system_ptr->getTracer()->traceEnabled()) {
9826145Snate@binkert.org      g_system_ptr->getTracer()->traceRequest((m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version), msg.getAddress(), msg.getProgramCounter(),
9836145Snate@binkert.org                                              msg.getType(), g_eventQueue_ptr->getTime());
9846145Snate@binkert.org    }
9856145Snate@binkert.org#endif
9866145Snate@binkert.org
9876145Snate@binkert.org    Time latency = 0;  // initialzed to an null value
9886145Snate@binkert.org
9896145Snate@binkert.org    latency = SEQUENCER_TO_CONTROLLER_LATENCY;
9906145Snate@binkert.org
9916145Snate@binkert.org    // Send the message to the cache controller
9926145Snate@binkert.org    assert(latency > 0);
9936145Snate@binkert.org    m_chip_ptr->m_L1Cache_mandatoryQueue_vec[m_version]->enqueue(msg, latency);
9946145Snate@binkert.org
9956145Snate@binkert.org  }  // !found
9966145Snate@binkert.org}
9976145Snate@binkert.org
9986145Snate@binkert.orgbool Sequencer::tryCacheAccess(const Address& addr, CacheRequestType type,
9996145Snate@binkert.org                               const Address& pc, AccessModeType access_mode,
10006145Snate@binkert.org                               int size, DataBlock*& data_ptr) {
10016145Snate@binkert.org  if (type == CacheRequestType_IFETCH) {
10026145Snate@binkert.org    if (Protocol::m_TwoLevelCache) {
10036145Snate@binkert.org      return m_chip_ptr->m_L1Cache_L1IcacheMemory_vec[m_version]->tryCacheAccess(line_address(addr), type, data_ptr);
10046145Snate@binkert.org    }
10056145Snate@binkert.org    else {
10066145Snate@binkert.org      return m_chip_ptr->m_L1Cache_cacheMemory_vec[m_version]->tryCacheAccess(line_address(addr), type, data_ptr);
10076145Snate@binkert.org    }
10086145Snate@binkert.org  } else {
10096145Snate@binkert.org    if (Protocol::m_TwoLevelCache) {
10106145Snate@binkert.org      return m_chip_ptr->m_L1Cache_L1DcacheMemory_vec[m_version]->tryCacheAccess(line_address(addr), type, data_ptr);
10116145Snate@binkert.org    }
10126145Snate@binkert.org    else {
10136145Snate@binkert.org      return m_chip_ptr->m_L1Cache_cacheMemory_vec[m_version]->tryCacheAccess(line_address(addr), type, data_ptr);
10146145Snate@binkert.org    }
10156145Snate@binkert.org  }
10166145Snate@binkert.org}
10176145Snate@binkert.org
10186145Snate@binkert.orgvoid Sequencer::resetRequestTime(const Address& addr, int thread){
10196145Snate@binkert.org  assert(thread >= 0);
10206145Snate@binkert.org  //reset both load and store requests, if they exist
10216145Snate@binkert.org  if(m_readRequestTable_ptr[thread]->exist(line_address(addr))){
10226145Snate@binkert.org    CacheMsg& request = m_readRequestTable_ptr[thread]->lookup(addr);
10236145Snate@binkert.org    if( request.m_AccessMode != AccessModeType_UserMode){
10246145Snate@binkert.org      cout << "resetRequestType ERROR read request addr = " << addr << " thread = "<< thread << " is SUPERVISOR MODE" << endl;
10256145Snate@binkert.org      printProgress(cout);
10266145Snate@binkert.org    }
10276145Snate@binkert.org    //ASSERT(request.m_AccessMode == AccessModeType_UserMode);
10286145Snate@binkert.org    request.setTime(g_eventQueue_ptr->getTime());
10296145Snate@binkert.org  }
10306145Snate@binkert.org  if(m_writeRequestTable_ptr[thread]->exist(line_address(addr))){
10316145Snate@binkert.org    CacheMsg& request = m_writeRequestTable_ptr[thread]->lookup(addr);
10326145Snate@binkert.org    if( request.m_AccessMode != AccessModeType_UserMode){
10336145Snate@binkert.org      cout << "resetRequestType ERROR write request addr = " << addr << " thread = "<< thread << " is SUPERVISOR MODE" << endl;
10346145Snate@binkert.org      printProgress(cout);
10356145Snate@binkert.org    }
10366145Snate@binkert.org    //ASSERT(request.m_AccessMode == AccessModeType_UserMode);
10376145Snate@binkert.org    request.setTime(g_eventQueue_ptr->getTime());
10386145Snate@binkert.org  }
10396145Snate@binkert.org}
10406145Snate@binkert.org
10416145Snate@binkert.org// removes load request from queue
10426145Snate@binkert.orgvoid Sequencer::removeLoadRequest(const Address & addr, int thread){
10436145Snate@binkert.org  removeRequest(getReadRequest(addr, thread));
10446145Snate@binkert.org}
10456145Snate@binkert.org
10466145Snate@binkert.orgvoid Sequencer::removeStoreRequest(const Address & addr, int thread){
10476145Snate@binkert.org  removeRequest(getWriteRequest(addr, thread));
10486145Snate@binkert.org}
10496145Snate@binkert.org
10506145Snate@binkert.org// returns the read CacheMsg
10516145Snate@binkert.orgCacheMsg & Sequencer::getReadRequest( const Address & addr, int thread ){
10526145Snate@binkert.org  Address temp = addr;
10536145Snate@binkert.org  assert(thread >= 0);
10546145Snate@binkert.org  assert(temp == line_address(temp));
10556145Snate@binkert.org  assert(m_readRequestTable_ptr[thread]->exist(addr));
10566145Snate@binkert.org  return m_readRequestTable_ptr[thread]->lookup(addr);
10576145Snate@binkert.org}
10586145Snate@binkert.org
10596145Snate@binkert.orgCacheMsg & Sequencer::getWriteRequest( const Address & addr, int thread){
10606145Snate@binkert.org  Address temp = addr;
10616145Snate@binkert.org  assert(thread >= 0);
10626145Snate@binkert.org  assert(temp == line_address(temp));
10636145Snate@binkert.org  assert(m_writeRequestTable_ptr[thread]->exist(addr));
10646145Snate@binkert.org  return m_writeRequestTable_ptr[thread]->lookup(addr);
10656145Snate@binkert.org}
10666145Snate@binkert.org
10676145Snate@binkert.orgvoid Sequencer::print(ostream& out) const {
10686145Snate@binkert.org  out << "[Sequencer: " << m_chip_ptr->getID()
10696145Snate@binkert.org      << ", outstanding requests: " << m_outstanding_count;
10706145Snate@binkert.org
10716145Snate@binkert.org  int smt_threads = RubyConfig::numberofSMTThreads();
10726145Snate@binkert.org  for(int p=0; p < smt_threads; ++p){
10736145Snate@binkert.org    out << ", read request table[ " << p << " ]: " << *m_readRequestTable_ptr[p]
10746145Snate@binkert.org        << ", write request table[ " << p << " ]: " << *m_writeRequestTable_ptr[p];
10756145Snate@binkert.org  }
10766145Snate@binkert.org  out << "]";
10776145Snate@binkert.org}
10786145Snate@binkert.org
10796145Snate@binkert.org// this can be called from setState whenever coherence permissions are upgraded
10806145Snate@binkert.org// when invoked, coherence violations will be checked for the given block
10816145Snate@binkert.orgvoid Sequencer::checkCoherence(const Address& addr) {
10826145Snate@binkert.org#ifdef CHECK_COHERENCE
10836145Snate@binkert.org  g_system_ptr->checkGlobalCoherenceInvariant(addr);
10846145Snate@binkert.org#endif
10856145Snate@binkert.org}
10866145Snate@binkert.org
10876145Snate@binkert.orgbool Sequencer::getRubyMemoryValue(const Address& addr, char* value,
10886145Snate@binkert.org                                   unsigned int size_in_bytes ) {
10896145Snate@binkert.org  if(g_SIMICS){
10906145Snate@binkert.org    for(unsigned int i=0; i < size_in_bytes; i++) {
10916145Snate@binkert.org      value[i] = SIMICS_read_physical_memory( m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version,
10926145Snate@binkert.org                                              addr.getAddress() + i, 1 );
10936145Snate@binkert.org    }
10946145Snate@binkert.org    return false; // Do nothing?
10956145Snate@binkert.org  } else {
10966145Snate@binkert.org    bool found = false;
10976145Snate@binkert.org    const Address lineAddr = line_address(addr);
10986145Snate@binkert.org    DataBlock data;
10996145Snate@binkert.org    PhysAddress paddr(addr);
11006145Snate@binkert.org    DataBlock* dataPtr = &data;
11016145Snate@binkert.org    Chip* n = dynamic_cast<Chip*>(m_chip_ptr);
11026145Snate@binkert.org    // LUKE - use variable names instead of macros
11036145Snate@binkert.org    assert(n->m_L1Cache_L1IcacheMemory_vec[m_version] != NULL);
11046145Snate@binkert.org    assert(n->m_L1Cache_L1DcacheMemory_vec[m_version] != NULL);
11056145Snate@binkert.org
11066145Snate@binkert.org    MachineID l2_mach = map_L2ChipId_to_L2Cache(addr, m_chip_ptr->getID() );
11076145Snate@binkert.org    int l2_ver = l2_mach.num%RubyConfig::numberOfL2CachePerChip();
11086145Snate@binkert.org
11096145Snate@binkert.org    if (Protocol::m_TwoLevelCache) {
11106145Snate@binkert.org      if(Protocol::m_CMP){
11116145Snate@binkert.org        assert(n->m_L2Cache_L2cacheMemory_vec[l2_ver] != NULL);
11126145Snate@binkert.org      }
11136145Snate@binkert.org      else{
11146145Snate@binkert.org        assert(n->m_L1Cache_cacheMemory_vec[m_version] != NULL);
11156145Snate@binkert.org      }
11166145Snate@binkert.org    }
11176145Snate@binkert.org
11186145Snate@binkert.org    if (n->m_L1Cache_L1IcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_IFETCH, dataPtr)){
11196145Snate@binkert.org      n->m_L1Cache_L1IcacheMemory_vec[m_version]->getMemoryValue(addr, value, size_in_bytes);
11206145Snate@binkert.org      found = true;
11216145Snate@binkert.org    } else if (n->m_L1Cache_L1DcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){
11226145Snate@binkert.org      n->m_L1Cache_L1DcacheMemory_vec[m_version]->getMemoryValue(addr, value, size_in_bytes);
11236145Snate@binkert.org      found = true;
11246145Snate@binkert.org    } else if (Protocol::m_CMP && n->m_L2Cache_L2cacheMemory_vec[l2_ver]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){
11256145Snate@binkert.org      n->m_L2Cache_L2cacheMemory_vec[l2_ver]->getMemoryValue(addr, value, size_in_bytes);
11266145Snate@binkert.org      found = true;
11276151Sdrh5@cs.wisc.edu      // } else if (n->TBE_TABLE_MEMBER_VARIABLE->isPresent(lineAddr)){
11286151Sdrh5@cs.wisc.edu      //       ASSERT(n->TBE_TABLE_MEMBER_VARIABLE->isPresent(lineAddr));
11296151Sdrh5@cs.wisc.edu      //       L1Cache_TBE tbeEntry = n->TBE_TABLE_MEMBER_VARIABLE->lookup(lineAddr);
11306145Snate@binkert.org
11316151Sdrh5@cs.wisc.edu      //       int offset = addr.getOffset();
11326151Sdrh5@cs.wisc.edu      //       for(int i=0; i<size_in_bytes; ++i){
11336151Sdrh5@cs.wisc.edu      //         value[i] = tbeEntry.getDataBlk().getByte(offset + i);
11346151Sdrh5@cs.wisc.edu      //       }
11356145Snate@binkert.org
11366151Sdrh5@cs.wisc.edu      //       found = true;
11376145Snate@binkert.org    } else {
11386145Snate@binkert.org      // Address not found
11396145Snate@binkert.org      //cout << "  " << m_chip_ptr->getID() << " NOT IN CACHE, Value at Directory is: " << (int) value[0] << endl;
11406145Snate@binkert.org      n = dynamic_cast<Chip*>(g_system_ptr->getChip(map_Address_to_DirectoryNode(addr)/RubyConfig::numberOfDirectoryPerChip()));
11416145Snate@binkert.org      int dir_version = map_Address_to_DirectoryNode(addr)%RubyConfig::numberOfDirectoryPerChip();
11426145Snate@binkert.org      for(unsigned int i=0; i<size_in_bytes; ++i){
11436145Snate@binkert.org        int offset = addr.getOffset();
11446145Snate@binkert.org        value[i] = n->m_Directory_directory_vec[dir_version]->lookup(lineAddr).m_DataBlk.getByte(offset + i);
11456145Snate@binkert.org      }
11466145Snate@binkert.org      // Address not found
11476145Snate@binkert.org      //WARN_MSG("Couldn't find address");
11486145Snate@binkert.org      //WARN_EXPR(addr);
11496145Snate@binkert.org      found = false;
11506145Snate@binkert.org    }
11516145Snate@binkert.org    return true;
11526145Snate@binkert.org  }
11536145Snate@binkert.org}
11546145Snate@binkert.org
11556145Snate@binkert.orgbool Sequencer::setRubyMemoryValue(const Address& addr, char *value,
11566145Snate@binkert.org                                   unsigned int size_in_bytes) {
11576145Snate@binkert.org  char test_buffer[64];
11586145Snate@binkert.org
11596145Snate@binkert.org  if(g_SIMICS){
11606145Snate@binkert.org    return false; // Do nothing?
11616145Snate@binkert.org  } else {
11626145Snate@binkert.org    // idea here is that coherent cache should find the
11636145Snate@binkert.org    // latest data, the update it
11646145Snate@binkert.org    bool found = false;
11656145Snate@binkert.org    const Address lineAddr = line_address(addr);
11666145Snate@binkert.org    PhysAddress paddr(addr);
11676145Snate@binkert.org    DataBlock data;
11686145Snate@binkert.org    DataBlock* dataPtr = &data;
11696145Snate@binkert.org    Chip* n = dynamic_cast<Chip*>(m_chip_ptr);
11706145Snate@binkert.org
11716145Snate@binkert.org    MachineID l2_mach = map_L2ChipId_to_L2Cache(addr, m_chip_ptr->getID() );
11726145Snate@binkert.org    int l2_ver = l2_mach.num%RubyConfig::numberOfL2CachePerChip();
11736145Snate@binkert.org    // LUKE - use variable names instead of macros
11746145Snate@binkert.org    //cout << "number of L2caches per chip = " << RubyConfig::numberOfL2CachePerChip(m_version) << endl;
11756145Snate@binkert.org    //cout << "L1I cache vec size = " << n->m_L1Cache_L1IcacheMemory_vec.size() << endl;
11766145Snate@binkert.org    //cout << "L1D cache vec size = " << n->m_L1Cache_L1DcacheMemory_vec.size() << endl;
11776145Snate@binkert.org    //cout << "L1cache_cachememory size = " << n->m_L1Cache_cacheMemory_vec.size() << endl;
11786145Snate@binkert.org    //cout << "L1cache_l2cachememory size = " << n->m_L1Cache_L2cacheMemory_vec.size() << endl;
11796145Snate@binkert.org    // if (Protocol::m_TwoLevelCache) {
11806151Sdrh5@cs.wisc.edu    //       if(Protocol::m_CMP){
11816151Sdrh5@cs.wisc.edu    //         cout << "CMP L2 cache vec size = " << n->m_L2Cache_L2cacheMemory_vec.size() << endl;
11826151Sdrh5@cs.wisc.edu    //       }
11836151Sdrh5@cs.wisc.edu    //       else{
11846151Sdrh5@cs.wisc.edu    //        cout << "L2 cache vec size = " << n->m_L1Cache_cacheMemory_vec.size() << endl;
11856151Sdrh5@cs.wisc.edu    //       }
11866151Sdrh5@cs.wisc.edu    //     }
11876145Snate@binkert.org
11886145Snate@binkert.org    assert(n->m_L1Cache_L1IcacheMemory_vec[m_version] != NULL);
11896145Snate@binkert.org    assert(n->m_L1Cache_L1DcacheMemory_vec[m_version] != NULL);
11906145Snate@binkert.org    if (Protocol::m_TwoLevelCache) {
11916145Snate@binkert.org      if(Protocol::m_CMP){
11926145Snate@binkert.org        assert(n->m_L2Cache_L2cacheMemory_vec[l2_ver] != NULL);
11936145Snate@binkert.org      }
11946145Snate@binkert.org      else{
11956145Snate@binkert.org        assert(n->m_L1Cache_cacheMemory_vec[m_version] != NULL);
11966145Snate@binkert.org      }
11976145Snate@binkert.org    }
11986145Snate@binkert.org
11996145Snate@binkert.org    if (n->m_L1Cache_L1IcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_IFETCH, dataPtr)){
12006145Snate@binkert.org      n->m_L1Cache_L1IcacheMemory_vec[m_version]->setMemoryValue(addr, value, size_in_bytes);
12016145Snate@binkert.org      found = true;
12026145Snate@binkert.org    } else if (n->m_L1Cache_L1DcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){
12036145Snate@binkert.org      n->m_L1Cache_L1DcacheMemory_vec[m_version]->setMemoryValue(addr, value, size_in_bytes);
12046145Snate@binkert.org      found = true;
12056145Snate@binkert.org    } else if (Protocol::m_CMP && n->m_L2Cache_L2cacheMemory_vec[l2_ver]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){
12066145Snate@binkert.org      n->m_L2Cache_L2cacheMemory_vec[l2_ver]->setMemoryValue(addr, value, size_in_bytes);
12076145Snate@binkert.org      found = true;
12086151Sdrh5@cs.wisc.edu      // } else if (n->TBE_TABLE_MEMBER_VARIABLE->isTagPresent(lineAddr)){
12096151Sdrh5@cs.wisc.edu      //       L1Cache_TBE& tbeEntry = n->TBE_TABLE_MEMBER_VARIABLE->lookup(lineAddr);
12106151Sdrh5@cs.wisc.edu      //       DataBlock tmpData;
12116151Sdrh5@cs.wisc.edu      //       int offset = addr.getOffset();
12126151Sdrh5@cs.wisc.edu      //       for(int i=0; i<size_in_bytes; ++i){
12136151Sdrh5@cs.wisc.edu      //         tmpData.setByte(offset + i, value[i]);
12146151Sdrh5@cs.wisc.edu      //       }
12156151Sdrh5@cs.wisc.edu      //       tbeEntry.setDataBlk(tmpData);
12166151Sdrh5@cs.wisc.edu      //       tbeEntry.setDirty(true);
12176145Snate@binkert.org    } else {
12186145Snate@binkert.org      // Address not found
12196145Snate@binkert.org      n = dynamic_cast<Chip*>(g_system_ptr->getChip(map_Address_to_DirectoryNode(addr)/RubyConfig::numberOfDirectoryPerChip()));
12206145Snate@binkert.org      int dir_version = map_Address_to_DirectoryNode(addr)%RubyConfig::numberOfDirectoryPerChip();
12216145Snate@binkert.org      for(unsigned int i=0; i<size_in_bytes; ++i){
12226145Snate@binkert.org        int offset = addr.getOffset();
12236145Snate@binkert.org        n->m_Directory_directory_vec[dir_version]->lookup(lineAddr).m_DataBlk.setByte(offset + i, value[i]);
12246145Snate@binkert.org      }
12256145Snate@binkert.org      found = false;
12266145Snate@binkert.org    }
12276145Snate@binkert.org
12286145Snate@binkert.org    if (found){
12296145Snate@binkert.org      found = getRubyMemoryValue(addr, test_buffer, size_in_bytes);
12306145Snate@binkert.org      assert(found);
12316145Snate@binkert.org      if(value[0] != test_buffer[0]){
12326145Snate@binkert.org        WARN_EXPR((int) value[0]);
12336145Snate@binkert.org        WARN_EXPR((int) test_buffer[0]);
12346145Snate@binkert.org        ERROR_MSG("setRubyMemoryValue failed to set value.");
12356145Snate@binkert.org      }
12366145Snate@binkert.org    }
12376145Snate@binkert.org
12386145Snate@binkert.org    return true;
12396145Snate@binkert.org  }
12406145Snate@binkert.org}
1241