Sequencer.cc revision 6145
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 6166145Snate@binkert.org #if 0 6176145Snate@binkert.org uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick")); 6186145Snate@binkert.org uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr")); 6196145Snate@binkert.org uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick")); 6206145Snate@binkert.org uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr")); 6216145Snate@binkert.org 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; 6226145Snate@binkert.org #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 7876145Snate@binkert.orgbool Sequencer::isReady(const CacheMsg& request) const { 7886145Snate@binkert.org 7896145Snate@binkert.org if (m_outstanding_count >= g_SEQUENCER_OUTSTANDING_REQUESTS) { 7906145Snate@binkert.org //cout << "TOO MANY OUTSTANDING: " << m_outstanding_count << " " << g_SEQUENCER_OUTSTANDING_REQUESTS << " VER " << m_version << endl; 7916145Snate@binkert.org //printProgress(cout); 7926145Snate@binkert.org return false; 7936145Snate@binkert.org } 7946145Snate@binkert.org int thread = request.getThreadID(); 7956145Snate@binkert.org 7966145Snate@binkert.org // This code allows reads to be performed even when we have a write 7976145Snate@binkert.org // request outstanding for the line 7986145Snate@binkert.org bool write = 7996145Snate@binkert.org (request.getType() == CacheRequestType_ST) || 8006145Snate@binkert.org (request.getType() == CacheRequestType_ST_XACT) || 8016145Snate@binkert.org (request.getType() == CacheRequestType_LDX_XACT) || 8026145Snate@binkert.org (request.getType() == CacheRequestType_ATOMIC); 8036145Snate@binkert.org 8046145Snate@binkert.org // LUKE - disallow more than one request type per address 8056145Snate@binkert.org // INVARIANT: at most one request type per address, per processor 8066145Snate@binkert.org int smt_threads = RubyConfig::numberofSMTThreads(); 8076145Snate@binkert.org for(int p=0; p < smt_threads; ++p){ 8086145Snate@binkert.org if( m_writeRequestTable_ptr[p]->exist(line_address(request.getAddress())) || 8096145Snate@binkert.org m_readRequestTable_ptr[p]->exist(line_address(request.getAddress())) ){ 8106145Snate@binkert.org //cout << "OUTSTANDING REQUEST EXISTS " << p << " VER " << m_version << endl; 8116145Snate@binkert.org //printProgress(cout); 8126145Snate@binkert.org return false; 8136145Snate@binkert.org } 8146145Snate@binkert.org } 8156145Snate@binkert.org 8166145Snate@binkert.org if (TSO) { 8176145Snate@binkert.org return m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady(); 8186145Snate@binkert.org } 8196145Snate@binkert.org return true; 8206145Snate@binkert.org} 8216145Snate@binkert.org 8226145Snate@binkert.org// Called by Driver (Simics or Tester). 8236145Snate@binkert.orgvoid Sequencer::makeRequest(const CacheMsg& request) { 8246145Snate@binkert.org //assert(isReady(request)); 8256145Snate@binkert.org bool write = (request.getType() == CacheRequestType_ST) || 8266145Snate@binkert.org (request.getType() == CacheRequestType_ST_XACT) || 8276145Snate@binkert.org (request.getType() == CacheRequestType_LDX_XACT) || 8286145Snate@binkert.org (request.getType() == CacheRequestType_ATOMIC); 8296145Snate@binkert.org 8306145Snate@binkert.org if (TSO && (request.getPrefetch() == PrefetchBit_No) && write) { 8316145Snate@binkert.org assert(m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->isReady()); 8326145Snate@binkert.org m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->insertStore(request); 8336145Snate@binkert.org return; 8346145Snate@binkert.org } 8356145Snate@binkert.org 8366145Snate@binkert.org bool hit = doRequest(request); 8376145Snate@binkert.org 8386145Snate@binkert.org} 8396145Snate@binkert.org 8406145Snate@binkert.orgbool Sequencer::doRequest(const CacheMsg& request) { 8416145Snate@binkert.org bool hit = false; 8426145Snate@binkert.org // Check the fast path 8436145Snate@binkert.org DataBlock* data_ptr; 8446145Snate@binkert.org 8456145Snate@binkert.org int thread = request.getThreadID(); 8466145Snate@binkert.org 8476145Snate@binkert.org hit = tryCacheAccess(line_address(request.getAddress()), 8486145Snate@binkert.org request.getType(), 8496145Snate@binkert.org request.getProgramCounter(), 8506145Snate@binkert.org request.getAccessMode(), 8516145Snate@binkert.org request.getSize(), 8526145Snate@binkert.org data_ptr); 8536145Snate@binkert.org 8546145Snate@binkert.org if (hit && (request.getType() == CacheRequestType_IFETCH || !REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH) ) { 8556145Snate@binkert.org DEBUG_MSG(SEQUENCER_COMP, MedPrio, "Fast path hit"); 8566145Snate@binkert.org hitCallback(request, *data_ptr, GenericMachineType_L1Cache, thread); 8576145Snate@binkert.org return true; 8586145Snate@binkert.org } 8596145Snate@binkert.org 8606145Snate@binkert.org #if 0 8616145Snate@binkert.org uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick")); 8626145Snate@binkert.org uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr")); 8636145Snate@binkert.org uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick")); 8646145Snate@binkert.org uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr")); 8656145Snate@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;; 8666145Snate@binkert.org #endif 8676145Snate@binkert.org 8686145Snate@binkert.org if (TSO && (request.getType() == CacheRequestType_LD || request.getType() == CacheRequestType_IFETCH)) { 8696145Snate@binkert.org 8706145Snate@binkert.org // See if we can satisfy the load entirely from the store buffer 8716145Snate@binkert.org SubBlock subblock(line_address(request.getAddress()), request.getSize()); 8726145Snate@binkert.org if (m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->trySubBlock(subblock)) { 8736145Snate@binkert.org DataBlock dummy; 8746145Snate@binkert.org hitCallback(request, dummy, GenericMachineType_NULL, thread); // Call with an 'empty' datablock, since the data is in the store buffer 8756145Snate@binkert.org return true; 8766145Snate@binkert.org } 8776145Snate@binkert.org } 8786145Snate@binkert.org 8796145Snate@binkert.org DEBUG_MSG(SEQUENCER_COMP, MedPrio, "Fast path miss"); 8806145Snate@binkert.org issueRequest(request); 8816145Snate@binkert.org return hit; 8826145Snate@binkert.org} 8836145Snate@binkert.org 8846145Snate@binkert.orgvoid Sequencer::issueRequest(const CacheMsg& request) { 8856145Snate@binkert.org bool found = insertRequest(request); 8866145Snate@binkert.org 8876145Snate@binkert.org if (!found) { 8886145Snate@binkert.org CacheMsg msg = request; 8896145Snate@binkert.org msg.getAddress() = line_address(request.getAddress()); // Make line address 8906145Snate@binkert.org 8916145Snate@binkert.org // Fast Path L1 misses are profiled here - all non-fast path misses are profiled within the generated protocol code 8926145Snate@binkert.org if (!REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH) { 8936145Snate@binkert.org g_system_ptr->getProfiler()->addPrimaryStatSample(msg, m_chip_ptr->getID()); 8946145Snate@binkert.org } 8956145Snate@binkert.org 8966145Snate@binkert.org if (PROTOCOL_DEBUG_TRACE) { 8976145Snate@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())); 8986145Snate@binkert.org } 8996145Snate@binkert.org 9006145Snate@binkert.org#if 0 9016145Snate@binkert.org // Commented out by nate binkert because I removed the trace stuff 9026145Snate@binkert.org if (g_system_ptr->getTracer()->traceEnabled()) { 9036145Snate@binkert.org g_system_ptr->getTracer()->traceRequest((m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version), msg.getAddress(), msg.getProgramCounter(), 9046145Snate@binkert.org msg.getType(), g_eventQueue_ptr->getTime()); 9056145Snate@binkert.org } 9066145Snate@binkert.org#endif 9076145Snate@binkert.org 9086145Snate@binkert.org Time latency = 0; // initialzed to an null value 9096145Snate@binkert.org 9106145Snate@binkert.org latency = SEQUENCER_TO_CONTROLLER_LATENCY; 9116145Snate@binkert.org 9126145Snate@binkert.org // Send the message to the cache controller 9136145Snate@binkert.org assert(latency > 0); 9146145Snate@binkert.org m_chip_ptr->m_L1Cache_mandatoryQueue_vec[m_version]->enqueue(msg, latency); 9156145Snate@binkert.org 9166145Snate@binkert.org } // !found 9176145Snate@binkert.org} 9186145Snate@binkert.org 9196145Snate@binkert.orgbool Sequencer::tryCacheAccess(const Address& addr, CacheRequestType type, 9206145Snate@binkert.org const Address& pc, AccessModeType access_mode, 9216145Snate@binkert.org int size, DataBlock*& data_ptr) { 9226145Snate@binkert.org if (type == CacheRequestType_IFETCH) { 9236145Snate@binkert.org if (Protocol::m_TwoLevelCache) { 9246145Snate@binkert.org return m_chip_ptr->m_L1Cache_L1IcacheMemory_vec[m_version]->tryCacheAccess(line_address(addr), type, data_ptr); 9256145Snate@binkert.org } 9266145Snate@binkert.org else { 9276145Snate@binkert.org return m_chip_ptr->m_L1Cache_cacheMemory_vec[m_version]->tryCacheAccess(line_address(addr), type, data_ptr); 9286145Snate@binkert.org } 9296145Snate@binkert.org } else { 9306145Snate@binkert.org if (Protocol::m_TwoLevelCache) { 9316145Snate@binkert.org return m_chip_ptr->m_L1Cache_L1DcacheMemory_vec[m_version]->tryCacheAccess(line_address(addr), type, data_ptr); 9326145Snate@binkert.org } 9336145Snate@binkert.org else { 9346145Snate@binkert.org return m_chip_ptr->m_L1Cache_cacheMemory_vec[m_version]->tryCacheAccess(line_address(addr), type, data_ptr); 9356145Snate@binkert.org } 9366145Snate@binkert.org } 9376145Snate@binkert.org} 9386145Snate@binkert.org 9396145Snate@binkert.orgvoid Sequencer::resetRequestTime(const Address& addr, int thread){ 9406145Snate@binkert.org assert(thread >= 0); 9416145Snate@binkert.org //reset both load and store requests, if they exist 9426145Snate@binkert.org if(m_readRequestTable_ptr[thread]->exist(line_address(addr))){ 9436145Snate@binkert.org CacheMsg& request = m_readRequestTable_ptr[thread]->lookup(addr); 9446145Snate@binkert.org if( request.m_AccessMode != AccessModeType_UserMode){ 9456145Snate@binkert.org cout << "resetRequestType ERROR read request addr = " << addr << " thread = "<< thread << " is SUPERVISOR MODE" << endl; 9466145Snate@binkert.org printProgress(cout); 9476145Snate@binkert.org } 9486145Snate@binkert.org //ASSERT(request.m_AccessMode == AccessModeType_UserMode); 9496145Snate@binkert.org request.setTime(g_eventQueue_ptr->getTime()); 9506145Snate@binkert.org } 9516145Snate@binkert.org if(m_writeRequestTable_ptr[thread]->exist(line_address(addr))){ 9526145Snate@binkert.org CacheMsg& request = m_writeRequestTable_ptr[thread]->lookup(addr); 9536145Snate@binkert.org if( request.m_AccessMode != AccessModeType_UserMode){ 9546145Snate@binkert.org cout << "resetRequestType ERROR write request addr = " << addr << " thread = "<< thread << " is SUPERVISOR MODE" << endl; 9556145Snate@binkert.org printProgress(cout); 9566145Snate@binkert.org } 9576145Snate@binkert.org //ASSERT(request.m_AccessMode == AccessModeType_UserMode); 9586145Snate@binkert.org request.setTime(g_eventQueue_ptr->getTime()); 9596145Snate@binkert.org } 9606145Snate@binkert.org} 9616145Snate@binkert.org 9626145Snate@binkert.org// removes load request from queue 9636145Snate@binkert.orgvoid Sequencer::removeLoadRequest(const Address & addr, int thread){ 9646145Snate@binkert.org removeRequest(getReadRequest(addr, thread)); 9656145Snate@binkert.org} 9666145Snate@binkert.org 9676145Snate@binkert.orgvoid Sequencer::removeStoreRequest(const Address & addr, int thread){ 9686145Snate@binkert.org removeRequest(getWriteRequest(addr, thread)); 9696145Snate@binkert.org} 9706145Snate@binkert.org 9716145Snate@binkert.org// returns the read CacheMsg 9726145Snate@binkert.orgCacheMsg & Sequencer::getReadRequest( const Address & addr, int thread ){ 9736145Snate@binkert.org Address temp = addr; 9746145Snate@binkert.org assert(thread >= 0); 9756145Snate@binkert.org assert(temp == line_address(temp)); 9766145Snate@binkert.org assert(m_readRequestTable_ptr[thread]->exist(addr)); 9776145Snate@binkert.org return m_readRequestTable_ptr[thread]->lookup(addr); 9786145Snate@binkert.org} 9796145Snate@binkert.org 9806145Snate@binkert.orgCacheMsg & Sequencer::getWriteRequest( const Address & addr, int thread){ 9816145Snate@binkert.org Address temp = addr; 9826145Snate@binkert.org assert(thread >= 0); 9836145Snate@binkert.org assert(temp == line_address(temp)); 9846145Snate@binkert.org assert(m_writeRequestTable_ptr[thread]->exist(addr)); 9856145Snate@binkert.org return m_writeRequestTable_ptr[thread]->lookup(addr); 9866145Snate@binkert.org} 9876145Snate@binkert.org 9886145Snate@binkert.orgvoid Sequencer::print(ostream& out) const { 9896145Snate@binkert.org out << "[Sequencer: " << m_chip_ptr->getID() 9906145Snate@binkert.org << ", outstanding requests: " << m_outstanding_count; 9916145Snate@binkert.org 9926145Snate@binkert.org int smt_threads = RubyConfig::numberofSMTThreads(); 9936145Snate@binkert.org for(int p=0; p < smt_threads; ++p){ 9946145Snate@binkert.org out << ", read request table[ " << p << " ]: " << *m_readRequestTable_ptr[p] 9956145Snate@binkert.org << ", write request table[ " << p << " ]: " << *m_writeRequestTable_ptr[p]; 9966145Snate@binkert.org } 9976145Snate@binkert.org out << "]"; 9986145Snate@binkert.org} 9996145Snate@binkert.org 10006145Snate@binkert.org// this can be called from setState whenever coherence permissions are upgraded 10016145Snate@binkert.org// when invoked, coherence violations will be checked for the given block 10026145Snate@binkert.orgvoid Sequencer::checkCoherence(const Address& addr) { 10036145Snate@binkert.org#ifdef CHECK_COHERENCE 10046145Snate@binkert.org g_system_ptr->checkGlobalCoherenceInvariant(addr); 10056145Snate@binkert.org#endif 10066145Snate@binkert.org} 10076145Snate@binkert.org 10086145Snate@binkert.orgbool Sequencer::getRubyMemoryValue(const Address& addr, char* value, 10096145Snate@binkert.org unsigned int size_in_bytes ) { 10106145Snate@binkert.org if(g_SIMICS){ 10116145Snate@binkert.org for(unsigned int i=0; i < size_in_bytes; i++) { 10126145Snate@binkert.org value[i] = SIMICS_read_physical_memory( m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, 10136145Snate@binkert.org addr.getAddress() + i, 1 ); 10146145Snate@binkert.org } 10156145Snate@binkert.org return false; // Do nothing? 10166145Snate@binkert.org } else { 10176145Snate@binkert.org bool found = false; 10186145Snate@binkert.org const Address lineAddr = line_address(addr); 10196145Snate@binkert.org DataBlock data; 10206145Snate@binkert.org PhysAddress paddr(addr); 10216145Snate@binkert.org DataBlock* dataPtr = &data; 10226145Snate@binkert.org Chip* n = dynamic_cast<Chip*>(m_chip_ptr); 10236145Snate@binkert.org // LUKE - use variable names instead of macros 10246145Snate@binkert.org assert(n->m_L1Cache_L1IcacheMemory_vec[m_version] != NULL); 10256145Snate@binkert.org assert(n->m_L1Cache_L1DcacheMemory_vec[m_version] != NULL); 10266145Snate@binkert.org 10276145Snate@binkert.org MachineID l2_mach = map_L2ChipId_to_L2Cache(addr, m_chip_ptr->getID() ); 10286145Snate@binkert.org int l2_ver = l2_mach.num%RubyConfig::numberOfL2CachePerChip(); 10296145Snate@binkert.org 10306145Snate@binkert.org if (Protocol::m_TwoLevelCache) { 10316145Snate@binkert.org if(Protocol::m_CMP){ 10326145Snate@binkert.org assert(n->m_L2Cache_L2cacheMemory_vec[l2_ver] != NULL); 10336145Snate@binkert.org } 10346145Snate@binkert.org else{ 10356145Snate@binkert.org assert(n->m_L1Cache_cacheMemory_vec[m_version] != NULL); 10366145Snate@binkert.org } 10376145Snate@binkert.org } 10386145Snate@binkert.org 10396145Snate@binkert.org if (n->m_L1Cache_L1IcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_IFETCH, dataPtr)){ 10406145Snate@binkert.org n->m_L1Cache_L1IcacheMemory_vec[m_version]->getMemoryValue(addr, value, size_in_bytes); 10416145Snate@binkert.org found = true; 10426145Snate@binkert.org } else if (n->m_L1Cache_L1DcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){ 10436145Snate@binkert.org n->m_L1Cache_L1DcacheMemory_vec[m_version]->getMemoryValue(addr, value, size_in_bytes); 10446145Snate@binkert.org found = true; 10456145Snate@binkert.org } else if (Protocol::m_CMP && n->m_L2Cache_L2cacheMemory_vec[l2_ver]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){ 10466145Snate@binkert.org n->m_L2Cache_L2cacheMemory_vec[l2_ver]->getMemoryValue(addr, value, size_in_bytes); 10476145Snate@binkert.org found = true; 10486145Snate@binkert.org // } else if (n->TBE_TABLE_MEMBER_VARIABLE->isPresent(lineAddr)){ 10496145Snate@binkert.org// ASSERT(n->TBE_TABLE_MEMBER_VARIABLE->isPresent(lineAddr)); 10506145Snate@binkert.org// L1Cache_TBE tbeEntry = n->TBE_TABLE_MEMBER_VARIABLE->lookup(lineAddr); 10516145Snate@binkert.org 10526145Snate@binkert.org// int offset = addr.getOffset(); 10536145Snate@binkert.org// for(int i=0; i<size_in_bytes; ++i){ 10546145Snate@binkert.org// value[i] = tbeEntry.getDataBlk().getByte(offset + i); 10556145Snate@binkert.org// } 10566145Snate@binkert.org 10576145Snate@binkert.org// found = true; 10586145Snate@binkert.org } else { 10596145Snate@binkert.org // Address not found 10606145Snate@binkert.org //cout << " " << m_chip_ptr->getID() << " NOT IN CACHE, Value at Directory is: " << (int) value[0] << endl; 10616145Snate@binkert.org n = dynamic_cast<Chip*>(g_system_ptr->getChip(map_Address_to_DirectoryNode(addr)/RubyConfig::numberOfDirectoryPerChip())); 10626145Snate@binkert.org int dir_version = map_Address_to_DirectoryNode(addr)%RubyConfig::numberOfDirectoryPerChip(); 10636145Snate@binkert.org for(unsigned int i=0; i<size_in_bytes; ++i){ 10646145Snate@binkert.org int offset = addr.getOffset(); 10656145Snate@binkert.org value[i] = n->m_Directory_directory_vec[dir_version]->lookup(lineAddr).m_DataBlk.getByte(offset + i); 10666145Snate@binkert.org } 10676145Snate@binkert.org // Address not found 10686145Snate@binkert.org //WARN_MSG("Couldn't find address"); 10696145Snate@binkert.org //WARN_EXPR(addr); 10706145Snate@binkert.org found = false; 10716145Snate@binkert.org } 10726145Snate@binkert.org return true; 10736145Snate@binkert.org } 10746145Snate@binkert.org} 10756145Snate@binkert.org 10766145Snate@binkert.orgbool Sequencer::setRubyMemoryValue(const Address& addr, char *value, 10776145Snate@binkert.org unsigned int size_in_bytes) { 10786145Snate@binkert.org char test_buffer[64]; 10796145Snate@binkert.org 10806145Snate@binkert.org if(g_SIMICS){ 10816145Snate@binkert.org return false; // Do nothing? 10826145Snate@binkert.org } else { 10836145Snate@binkert.org // idea here is that coherent cache should find the 10846145Snate@binkert.org // latest data, the update it 10856145Snate@binkert.org bool found = false; 10866145Snate@binkert.org const Address lineAddr = line_address(addr); 10876145Snate@binkert.org PhysAddress paddr(addr); 10886145Snate@binkert.org DataBlock data; 10896145Snate@binkert.org DataBlock* dataPtr = &data; 10906145Snate@binkert.org Chip* n = dynamic_cast<Chip*>(m_chip_ptr); 10916145Snate@binkert.org 10926145Snate@binkert.org MachineID l2_mach = map_L2ChipId_to_L2Cache(addr, m_chip_ptr->getID() ); 10936145Snate@binkert.org int l2_ver = l2_mach.num%RubyConfig::numberOfL2CachePerChip(); 10946145Snate@binkert.org // LUKE - use variable names instead of macros 10956145Snate@binkert.org //cout << "number of L2caches per chip = " << RubyConfig::numberOfL2CachePerChip(m_version) << endl; 10966145Snate@binkert.org //cout << "L1I cache vec size = " << n->m_L1Cache_L1IcacheMemory_vec.size() << endl; 10976145Snate@binkert.org //cout << "L1D cache vec size = " << n->m_L1Cache_L1DcacheMemory_vec.size() << endl; 10986145Snate@binkert.org //cout << "L1cache_cachememory size = " << n->m_L1Cache_cacheMemory_vec.size() << endl; 10996145Snate@binkert.org //cout << "L1cache_l2cachememory size = " << n->m_L1Cache_L2cacheMemory_vec.size() << endl; 11006145Snate@binkert.org // if (Protocol::m_TwoLevelCache) { 11016145Snate@binkert.org// if(Protocol::m_CMP){ 11026145Snate@binkert.org// cout << "CMP L2 cache vec size = " << n->m_L2Cache_L2cacheMemory_vec.size() << endl; 11036145Snate@binkert.org// } 11046145Snate@binkert.org// else{ 11056145Snate@binkert.org// cout << "L2 cache vec size = " << n->m_L1Cache_cacheMemory_vec.size() << endl; 11066145Snate@binkert.org// } 11076145Snate@binkert.org// } 11086145Snate@binkert.org 11096145Snate@binkert.org assert(n->m_L1Cache_L1IcacheMemory_vec[m_version] != NULL); 11106145Snate@binkert.org assert(n->m_L1Cache_L1DcacheMemory_vec[m_version] != NULL); 11116145Snate@binkert.org if (Protocol::m_TwoLevelCache) { 11126145Snate@binkert.org if(Protocol::m_CMP){ 11136145Snate@binkert.org assert(n->m_L2Cache_L2cacheMemory_vec[l2_ver] != NULL); 11146145Snate@binkert.org } 11156145Snate@binkert.org else{ 11166145Snate@binkert.org assert(n->m_L1Cache_cacheMemory_vec[m_version] != NULL); 11176145Snate@binkert.org } 11186145Snate@binkert.org } 11196145Snate@binkert.org 11206145Snate@binkert.org if (n->m_L1Cache_L1IcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_IFETCH, dataPtr)){ 11216145Snate@binkert.org n->m_L1Cache_L1IcacheMemory_vec[m_version]->setMemoryValue(addr, value, size_in_bytes); 11226145Snate@binkert.org found = true; 11236145Snate@binkert.org } else if (n->m_L1Cache_L1DcacheMemory_vec[m_version]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){ 11246145Snate@binkert.org n->m_L1Cache_L1DcacheMemory_vec[m_version]->setMemoryValue(addr, value, size_in_bytes); 11256145Snate@binkert.org found = true; 11266145Snate@binkert.org } else if (Protocol::m_CMP && n->m_L2Cache_L2cacheMemory_vec[l2_ver]->tryCacheAccess(lineAddr, CacheRequestType_LD, dataPtr)){ 11276145Snate@binkert.org n->m_L2Cache_L2cacheMemory_vec[l2_ver]->setMemoryValue(addr, value, size_in_bytes); 11286145Snate@binkert.org found = true; 11296145Snate@binkert.org // } else if (n->TBE_TABLE_MEMBER_VARIABLE->isTagPresent(lineAddr)){ 11306145Snate@binkert.org// L1Cache_TBE& tbeEntry = n->TBE_TABLE_MEMBER_VARIABLE->lookup(lineAddr); 11316145Snate@binkert.org// DataBlock tmpData; 11326145Snate@binkert.org// int offset = addr.getOffset(); 11336145Snate@binkert.org// for(int i=0; i<size_in_bytes; ++i){ 11346145Snate@binkert.org// tmpData.setByte(offset + i, value[i]); 11356145Snate@binkert.org// } 11366145Snate@binkert.org// tbeEntry.setDataBlk(tmpData); 11376145Snate@binkert.org// tbeEntry.setDirty(true); 11386145Snate@binkert.org } else { 11396145Snate@binkert.org // Address not found 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 n->m_Directory_directory_vec[dir_version]->lookup(lineAddr).m_DataBlk.setByte(offset + i, value[i]); 11456145Snate@binkert.org } 11466145Snate@binkert.org found = false; 11476145Snate@binkert.org } 11486145Snate@binkert.org 11496145Snate@binkert.org if (found){ 11506145Snate@binkert.org found = getRubyMemoryValue(addr, test_buffer, size_in_bytes); 11516145Snate@binkert.org assert(found); 11526145Snate@binkert.org if(value[0] != test_buffer[0]){ 11536145Snate@binkert.org WARN_EXPR((int) value[0]); 11546145Snate@binkert.org WARN_EXPR((int) test_buffer[0]); 11556145Snate@binkert.org ERROR_MSG("setRubyMemoryValue failed to set value."); 11566145Snate@binkert.org } 11576145Snate@binkert.org } 11586145Snate@binkert.org 11596145Snate@binkert.org return true; 11606145Snate@binkert.org } 11616145Snate@binkert.org} 1162