diff options
Diffstat (limited to 'src/mem/ruby/interfaces')
-rw-r--r-- | src/mem/ruby/interfaces/OpalInterface.cc | 446 | ||||
-rw-r--r-- | src/mem/ruby/interfaces/OpalInterface.hh | 214 |
2 files changed, 0 insertions, 660 deletions
diff --git a/src/mem/ruby/interfaces/OpalInterface.cc b/src/mem/ruby/interfaces/OpalInterface.cc deleted file mode 100644 index 362c7bcb6..000000000 --- a/src/mem/ruby/interfaces/OpalInterface.cc +++ /dev/null @@ -1,446 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - */ - -/*------------------------------------------------------------------------*/ -/* Includes */ -/*------------------------------------------------------------------------*/ - -#include "OpalInterface.hh" -#include "interface.hh" -#include "System.hh" -#include "SubBlock.hh" -#include "mf_api.hh" -#include "Chip.hh" -#include "RubyConfig.hh" -//#include "XactIsolationChecker.hh" //gem5:Arka for decomissioning ruby/log_tm -// #include "TransactionInterfaceManager.hh" -//#include "TransactionVersionManager.hh" //gem5:Arka for decomissioning ruby/log_tm -#include "Sequencer.hh" - -/*------------------------------------------------------------------------*/ -/* Forward declarations */ -/*------------------------------------------------------------------------*/ - -static CacheRequestType get_request_type( OpalMemop_t opaltype ); -static OpalMemop_t get_opal_request_type( CacheRequestType type ); - -/// The static opalinterface instance -OpalInterface *OpalInterface::inst = NULL; - -/*------------------------------------------------------------------------*/ -/* Constructor(s) / destructor */ -/*------------------------------------------------------------------------*/ - -//************************************************************************** -OpalInterface::OpalInterface(System* sys_ptr) { - clearStats(); - ASSERT( inst == NULL ); - inst = this; - m_opal_intf = NULL; -} - -/*------------------------------------------------------------------------*/ -/* Public methods */ -/*------------------------------------------------------------------------*/ - -//************************************************************************** -void OpalInterface::printConfig(ostream& out) const { - out << "Opal_ruby_multiplier: " << OPAL_RUBY_MULTIPLIER << endl; - out << endl; -} - -void OpalInterface::printStats(ostream& out) const { - out << endl; - out << "Opal Interface Stats" << endl; - out << "----------------------" << endl; - out << endl; -} - -//************************************************************************** -void OpalInterface::clearStats() { -} - -//************************************************************************** -integer_t OpalInterface::getInstructionCount(int procID) const { - return ((*m_opal_intf->getInstructionCount)(procID)); -} - -//************************************************************************* -uint64 OpalInterface::getOpalTime(int procID) const { - return ((*m_opal_intf->getOpalTime)(procID)); -} - -/************ For WATTCH power stats ************************************/ -//************************************************************************* -void OpalInterface::incrementL2Access(int procID) const{ - ((*m_opal_intf->incrementL2Access)(procID)); -} - -//************************************************************************* -void OpalInterface::incrementPrefetcherAccess(int procID, int num_prefetches, int isinstr) const{ - ((*m_opal_intf->incrementPrefetcherAccess)(procID, num_prefetches, isinstr)); -} -/******************** END WATTCH power stats ****************************/ - -// Notifies Opal of an L2 miss -//************************************************************************* -void OpalInterface::notifyL2Miss(int procID, physical_address_t physicalAddr, OpalMemop_t type, int tagexists) const{ - ((*m_opal_intf->notifyL2Miss)(procID, physicalAddr, type, tagexists)); -} - -/****************************************************************** - * void hitCallback(int cpuNumber) - * Called by Sequencer. Calls opal. - ******************************************************************/ - -//************************************************************************** -void OpalInterface::hitCallback(NodeID proc, SubBlock& data, CacheRequestType type, int thread) { - // notify opal that the transaction has completed - (*m_opal_intf->hitCallback)( proc, data.getAddress().getAddress(), get_opal_request_type(type), thread ); -} - -//************************************************************************** -// Useful functions if Ruby needs to read/write physical memory when running with Opal -integer_t OpalInterface::readPhysicalMemory(int procID, - physical_address_t address, - int len ){ - return SIMICS_read_physical_memory(procID, address, len); -} - -//************************************************************************** -void OpalInterface::writePhysicalMemory( int procID, - physical_address_t address, - integer_t value, - int len ){ - SIMICS_write_physical_memory(procID, address, value, len); -} - -//*************************************************************** -// notifies Opal to print debug info -void OpalInterface::printDebug(){ - (*m_opal_intf->printDebug)(); -} - -//*************************************************************** - -/****************************************************************** - * Called by opal's memory operations (memop.C) - * May call Sequencer. - ******************************************************************/ - -//**************************************************************************** -int OpalInterface::getNumberOutstanding( int cpuNumber ){ - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->getSequencer(cpuNumber%RubyConfig::numberOfProcsPerChip()); - - return targetSequencer_ptr->getNumberOutstanding(); -} - -//**************************************************************************** -int OpalInterface::getNumberOutstandingDemand( int cpuNumber ){ - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->getSequencer(cpuNumber%RubyConfig::numberOfProcsPerChip()); - - return targetSequencer_ptr->getNumberOutstandingDemand(); -} - -//**************************************************************************** -int OpalInterface::getNumberOutstandingPrefetch( int cpuNumber ){ - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->getSequencer(cpuNumber%RubyConfig::numberOfProcsPerChip()); - - return targetSequencer_ptr->getNumberOutstandingPrefetch(); -} - -//************************************************************************** -int OpalInterface::isReady( int cpuNumber, la_t logicalAddr, pa_t physicalAddr, OpalMemop_t typeOfRequest, int thread ) { - // Send request to sequencer - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->getSequencer(cpuNumber%RubyConfig::numberOfProcsPerChip()); - - // FIXME - some of these fields have bogus values sinced isReady() - // doesn't need them. However, it would be cleaner if all of these - // fields were exact. - - return (targetSequencer_ptr->isReady(CacheMsg(Address( physicalAddr ), - Address( physicalAddr ), - get_request_type(typeOfRequest), - Address(0), - AccessModeType_UserMode, // User/supervisor mode - 0, // Size in bytes of request - PrefetchBit_No, // Not a prefetch - 0, // Version number - Address(logicalAddr), // Virtual Address - thread, // SMT thread - 0, // TM specific - timestamp of memory request - false // TM specific - whether request is part of escape action - ) - )); -} - -// FIXME: duplicated code should be avoided -//************************************************************************** -void OpalInterface::makeRequest(int cpuNumber, la_t logicalAddr, pa_t physicalAddr, - int requestSize, OpalMemop_t typeOfRequest, - la_t virtualPC, int isPriv, int thread) { - // Issue the request to the sequencer. - // set access type (user/supervisor) - AccessModeType access_mode; - if (isPriv) { - access_mode = AccessModeType_SupervisorMode; - } else { - access_mode = AccessModeType_UserMode; - } - - // Send request to sequencer - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->getSequencer(cpuNumber%RubyConfig::numberOfProcsPerChip()); - - targetSequencer_ptr->makeRequest(CacheMsg(Address( physicalAddr ), - Address( physicalAddr ), - get_request_type(typeOfRequest), - Address(virtualPC), - access_mode, // User/supervisor mode - requestSize, // Size in bytes of request - PrefetchBit_No, // Not a prefetch - 0, // Version number - Address(logicalAddr), // Virtual Address - thread, // SMT thread - 0, // TM specific - timestamp of memory request - false // TM specific - whether request is part of escape action - ) - ); -} - - -//************************************************************************** -void OpalInterface::makePrefetch(int cpuNumber, la_t logicalAddr, pa_t physicalAddr, - int requestSize, OpalMemop_t typeOfRequest, - la_t virtualPC, int isPriv, int thread) { - DEBUG_MSG(SEQUENCER_COMP,MedPrio,"Making prefetch request"); - - // Issue the request to the sequencer. - // set access type (user/supervisor) - AccessModeType access_mode; - if (isPriv) { - access_mode = AccessModeType_SupervisorMode; - } else { - access_mode = AccessModeType_UserMode; - } - - // make the prefetch - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->getSequencer(cpuNumber%RubyConfig::numberOfProcsPerChip()); - targetSequencer_ptr->makeRequest(CacheMsg(Address( physicalAddr ), - Address( physicalAddr ), - get_request_type(typeOfRequest), - Address(virtualPC), - access_mode, - requestSize, - PrefetchBit_Yes, // True means this is a prefetch - 0, // Version number - Address(logicalAddr), // Virtual Address - thread, // SMT thread - 0, // TM specific - timestamp of memory request - false // TM specific - whether request is part of escape action - ) - ); - return; -} - -//************************************************************************** -int OpalInterface::staleDataRequest( int cpuNumber, pa_t physicalAddr, - int requestSize, int8 *buffer ) { - // Find sequencer - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->getSequencer(cpuNumber%RubyConfig::numberOfProcsPerChip()); - assert(targetSequencer_ptr != NULL); - - // query the cache for stale data values (if any) - bool hit = false; - //hit = targetSequencer_ptr->staleDataAccess( Address(physicalAddr), - // requestSize, buffer ); - - return hit; -} - -//************************************************************************** -void OpalInterface::notify( int status ) { - if (OpalInterface::inst == NULL) { - if (status == 1) { - // notify system that opal is now loaded - g_system_ptr->opalLoadNotify(); - } else { - return; - } - } - - // opal interface must be allocated now - ASSERT( OpalInterface::inst != NULL ); - if ( status == 0 ) { - - } else if ( status == 1 ) { - // install notification: query opal for its interface - OpalInterface::inst->queryOpalInterface(); - if ( OpalInterface::inst->m_opal_intf != NULL ) { - cout << "OpalInterface: installation successful." << endl; - // test: (*(OpalInterface::inst->m_opal_intf->hitCallback))( 0, 0xFFULL ); - } - } else if ( status == 2 ) { - // unload notification - // NOTE: this is not tested, as we can't unload ruby or opal right now. - OpalInterface::inst->removeOpalInterface(); - } -} - -// advance ruby time -//************************************************************************** -int OpalInterface::s_advance_counter = 0; - -void OpalInterface::advanceTime( void ) { - s_advance_counter++; - if (s_advance_counter == OPAL_RUBY_MULTIPLIER) { - Time time = g_eventQueue_ptr->getTime() + 1; - DEBUG_EXPR(NODE_COMP, HighPrio, time); - g_eventQueue_ptr->triggerEvents(time); - s_advance_counter = 0; - } -} - -// return ruby's time -//************************************************************************** -unsigned long long OpalInterface::getTime( void ) { - return (g_eventQueue_ptr->getTime()); -} - -// print's Ruby outstanding request table -void OpalInterface::printProgress(int cpuNumber){ - Sequencer* targetSequencer_ptr = g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->getSequencer(cpuNumber%RubyConfig::numberOfProcsPerChip()); - assert(targetSequencer_ptr != NULL); - - targetSequencer_ptr->printProgress(cout); -} - -// Non-method helper function -//************************************************************************** -static CacheRequestType get_request_type( OpalMemop_t opaltype ) { - CacheRequestType type; - - if (opaltype == OPAL_LOAD) { - type = CacheRequestType_LD; - } else if (opaltype == OPAL_STORE){ - type = CacheRequestType_ST; - } else if (opaltype == OPAL_IFETCH){ - type = CacheRequestType_IFETCH; - } else if (opaltype == OPAL_ATOMIC){ - type = CacheRequestType_ATOMIC; - } else { - ERROR_MSG("Error: Strange memory transaction type: not a LD or a ST"); - } - return type; -} - -//************************************************************************** -static OpalMemop_t get_opal_request_type( CacheRequestType type ) { - OpalMemop_t opal_type; - - if(type == CacheRequestType_LD){ - opal_type = OPAL_LOAD; - } - else if( type == CacheRequestType_ST){ - opal_type = OPAL_STORE; - } - else if( type == CacheRequestType_IFETCH){ - opal_type = OPAL_IFETCH; - } - else if( type == CacheRequestType_ATOMIC){ - opal_type = OPAL_ATOMIC; - } - else{ - ERROR_MSG("Error: Strange memory transaction type: not a LD or a ST"); - } - - //cout << "get_opal_request_type() CacheRequestType[ " << type << " ] opal_type[ " << opal_type << " ] " << endl; - return opal_type; -} - -//************************************************************************** -void OpalInterface::removeOpalInterface( void ) { - cout << "ruby: opal uninstalled. reinstalling timing model." << endl; - SIMICS_install_timing_model(); -} - -//************************************************************************** -bool OpalInterface::isOpalLoaded( void ) { - if (!g_SIMICS) { - return false; - } else { - mf_opal_api_t *opal_interface = SIMICS_get_opal_interface(); - if ( opal_interface == NULL ) { - return false; - } else { - return true; - } - } -} - -//************************************************************************** -void OpalInterface::queryOpalInterface( void ) { - m_opal_intf = SIMICS_get_opal_interface(); - if ( m_opal_intf == NULL ) { - WARN_MSG("error: OpalInterface: opal does not implement mf-opal-api interface.\n"); - } else { - // opal is loaded -- remove the timing_model interface - cout << "Ruby: ruby-opal link established. removing timing_model." << endl; - SIMICS_remove_timing_model(); - - if (m_opal_intf->notifyCallback != NULL) { - cout << "opalinterface: doing notify callback\n"; - (*m_opal_intf->notifyCallback)( 1 ); - } else { - // 2/27/2005, removed spurious error message (MRM) - // cout << "error: opalinterface: mf-opal-api has NULL notify callback.\n"; - } - } -} - -// install the opal interface to simics -//************************************************************************** -void OpalInterface::installInterface( mf_ruby_api_t *api ) { - // install ruby interface - api->isReady = &OpalInterface::isReady; - api->makeRequest = &OpalInterface::makeRequest; - api->makePrefetch = &OpalInterface::makePrefetch; - api->advanceTime = &OpalInterface::advanceTime; - api->getTime = &OpalInterface::getTime; - api->staleDataRequest = &OpalInterface::staleDataRequest; - api->notifyCallback = &OpalInterface::notify; - api->getNumberOutstanding = &OpalInterface::getNumberOutstanding; - api->getNumberOutstandingDemand = &OpalInterface::getNumberOutstandingDemand; - api->getNumberOutstandingPrefetch = &OpalInterface::getNumberOutstandingPrefetch; - api->printProgress = &OpalInterface::printProgress; -} diff --git a/src/mem/ruby/interfaces/OpalInterface.hh b/src/mem/ruby/interfaces/OpalInterface.hh deleted file mode 100644 index 4bc63d15a..000000000 --- a/src/mem/ruby/interfaces/OpalInterface.hh +++ /dev/null @@ -1,214 +0,0 @@ - -/* - * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * $Id$ - * - * Description: - * - */ - -#ifndef OpalInterface_H -#define OpalInterface_H - -/*------------------------------------------------------------------------*/ -/* Includes */ -/*------------------------------------------------------------------------*/ - -#include "Global.hh" -#include "Driver.hh" -#include "mf_api.hh" -#include "CacheRequestType.hh" - -/*------------------------------------------------------------------------*/ -/* Class declaration(s) */ -/*------------------------------------------------------------------------*/ - -class System; -class TransactionInterfaceManager; -class Sequencer; - -/** - * the processor model (opal) calls these OpalInterface APIs to access - * the memory hierarchy (ruby). - * @see pseq_t - * @author cmauer - * @version $Id$ - */ -class OpalInterface : public Driver { -public: - // Constructors - OpalInterface(System* sys_ptr); - - // Destructor - // ~OpalInterface(); - - integer_t getInstructionCount(int procID) const; - void hitCallback( NodeID proc, SubBlock& data, CacheRequestType type, int thread ); - void printStats(ostream& out) const; - void clearStats(); - void printConfig(ostream& out) const; - void print(ostream& out) const; - - integer_t readPhysicalMemory(int procID, physical_address_t address, - int len ); - - void writePhysicalMemory( int procID, physical_address_t address, - integer_t value, int len ); - uint64 getOpalTime(int procID) const; - - // for WATTCH power - void incrementL2Access(int procID) const; - void incrementPrefetcherAccess(int procID, int num_prefetches, int isinstr) const; - - // notifies Opal of an L2 miss - void notifyL2Miss(int procID, physical_address_t physicalAddr, OpalMemop_t type, int tagexists) const; - - void printDebug(); - - /// The static opalinterface instance - static OpalInterface *inst; - - /// static methods - static int getNumberOutstanding(int cpuNumber); - static int getNumberOutstandingDemand(int cpuNumber); - static int getNumberOutstandingPrefetch( int cpuNumber ); - - /* returns true if the sequencer is able to handle more requests. - This implements "back-pressure" by which the processor knows - not to issue more requests if the network or cache's limits are reached. - */ - static int isReady( int cpuNumber, la_t logicalAddr, pa_t physicalAddr, OpalMemop_t typeOfRequest, int thread ); - - /* - makeRequest performs the coherence transactions necessary to get the - physical address in the cache with the correct permissions. More than - one request can be outstanding to ruby, but only one per block address. - The size of the cache line is defined to Intf_CacheLineSize. - When a request is finished (e.g. the cache contains physical address), - ruby calls completedRequest(). No request can be bigger than - Opal_CacheLineSize. It is illegal to request non-aligned memory - locations. A request of size 2 must be at an even byte, a size 4 must - be at a byte address half-word aligned, etc. Requests also can't cross a - cache-line boundaries. - */ - static void makeRequest(int cpuNumber, la_t logicalAddr, pa_t physicalAddr, - int requestSize, OpalMemop_t typeOfRequest, - la_t virtualPC, int isPriv, int thread); - - /* prefetch a given block... - */ - static void makePrefetch(int cpuNumber, la_t logicalAddr, pa_t physicalAddr, - int requestSize, OpalMemop_t typeOfRequest, - la_t virtualPC, int isPriv, int thread); - - /* - * request data from the cache, even if it's state is "Invalid". - */ - static int staleDataRequest( int cpuNumber, pa_t physicalAddr, - int requestSize, int8 *buffer ); - - /* notify ruby of opal's status - */ - static void notify( int status ); - - /* - * advance ruby one cycle - */ - static void advanceTime( void ); - - /* - * return ruby's cycle count. - */ - static unsigned long long getTime( void ); - - /* prints Ruby's outstanding request table */ - static void printProgress(int cpuNumber); - - /* - * initialize / install the inter-module interface - */ - static void installInterface( mf_ruby_api_t *api ); - - /* - * Test if opal is loaded or not - */ - static bool isOpalLoaded( void ); - - /* - * query opal for its api - */ - void queryOpalInterface( void ); - - /* - * remove the opal interface (opal is unloaded). - */ - void removeOpalInterface( void ); - - /* - * set the opal interface (used if stand-alone testing) - */ - void setOpalInterface( mf_opal_api_t *opal_intf ) { - m_opal_intf = opal_intf; - } - - /** - * Signal an abort - */ - //void abortCallback(NodeID proc); - -private: - // Private Methods - - // Private copy constructor and assignment operator - OpalInterface(const OpalInterface& obj); - OpalInterface& operator=(const OpalInterface& obj); - - // Data Members (m_ prefix) - mf_opal_api_t *m_opal_intf; - Time m_simicsStartTime; - - static int s_advance_counter; -}; - -// Output operator declaration -ostream& operator<<(ostream& out, const OpalInterface& obj); - -// ******************* Definitions ******************* - -// Output operator definition -extern inline -ostream& operator<<(ostream& out, const OpalInterface& obj) -{ -// obj.print(out); - out << flush; - return out; -} - -#endif // OpalInterface_H |