ruby: remove unnecessary code.
1) Removing files from the ruby build left some unresovled symbols. Those have been fixed. 2) Most of the dependencies on Simics data types and the simics interface files have been removed. 3) Almost all mention of opal is gone. 4) Huge chunks of LogTM are now gone. 5) Handling 1-4 left ~hundreds of unresolved references, which were fixed, yielding a snowball effect (and the massive size of this delta).
This commit is contained in:
parent
6ceaffd724
commit
d8c592a05d
42 changed files with 442 additions and 9365 deletions
|
@ -59,8 +59,6 @@ using namespace std;
|
||||||
// #endif
|
// #endif
|
||||||
// };
|
// };
|
||||||
|
|
||||||
#include "FakeSimicsDataTypes.hh"
|
|
||||||
|
|
||||||
#include "confio.hh"
|
#include "confio.hh"
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -70,8 +70,6 @@ using namespace std;
|
||||||
// #endif
|
// #endif
|
||||||
// };
|
// };
|
||||||
|
|
||||||
#include "FakeSimicsDataTypes.hh"
|
|
||||||
|
|
||||||
#include "Global.hh"
|
#include "Global.hh"
|
||||||
|
|
||||||
#include "confio.hh"
|
#include "confio.hh"
|
||||||
|
@ -124,8 +122,7 @@ static set_error_t initvar_set_attr( void *ptr, void *obj,
|
||||||
initvar_t::initvar_t( const char *name, const char *relativeIncludePath,
|
initvar_t::initvar_t( const char *name, const char *relativeIncludePath,
|
||||||
const char *initializingString,
|
const char *initializingString,
|
||||||
void (*allocate_fn)(void),
|
void (*allocate_fn)(void),
|
||||||
void (*my_generate_fn)(void),
|
void (*my_generate_fn)(void) )
|
||||||
get_attr_t my_get_attr, set_attr_t my_set_attr )
|
|
||||||
{
|
{
|
||||||
m_is_init = false;
|
m_is_init = false;
|
||||||
m_name = (char *) malloc( sizeof(char)*(strlen( name ) + 2) );
|
m_name = (char *) malloc( sizeof(char)*(strlen( name ) + 2) );
|
||||||
|
@ -135,8 +132,6 @@ initvar_t::initvar_t( const char *name, const char *relativeIncludePath,
|
||||||
strcpy( m_rel_include_path, relativeIncludePath );
|
strcpy( m_rel_include_path, relativeIncludePath );
|
||||||
m_allocate_f = allocate_fn;
|
m_allocate_f = allocate_fn;
|
||||||
m_generate_values_f = my_generate_fn;
|
m_generate_values_f = my_generate_fn;
|
||||||
m_my_get_attr = my_get_attr;
|
|
||||||
m_my_set_attr = my_set_attr;
|
|
||||||
|
|
||||||
initvar_t::m_inst = this;
|
initvar_t::m_inst = this;
|
||||||
init_config_reader( initializingString );
|
init_config_reader( initializingString );
|
||||||
|
@ -247,7 +242,7 @@ void initvar_t::checkInitialization( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
attr_value_t initvar_t::dispatch_get( void *id, void *obj,
|
int initvar_t::dispatch_get( void *id, void *obj,
|
||||||
attr_value_t *idx )
|
attr_value_t *idx )
|
||||||
{
|
{
|
||||||
const char *command = (const char *) id;
|
const char *command = (const char *) id;
|
||||||
|
@ -256,13 +251,11 @@ attr_value_t initvar_t::dispatch_get( void *id, void *obj,
|
||||||
DEBUG_OUT(" : you must initialize %s with a configuration file first.\n", m_name);
|
DEBUG_OUT(" : you must initialize %s with a configuration file first.\n", m_name);
|
||||||
DEBUG_OUT(" : use the command \'%s0.init\'\n", m_name);
|
DEBUG_OUT(" : use the command \'%s0.init\'\n", m_name);
|
||||||
|
|
||||||
attr_value_t ret;
|
return 0;
|
||||||
ret.kind = Sim_Val_Invalid;
|
|
||||||
ret.u.integer = 0;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((*m_my_get_attr)(id, obj, idx));
|
std::cerr << __FILE__ << "(" << __LINE__ << "): Not implmented." << std::endl;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -331,7 +324,9 @@ set_error_t initvar_t::dispatch_set( void *id, void *obj,
|
||||||
return Sim_Set_Illegal_Value;
|
return Sim_Set_Illegal_Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*m_my_set_attr)( id, obj, val, idx );
|
|
||||||
|
std::cerr << __FILE__ << "(" << __LINE__ << "): Not implmented." << std::endl;
|
||||||
|
return Sim_Set_Illegal_Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
@ -588,22 +583,3 @@ const char *initvar_t::get_config_name( void )
|
||||||
return m_config_filename;
|
return m_config_filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Global functions */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
attr_value_t initvar_dispatch_get( void *id, void *obj,
|
|
||||||
attr_value_t *idx )
|
|
||||||
{
|
|
||||||
initvar_t *init_obj = initvar_t::m_inst;
|
|
||||||
return (init_obj->dispatch_get( id, obj, idx ));
|
|
||||||
}
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
set_error_t initvar_dispatch_set( void *id, void *obj,
|
|
||||||
attr_value_t *val, attr_value_t *idx )
|
|
||||||
{
|
|
||||||
initvar_t *init_obj = initvar_t::m_inst;
|
|
||||||
return (init_obj->dispatch_set( id, obj, val, idx ));
|
|
||||||
}
|
|
||||||
|
|
|
@ -70,8 +70,8 @@ public:
|
||||||
initvar_t( const char *name, const char *relativeIncludePath,
|
initvar_t( const char *name, const char *relativeIncludePath,
|
||||||
const char *initializingString,
|
const char *initializingString,
|
||||||
void (*allocate_fn)(void),
|
void (*allocate_fn)(void),
|
||||||
void (*my_generate_fn)(void),
|
void (*my_generate_fn)(void)
|
||||||
get_attr_t my_get_attr, set_attr_t my_set_attr );
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor: frees object.
|
* Destructor: frees object.
|
||||||
|
@ -96,8 +96,8 @@ public:
|
||||||
const char *get_config_name( void );
|
const char *get_config_name( void );
|
||||||
|
|
||||||
/// calls through to the get_attr function, if object is initialized
|
/// calls through to the get_attr function, if object is initialized
|
||||||
attr_value_t dispatch_get( void *id, void *obj,
|
int dispatch_get( void *id, void *obj,
|
||||||
attr_value_t *idx );
|
attr_value_t *idx );
|
||||||
|
|
||||||
/** adds initialization attributes, calls through to the set_attr function,
|
/** adds initialization attributes, calls through to the set_attr function,
|
||||||
* if object is initialized.
|
* if object is initialized.
|
||||||
|
@ -144,10 +144,6 @@ protected:
|
||||||
/// a pointer to the generate values function
|
/// a pointer to the generate values function
|
||||||
void (*m_generate_values_f)(void);
|
void (*m_generate_values_f)(void);
|
||||||
|
|
||||||
/// a pointer to the session get function
|
|
||||||
get_attr_t m_my_get_attr;
|
|
||||||
/// a pointer to the session set function
|
|
||||||
set_attr_t m_my_set_attr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 1999-2005 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file has been modified by Kevin Moore and Dan Nussbaum of the
|
|
||||||
Scalable Systems Research Group at Sun Microsystems Laboratories
|
|
||||||
(http://research.sun.com/scalable/) to support the Adaptive
|
|
||||||
Transactional Memory Test Platform (ATMTP).
|
|
||||||
|
|
||||||
Please send email to atmtp-interest@sun.com with feedback, questions, or
|
|
||||||
to request future announcements about ATMTP.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
File modification date: 2008-02-23
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
external_type(PartialAddressFilter, desc="Bloom filter for tracking transaction locks."){
|
|
||||||
bool isRead(Address);
|
|
||||||
bool isWrite(Address);
|
|
||||||
|
|
||||||
void addEntry(Address, bool);
|
|
||||||
void clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
external_type(TransactionInterfaceManager) {
|
|
||||||
bool shouldNackLoad(Address, uint64, MachineID);
|
|
||||||
bool shouldNackStore(Address, uint64, MachineID);
|
|
||||||
bool checkReadWriteSignatures(Address);
|
|
||||||
bool checkWriteSignatures(Address);
|
|
||||||
|
|
||||||
void notifySendNack(Address, uint64, MachineID);
|
|
||||||
void notifyReceiveNack(int, Address, uint64, uint64, MachineID);
|
|
||||||
void notifyReceiveNackFinal(int, Address);
|
|
||||||
|
|
||||||
uint64 getTimestamp(int);
|
|
||||||
uint64 getOldestTimestamp();
|
|
||||||
|
|
||||||
bool existGlobalLoadConflict(int, Address);
|
|
||||||
bool existGlobalStoreConflict(int, Address);
|
|
||||||
|
|
||||||
void profileTransactionMiss(int, bool);
|
|
||||||
|
|
||||||
void xactReplacement(Address);
|
|
||||||
|
|
||||||
/* DEPRECATED */
|
|
||||||
bool existLoadConflict(Address);
|
|
||||||
bool existStoreConflict(Address);
|
|
||||||
bool isInReadFilterSummary(Address);
|
|
||||||
bool isInWriteFilterSummary(Address);
|
|
||||||
bool isTokenOwner(int);
|
|
||||||
void setAbortFlag(int, Address);
|
|
||||||
void setEnemyProcessor(int, MachineID);
|
|
||||||
bool isRemoteOlder(uint64);
|
|
||||||
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,166 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1999-2005 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: MOESI_CMP_token-dir.sm 1.6 05/01/19 15:48:35-06:00 mikem@royal16.cs.wisc.edu $
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
machine(Directory, "Token protocol") {
|
|
||||||
|
|
||||||
MessageBuffer requestToDir, network="From", virtual_network="2", ordered="false";
|
|
||||||
MessageBuffer responseToDir, network="From", virtual_network="3", ordered="false";
|
|
||||||
MessageBuffer responseFromDir, network="To", virtual_network="3", ordered="false";
|
|
||||||
|
|
||||||
// STATES
|
|
||||||
enumeration(State, desc="Directory states", default="Directory_State_I") {
|
|
||||||
// Base states
|
|
||||||
I, desc="Owner";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Events
|
|
||||||
enumeration(Event, desc="Directory events") {
|
|
||||||
Fetch, desc="A GETX arrives";
|
|
||||||
Data, desc="A GETS arrives";
|
|
||||||
}
|
|
||||||
|
|
||||||
// TYPES
|
|
||||||
|
|
||||||
// DirectoryEntry
|
|
||||||
structure(Entry, desc="...") {
|
|
||||||
DataBlock DataBlk, desc="data for the block";
|
|
||||||
}
|
|
||||||
|
|
||||||
external_type(DirectoryMemory) {
|
|
||||||
Entry lookup(Address);
|
|
||||||
bool isPresent(Address);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ** OBJECTS **
|
|
||||||
|
|
||||||
DirectoryMemory directory, constructor_hack="i";
|
|
||||||
|
|
||||||
State getState(Address addr) {
|
|
||||||
return State:I;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setState(Address addr, State state) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// ** OUT_PORTS **
|
|
||||||
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
|
||||||
|
|
||||||
// ** IN_PORTS **
|
|
||||||
|
|
||||||
in_port(requestNetwork_in, RequestMsg, requestToDir) {
|
|
||||||
if (requestNetwork_in.isReady()) {
|
|
||||||
peek(requestNetwork_in, RequestMsg) {
|
|
||||||
assert(in_msg.Destination.isElement(machineID));
|
|
||||||
if (in_msg.Type == CoherenceRequestType:GETS) {
|
|
||||||
trigger(Event:Fetch, in_msg.Address);
|
|
||||||
} else if (in_msg.Type == CoherenceRequestType:GETX) {
|
|
||||||
trigger(Event:Fetch, in_msg.Address);
|
|
||||||
} else {
|
|
||||||
error("Invalid message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
in_port(responseNetwork_in, ResponseMsg, responseToDir) {
|
|
||||||
if (responseNetwork_in.isReady()) {
|
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
|
||||||
assert(in_msg.Destination.isElement(machineID));
|
|
||||||
if (in_msg.Type == CoherenceResponseType:MEMORY_DATA) {
|
|
||||||
trigger(Event:Data, in_msg.Address);
|
|
||||||
} else {
|
|
||||||
DEBUG_EXPR(in_msg.Type);
|
|
||||||
error("Invalid message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
action(a_sendAck, "a", desc="Send ack to L2") {
|
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
|
||||||
enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") {
|
|
||||||
out_msg.Address := address;
|
|
||||||
out_msg.Type := CoherenceResponseType:MEMORY_ACK;
|
|
||||||
out_msg.Sender := machineID;
|
|
||||||
out_msg.Destination.add(in_msg.Sender);
|
|
||||||
out_msg.MessageSize := MessageSizeType:Response_Control;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action(d_sendData, "d", desc="Send data to requestor") {
|
|
||||||
peek(requestNetwork_in, RequestMsg) {
|
|
||||||
enqueue(responseNetwork_out, ResponseMsg, latency="MEMORY_LATENCY") {
|
|
||||||
out_msg.Address := address;
|
|
||||||
out_msg.Type := CoherenceResponseType:MEMORY_DATA;
|
|
||||||
out_msg.Sender := machineID;
|
|
||||||
out_msg.Destination.add(in_msg.Requestor);
|
|
||||||
out_msg.DataBlk := directory[in_msg.Address].DataBlk;
|
|
||||||
out_msg.Dirty := false;
|
|
||||||
out_msg.MessageSize := MessageSizeType:Response_Data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action(j_popIncomingRequestQueue, "j", desc="Pop incoming request queue") {
|
|
||||||
requestNetwork_in.dequeue();
|
|
||||||
}
|
|
||||||
|
|
||||||
action(k_popIncomingResponseQueue, "k", desc="Pop incoming request queue") {
|
|
||||||
responseNetwork_in.dequeue();
|
|
||||||
}
|
|
||||||
|
|
||||||
action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") {
|
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
|
||||||
directory[in_msg.Address].DataBlk := in_msg.DataBlk;
|
|
||||||
DEBUG_EXPR(in_msg.Address);
|
|
||||||
DEBUG_EXPR(in_msg.DataBlk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TRANSITIONS
|
|
||||||
|
|
||||||
transition(I, Fetch) {
|
|
||||||
d_sendData;
|
|
||||||
j_popIncomingRequestQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
transition(I, Data) {
|
|
||||||
m_writeDataToMemory;
|
|
||||||
a_sendAck;
|
|
||||||
k_popIncomingResponseQueue;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,153 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1999-2005 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: MSI_MOSI_CMP_directory-msg.sm 1.5 05/01/19 15:48:37-06:00 mikem@royal16.cs.wisc.edu $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// CoherenceRequestType
|
|
||||||
enumeration(CoherenceRequestType, desc="...") {
|
|
||||||
GETX, desc="Get eXclusive";
|
|
||||||
GETX_ESCAPE, desc="Get eXclusive, while in escape action";
|
|
||||||
UPGRADE, desc="UPGRADE to exclusive";
|
|
||||||
GETS, desc="Get Shared";
|
|
||||||
GETS_ESCAPE, desc="Get Shared, while in escape action";
|
|
||||||
GET_INSTR, desc="Get Instruction";
|
|
||||||
GET_INSTR_ESCAPE, desc="Get Instruction, while in escape action";
|
|
||||||
INV, desc="INValidate, could be NACKed";
|
|
||||||
INV_ESCAPE, desc="INValidate, cannot be NACKed";
|
|
||||||
PUTX, desc="replacement message, for writeback to lower caches";
|
|
||||||
PUTS, desc="clean replacement message, for writeback to lower caches";
|
|
||||||
REPLACE, desc="replacement message, from lowest cache";
|
|
||||||
CHECK_WRITE_FILTER, desc="check write filter message";
|
|
||||||
CHECK_READ_WRITE_FILTER, desc="check both read and write filters message";
|
|
||||||
}
|
|
||||||
|
|
||||||
// CoherenceResponseType
|
|
||||||
enumeration(CoherenceResponseType, desc="...") {
|
|
||||||
MEMORY_ACK, desc="Ack from memory controller";
|
|
||||||
DATA, desc="Data";
|
|
||||||
DATA_EXCLUSIVE, desc="Data";
|
|
||||||
L2_DATA, desc="data from L2, in shared mode";
|
|
||||||
L2_DATA_EXCLUSIVE, desc="data from L2, in exclusive mode";
|
|
||||||
MEMORY_DATA, desc="Data";
|
|
||||||
ACK, desc="Generic invalidate ack";
|
|
||||||
NACK, desc="NACK used to maintain transactional isolation";
|
|
||||||
WB_ACK, desc="writeback ack";
|
|
||||||
UNBLOCK, desc="unblock";
|
|
||||||
EXCLUSIVE_UNBLOCK, desc="exclusive unblock";
|
|
||||||
UNBLOCK_CANCEL, desc="unblock when trans. request fails";
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestMsg
|
|
||||||
structure(RequestMsg, desc="...", interface="NetworkMessage") {
|
|
||||||
Address Address, desc="Line address for this request";
|
|
||||||
Address PhysicalAddress, desc="Physical address for this request";
|
|
||||||
CoherenceRequestType Type, desc="Type of request (GetS, GetX, PutX, etc)";
|
|
||||||
AccessModeType AccessMode, desc="user/supervisor access type";
|
|
||||||
MachineID Requestor , desc="What component request";
|
|
||||||
NetDest Destination, desc="What components receive the request, includes MachineType and num";
|
|
||||||
MessageSizeType MessageSize, desc="size category of the message";
|
|
||||||
DataBlock DataBlk, desc="Data for the cache line (if PUTX)";
|
|
||||||
bool Dirty, default="false", desc="Dirty bit";
|
|
||||||
PrefetchBit Prefetch, desc="Is this a prefetch request";
|
|
||||||
uint64 Timestamp, desc="TLR-like Timestamp";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResponseMsg
|
|
||||||
structure(ResponseMsg, desc="...", interface="NetworkMessage") {
|
|
||||||
Address Address, desc="Line address for this request";
|
|
||||||
Address PhysicalAddress, desc="Physical address for this request";
|
|
||||||
CoherenceResponseType Type, desc="Type of response (Ack, Data, etc)";
|
|
||||||
MachineID Sender, desc="What component sent the data";
|
|
||||||
NetDest Destination, desc="Node to whom the data is sent";
|
|
||||||
DataBlock DataBlk, desc="Data for the cache line";
|
|
||||||
bool Dirty, default="false", desc="Dirty bit";
|
|
||||||
int AckCount, default="0", desc="number of acks in this message";
|
|
||||||
MessageSizeType MessageSize, desc="size category of the message";
|
|
||||||
uint64 Timestamp, desc="TLR-like Timestamp";
|
|
||||||
NetDest Nackers, desc="The nodes which sent NACKs to requestor";
|
|
||||||
bool Transactional, desc="Whether this address was transactional";
|
|
||||||
bool RemoveLastOwnerFromDir, desc="To solve some races with PUTX/GETS";
|
|
||||||
MachineID LastOwnerID, desc="What component sent the data";
|
|
||||||
}
|
|
||||||
|
|
||||||
// TriggerType
|
|
||||||
enumeration(TriggerType, desc="...") {
|
|
||||||
ALL_ACKS, desc="When all acks/nacks have been received";
|
|
||||||
}
|
|
||||||
|
|
||||||
// TriggerMsg
|
|
||||||
structure(TriggerMsg, desc="...", interface="Message") {
|
|
||||||
Address Address, desc="Line address for this request";
|
|
||||||
Address PhysicalAddress, desc="Physical address for this request";
|
|
||||||
TriggerType Type, desc="Type of trigger";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
GETX, desc="Get eXclusive";
|
|
||||||
UPGRADE, desc="UPGRADE to exclusive";
|
|
||||||
GETS, desc="Get Shared";
|
|
||||||
GET_INSTR, desc="Get Instruction";
|
|
||||||
INV, desc="INValidate";
|
|
||||||
PUTX, desc="replacement message, for writeback to lower caches";
|
|
||||||
REPLACE, desc="replacement message, from lowest cache";
|
|
||||||
CHECK_WRITE_FILTER, desc="check write filter message";
|
|
||||||
CHECK_READ_WRITE_FILTER, desc="check both read and write filters message";
|
|
||||||
*/
|
|
||||||
|
|
||||||
GenericRequestType convertToGenericType(CoherenceRequestType type) {
|
|
||||||
if(type == CoherenceRequestType:PUTX) {
|
|
||||||
return GenericRequestType:PUTX;
|
|
||||||
} else if(type == CoherenceRequestType:GETS) {
|
|
||||||
return GenericRequestType:GETS;
|
|
||||||
} else if(type == CoherenceRequestType:GETS_ESCAPE) {
|
|
||||||
return GenericRequestType:GETS;
|
|
||||||
} else if(type == CoherenceRequestType:GET_INSTR) {
|
|
||||||
return GenericRequestType:GET_INSTR;
|
|
||||||
} else if(type == CoherenceRequestType:GET_INSTR_ESCAPE) {
|
|
||||||
return GenericRequestType:GET_INSTR;
|
|
||||||
} else if(type == CoherenceRequestType:GETX) {
|
|
||||||
return GenericRequestType:GETX;
|
|
||||||
} else if(type == CoherenceRequestType:GETX_ESCAPE) {
|
|
||||||
return GenericRequestType:GETX;
|
|
||||||
} else if(type == CoherenceRequestType:UPGRADE) {
|
|
||||||
return GenericRequestType:UPGRADE;
|
|
||||||
} else if(type == CoherenceRequestType:INV) {
|
|
||||||
return GenericRequestType:INV;
|
|
||||||
} else if( type == CoherenceRequestType:REPLACE) {
|
|
||||||
return GenericRequestType:REPLACEMENT;
|
|
||||||
} else {
|
|
||||||
DEBUG_EXPR(type);
|
|
||||||
error("invalid CoherenceRequestType");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
../protocols/LogTM.sm
|
|
||||||
../protocols/MESI_CMP_filter_directory-msg.sm
|
|
||||||
../protocols/MESI_CMP_filter_directory-L2cache.sm
|
|
||||||
../protocols/MESI_CMP_filter_directory-L1cache.sm
|
|
||||||
../protocols/MESI_CMP_filter_directory-mem.sm
|
|
||||||
../protocols/standard_CMP-protocol.sm
|
|
||||||
|
|
|
@ -1,250 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 1999-2005 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: MOESI_CMP_token-dir.sm 1.6 05/01/19 15:48:35-06:00 mikem@royal16.cs.wisc.edu $
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This file is copied from Yasuko Watanabe's prefetch / memory protocol
|
|
||||||
// Copied here by aep 12/14/07
|
|
||||||
|
|
||||||
|
|
||||||
machine(Directory, "MESI_CMP_filter_directory protocol") {
|
|
||||||
|
|
||||||
MessageBuffer requestToDir, network="From", virtual_network="2", ordered="false";
|
|
||||||
MessageBuffer responseToDir, network="From", virtual_network="3", ordered="false";
|
|
||||||
MessageBuffer responseFromDir, network="To", virtual_network="3", ordered="false";
|
|
||||||
|
|
||||||
// STATES
|
|
||||||
enumeration(State, desc="Directory states", default="Directory_State_I") {
|
|
||||||
// Base states
|
|
||||||
I, desc="Owner";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Events
|
|
||||||
enumeration(Event, desc="Directory events") {
|
|
||||||
Fetch, desc="A memory fetch arrives";
|
|
||||||
Data, desc="writeback data arrives";
|
|
||||||
Memory_Data, desc="Fetched data from memory arrives";
|
|
||||||
Memory_Ack, desc="Writeback Ack from memory arrives";
|
|
||||||
}
|
|
||||||
|
|
||||||
// TYPES
|
|
||||||
|
|
||||||
// DirectoryEntry
|
|
||||||
structure(Entry, desc="...") {
|
|
||||||
DataBlock DataBlk, desc="data for the block";
|
|
||||||
}
|
|
||||||
|
|
||||||
external_type(DirectoryMemory) {
|
|
||||||
Entry lookup(Address);
|
|
||||||
bool isPresent(Address);
|
|
||||||
}
|
|
||||||
|
|
||||||
// to simulate detailed DRAM
|
|
||||||
external_type(MemoryControl, inport="yes", outport="yes") {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ** OBJECTS **
|
|
||||||
|
|
||||||
DirectoryMemory directory, constructor_hack="i";
|
|
||||||
MemoryControl memBuffer, constructor_hack="i";
|
|
||||||
|
|
||||||
State getState(Address addr) {
|
|
||||||
return State:I;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setState(Address addr, State state) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isGETRequest(CoherenceRequestType type) {
|
|
||||||
return (type == CoherenceRequestType:GETS) ||
|
|
||||||
(type == CoherenceRequestType:GET_INSTR) ||
|
|
||||||
(type == CoherenceRequestType:GETX);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ** OUT_PORTS **
|
|
||||||
out_port(responseNetwork_out, ResponseMsg, responseFromDir);
|
|
||||||
out_port(memQueue_out, MemoryMsg, memBuffer);
|
|
||||||
|
|
||||||
// ** IN_PORTS **
|
|
||||||
|
|
||||||
in_port(requestNetwork_in, RequestMsg, requestToDir) {
|
|
||||||
if (requestNetwork_in.isReady()) {
|
|
||||||
peek(requestNetwork_in, RequestMsg) {
|
|
||||||
assert(in_msg.Destination.isElement(machineID));
|
|
||||||
if (isGETRequest(in_msg.Type)) {
|
|
||||||
trigger(Event:Fetch, in_msg.Address);
|
|
||||||
} else {
|
|
||||||
DEBUG_EXPR(in_msg);
|
|
||||||
error("Invalid message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
in_port(responseNetwork_in, ResponseMsg, responseToDir) {
|
|
||||||
if (responseNetwork_in.isReady()) {
|
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
|
||||||
assert(in_msg.Destination.isElement(machineID));
|
|
||||||
if (in_msg.Type == CoherenceResponseType:MEMORY_DATA) {
|
|
||||||
trigger(Event:Data, in_msg.Address);
|
|
||||||
} else {
|
|
||||||
DEBUG_EXPR(in_msg.Type);
|
|
||||||
error("Invalid message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// off-chip memory request/response is done
|
|
||||||
in_port(memQueue_in, MemoryMsg, memBuffer) {
|
|
||||||
if (memQueue_in.isReady()) {
|
|
||||||
peek(memQueue_in, MemoryMsg) {
|
|
||||||
if (in_msg.Type == MemoryRequestType:MEMORY_READ) {
|
|
||||||
trigger(Event:Memory_Data, in_msg.Address);
|
|
||||||
} else if (in_msg.Type == MemoryRequestType:MEMORY_WB) {
|
|
||||||
trigger(Event:Memory_Ack, in_msg.Address);
|
|
||||||
} else {
|
|
||||||
DEBUG_EXPR(in_msg.Type);
|
|
||||||
error("Invalid message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Actions
|
|
||||||
action(a_sendAck, "a", desc="Send ack to L2") {
|
|
||||||
peek(memQueue_in, MemoryMsg) {
|
|
||||||
enqueue(responseNetwork_out, ResponseMsg, latency="1") {
|
|
||||||
out_msg.Address := address;
|
|
||||||
out_msg.Type := CoherenceResponseType:MEMORY_ACK;
|
|
||||||
out_msg.Sender := machineID;
|
|
||||||
out_msg.Destination.add(in_msg.OriginalRequestorMachId);
|
|
||||||
out_msg.MessageSize := MessageSizeType:Response_Control;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action(d_sendData, "d", desc="Send data to requestor") {
|
|
||||||
peek(memQueue_in, MemoryMsg) {
|
|
||||||
enqueue(responseNetwork_out, ResponseMsg, latency="1") {
|
|
||||||
out_msg.Address := address;
|
|
||||||
out_msg.Type := CoherenceResponseType:MEMORY_DATA;
|
|
||||||
out_msg.Sender := machineID;
|
|
||||||
out_msg.Destination.add(in_msg.OriginalRequestorMachId);
|
|
||||||
out_msg.DataBlk := in_msg.DataBlk;
|
|
||||||
out_msg.Dirty := false;
|
|
||||||
out_msg.MessageSize := MessageSizeType:Response_Data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action(j_popIncomingRequestQueue, "j", desc="Pop incoming request queue") {
|
|
||||||
requestNetwork_in.dequeue();
|
|
||||||
}
|
|
||||||
|
|
||||||
action(k_popIncomingResponseQueue, "k", desc="Pop incoming request queue") {
|
|
||||||
responseNetwork_in.dequeue();
|
|
||||||
}
|
|
||||||
|
|
||||||
action(l_popMemQueue, "q", desc="Pop off-chip request queue") {
|
|
||||||
memQueue_in.dequeue();
|
|
||||||
}
|
|
||||||
|
|
||||||
action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch request") {
|
|
||||||
peek(requestNetwork_in, RequestMsg) {
|
|
||||||
enqueue(memQueue_out, MemoryMsg, latency="1") {
|
|
||||||
out_msg.Address := address;
|
|
||||||
out_msg.Type := MemoryRequestType:MEMORY_READ;
|
|
||||||
out_msg.Sender := machineID;
|
|
||||||
out_msg.OriginalRequestorMachId := in_msg.Requestor;
|
|
||||||
out_msg.MessageSize := in_msg.MessageSize;
|
|
||||||
out_msg.Prefetch := in_msg.Prefetch;
|
|
||||||
out_msg.DataBlk := directory[in_msg.Address].DataBlk;
|
|
||||||
|
|
||||||
DEBUG_EXPR(out_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action(qw_queueMemoryWBRequest, "qw", desc="Queue off-chip writeback request") {
|
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
|
||||||
enqueue(memQueue_out, MemoryMsg, latency="1") {
|
|
||||||
out_msg.Address := address;
|
|
||||||
out_msg.Type := MemoryRequestType:MEMORY_WB;
|
|
||||||
out_msg.Sender := machineID;
|
|
||||||
out_msg.OriginalRequestorMachId := in_msg.Sender;
|
|
||||||
out_msg.DataBlk := in_msg.DataBlk;
|
|
||||||
out_msg.MessageSize := in_msg.MessageSize;
|
|
||||||
//out_msg.Prefetch := in_msg.Prefetch;
|
|
||||||
|
|
||||||
DEBUG_EXPR(out_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") {
|
|
||||||
peek(responseNetwork_in, ResponseMsg) {
|
|
||||||
directory[in_msg.Address].DataBlk := in_msg.DataBlk;
|
|
||||||
DEBUG_EXPR(in_msg.Address);
|
|
||||||
DEBUG_EXPR(in_msg.DataBlk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TRANSITIONS
|
|
||||||
|
|
||||||
transition(I, Fetch) {
|
|
||||||
//d_sendData;
|
|
||||||
qf_queueMemoryFetchRequest;
|
|
||||||
j_popIncomingRequestQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
transition(I, Data) {
|
|
||||||
m_writeDataToMemory;
|
|
||||||
//a_sendAck;
|
|
||||||
qw_queueMemoryWBRequest;
|
|
||||||
k_popIncomingResponseQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
transition(I, Memory_Data) {
|
|
||||||
d_sendData;
|
|
||||||
l_popMemQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
transition(I, Memory_Ack) {
|
|
||||||
a_sendAck;
|
|
||||||
l_popMemQueue;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
../protocols/LogTM.sm
|
|
||||||
../protocols/MESI_CMP_filter_directory-msg.sm
|
|
||||||
../protocols/MESI_CMP_filter_directory-L2cache.sm
|
|
||||||
../protocols/MESI_CMP_filter_directory-L1cache.sm
|
|
||||||
../protocols/MESI_CMP_filter_directory_m-mem.sm
|
|
||||||
../protocols/standard_CMP-protocol.sm
|
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "RubyConfig.hh"
|
#include "RubyConfig.hh"
|
||||||
#include "protocol_name.hh"
|
#include "protocol_name.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "interface.hh"
|
|
||||||
#include "Protocol.hh"
|
#include "Protocol.hh"
|
||||||
|
|
||||||
#define CHECK_POWER_OF_2(N) { if (!is_power_of_2(N)) { ERROR_MSG(#N " must be a power of 2."); }}
|
#define CHECK_POWER_OF_2(N) { if (!is_power_of_2(N)) { ERROR_MSG(#N " must be a power of 2."); }}
|
||||||
|
@ -179,7 +178,6 @@ void RubyConfig::printConfiguration(ostream& out) {
|
||||||
out << "------------------" << endl;
|
out << "------------------" << endl;
|
||||||
|
|
||||||
out << "protocol: " << CURRENT_PROTOCOL << endl;
|
out << "protocol: " << CURRENT_PROTOCOL << endl;
|
||||||
SIMICS_print_version(out);
|
|
||||||
out << "compiled_at: " << __TIME__ << ", " << __DATE__ << endl;
|
out << "compiled_at: " << __TIME__ << ", " << __DATE__ << endl;
|
||||||
out << "RUBY_DEBUG: " << bool_to_string(RUBY_DEBUG) << endl;
|
out << "RUBY_DEBUG: " << bool_to_string(RUBY_DEBUG) << endl;
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ PARAM_BOOL( REMOVE_SINGLE_CYCLE_DCACHE_FAST_PATH );
|
||||||
// CACHE & MEMORY PARAMETERS
|
// CACHE & MEMORY PARAMETERS
|
||||||
// *********************************************
|
// *********************************************
|
||||||
|
|
||||||
PARAM_BOOL( g_SIMICS );
|
PARAM_BOOL( g_SIMULATING );
|
||||||
|
|
||||||
PARAM( L1_CACHE_ASSOC );
|
PARAM( L1_CACHE_ASSOC );
|
||||||
PARAM( L1_CACHE_NUM_SETS_BITS );
|
PARAM( L1_CACHE_NUM_SETS_BITS );
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
g_RANDOM_SEED: 1
|
g_RANDOM_SEED: 1
|
||||||
g_SIMICS: true
|
g_SIMULATING: true
|
||||||
|
|
||||||
g_DEADLOCK_THRESHOLD: 500000
|
g_DEADLOCK_THRESHOLD: 500000
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// Please: - Add new variables only to rubyconfig.defaults file.
|
// Please: - Add new variables only to rubyconfig.defaults file.
|
||||||
// - Change them here only when necessary.
|
// - Change them here only when necessary.
|
||||||
|
|
||||||
g_SIMICS: false
|
g_SIMULATING: false
|
||||||
DATA_BLOCK: true
|
DATA_BLOCK: true
|
||||||
RANDOMIZATION: true
|
RANDOMIZATION: true
|
||||||
g_SYNTHETIC_DRIVER: true
|
g_SYNTHETIC_DRIVER: true
|
||||||
|
|
|
@ -42,30 +42,13 @@
|
||||||
#include "Debug.hh"
|
#include "Debug.hh"
|
||||||
#include "Profiler.hh"
|
#include "Profiler.hh"
|
||||||
#include "Tester.hh"
|
#include "Tester.hh"
|
||||||
#include "OpalInterface.hh"
|
|
||||||
#include "init.hh"
|
#include "init.hh"
|
||||||
#include "interface.hh"
|
|
||||||
|
|
||||||
#ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
#include "ContiguousAddressTranslator.hh"
|
|
||||||
|
|
||||||
/* Declared in interface.C */
|
|
||||||
extern ContiguousAddressTranslator * g_p_ca_translator;
|
|
||||||
|
|
||||||
#endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
// Maurice
|
|
||||||
// extern "C" {
|
|
||||||
// #include "simics/api.hh"
|
|
||||||
// };
|
|
||||||
|
|
||||||
#include "FakeSimicsDataTypes.hh"
|
|
||||||
|
|
||||||
#include "confio.hh"
|
#include "confio.hh"
|
||||||
#include "initvar.hh"
|
#include "initvar.hh"
|
||||||
|
|
||||||
|
@ -73,210 +56,65 @@ using namespace std;
|
||||||
// The defaults are stored in the variable global_default_param
|
// The defaults are stored in the variable global_default_param
|
||||||
#include "default_param.hh"
|
#include "default_param.hh"
|
||||||
|
|
||||||
attr_value_t ruby_session_get( void *id, void *obj,
|
static initvar_t *ruby_initvar_obj = NULL;
|
||||||
attr_value_t *idx ) {
|
|
||||||
attr_value_t ret;
|
|
||||||
|
|
||||||
// all session attributes default to return invalid
|
|
||||||
ret.kind = Sim_Val_Invalid;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_error_t ruby_session_set( void *id, void *obj,
|
|
||||||
attr_value_t *val, attr_value_t *idx ) {
|
|
||||||
const char *command = (const char *) id;
|
|
||||||
// Add new ruby commands to this function
|
|
||||||
|
|
||||||
#if 0 // Eventually add these commands back in
|
|
||||||
if (!strcmp(command, "dump-stats" ) ) {
|
|
||||||
char* filename = (char*) val->u.string;
|
|
||||||
if(strcmp(filename, "")){
|
|
||||||
ruby_dump_stats(filename);
|
|
||||||
} else {
|
|
||||||
ruby_dump_stats(NULL);
|
|
||||||
}
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "dump-short-stats" ) ) {
|
|
||||||
char* filename = (char*) val->u.string;
|
|
||||||
if(strcmp(filename, "")){
|
|
||||||
ruby_dump_short_stats(filename);
|
|
||||||
} else {
|
|
||||||
ruby_dump_short_stats(NULL);
|
|
||||||
}
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "periodic-stats-file" ) ) {
|
|
||||||
char* filename = (char*) val->u.string;
|
|
||||||
ruby_set_periodic_stats_file(filename);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "periodic-stats-interval" ) ) {
|
|
||||||
int interval = val->u.integer;
|
|
||||||
ruby_set_periodic_stats_interval(interval);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "clear-stats" ) ) {
|
|
||||||
ruby_clear_stats();
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "debug-verb" ) ) {
|
|
||||||
char* new_verbosity = (char*) val->u.string;
|
|
||||||
ruby_change_debug_verbosity(new_verbosity);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "debug-filter" ) ) {
|
|
||||||
char* new_debug_filter = (char*) val->u.string;
|
|
||||||
ruby_change_debug_filter(new_debug_filter);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "debug-output-file" ) ) {
|
|
||||||
char* new_filename = (char*) val->u.string;
|
|
||||||
ruby_set_debug_output_file(new_filename);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "debug-start-time" ) ) {
|
|
||||||
char* new_start_time = (char*) val->u.string;
|
|
||||||
ruby_set_debug_start_time(new_start_time);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "load-caches" ) ) {
|
|
||||||
char* filename = (char*) val->u.string;
|
|
||||||
ruby_load_caches(filename);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "save-caches" ) ) {
|
|
||||||
char* filename = (char*) val->u.string;
|
|
||||||
ruby_save_caches(filename);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "dump-cache" ) ) {
|
|
||||||
int cpuNumber = val->u.integer;
|
|
||||||
ruby_dump_cache(cpuNumber);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "dump-cache-data" ) ) {
|
|
||||||
int cpuNumber = val->u.list.vector[0].u.integer;
|
|
||||||
char *filename = (char*) val->u.list.vector[1].u.string;
|
|
||||||
ruby_dump_cache_data( cpuNumber, filename );
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "tracer-output-file" ) ) {
|
|
||||||
char* new_filename = (char*) val->u.string;
|
|
||||||
ruby_set_tracer_output_file(new_filename);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
} else if (!strcmp(command, "xact-visualizer-file" ) ) {
|
|
||||||
char* new_filename = (char*) val->u.string;
|
|
||||||
ruby_xact_visualizer_file(new_filename);
|
|
||||||
return Sim_Set_Ok;
|
|
||||||
}
|
|
||||||
fprintf( stderr, "error: unrecognized command: %s\n", command );
|
|
||||||
#endif
|
|
||||||
return Sim_Set_Illegal_Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static initvar_t *ruby_initvar_obj = NULL;
|
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
static void init_generate_values( void )
|
static void init_generate_values( void )
|
||||||
{
|
{
|
||||||
/* update generated values, based on input configuration */
|
/* update generated values, based on input configuration */
|
||||||
}
|
}
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
void init_variables( void )
|
void init_variables( void )
|
||||||
{
|
{
|
||||||
// allocate the "variable initialization" package
|
// allocate the "variable initialization" package
|
||||||
ruby_initvar_obj = new initvar_t( "ruby", "../../../ruby/",
|
ruby_initvar_obj = new initvar_t( "ruby", "../../../ruby/",
|
||||||
global_default_param,
|
global_default_param,
|
||||||
&init_simulator,
|
&init_simulator,
|
||||||
&init_generate_values,
|
&init_generate_values );
|
||||||
&ruby_session_get,
|
|
||||||
&ruby_session_set );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_simulator()
|
void init_simulator()
|
||||||
{
|
{
|
||||||
// Set things to NULL to make sure we don't de-reference them
|
// Set things to NULL to make sure we don't de-reference them
|
||||||
// without a seg. fault.
|
// without a seg. fault.
|
||||||
g_system_ptr = NULL;
|
g_system_ptr = NULL;
|
||||||
g_debug_ptr = NULL;
|
g_debug_ptr = NULL;
|
||||||
g_eventQueue_ptr = NULL;
|
g_eventQueue_ptr = NULL;
|
||||||
|
|
||||||
cout << "Ruby Timing Mode" << endl;
|
cout << "Ruby Timing Mode" << endl;
|
||||||
|
|
||||||
if (g_SIMICS) {
|
RubyConfig::init();
|
||||||
// LUKE - if we don't set the default SMT threads in condor scripts,
|
|
||||||
// set it now
|
|
||||||
if(g_NUM_SMT_THREADS == 0){
|
|
||||||
g_NUM_SMT_THREADS = 1;
|
|
||||||
}
|
|
||||||
if(g_NUM_PROCESSORS == 0){
|
|
||||||
//only set to default if value not set in condor scripts
|
|
||||||
// Account for SMT systems also
|
|
||||||
g_NUM_PROCESSORS = SIMICS_number_processors()/g_NUM_SMT_THREADS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RubyConfig::init();
|
g_debug_ptr = new Debug( DEBUG_FILTER_STRING,
|
||||||
|
DEBUG_VERBOSITY_STRING,
|
||||||
|
DEBUG_START_TIME,
|
||||||
|
DEBUG_OUTPUT_FILENAME );
|
||||||
|
|
||||||
g_debug_ptr = new Debug( DEBUG_FILTER_STRING,
|
cout << "Creating event queue..." << endl;
|
||||||
DEBUG_VERBOSITY_STRING,
|
g_eventQueue_ptr = new RubyEventQueue;
|
||||||
DEBUG_START_TIME,
|
cout << "Creating event queue done" << endl;
|
||||||
DEBUG_OUTPUT_FILENAME );
|
|
||||||
|
|
||||||
cout << "Creating event queue..." << endl;
|
cout << "Creating system..." << endl;
|
||||||
g_eventQueue_ptr = new RubyEventQueue;
|
cout << " Processors: " << RubyConfig::numberOfProcessors() << endl;
|
||||||
cout << "Creating event queue done" << endl;
|
|
||||||
|
|
||||||
cout << "Creating system..." << endl;
|
g_system_ptr = new RubySystem;
|
||||||
cout << " Processors: " << RubyConfig::numberOfProcessors() << endl;
|
cout << "Creating system done" << endl;
|
||||||
|
|
||||||
g_system_ptr = new RubySystem;
|
cout << "Ruby initialization complete" << endl;
|
||||||
cout << "Creating system done" << endl;
|
|
||||||
|
|
||||||
// if opal is loaded, its static interface object (inst) will be non-null,
|
|
||||||
// and the opal object needs to be notified that ruby is now loaded.
|
|
||||||
// "1" indicates a load and should be replaced with an enumerated type.
|
|
||||||
if (OpalInterface::inst != NULL) {
|
|
||||||
OpalInterface::inst->notify( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
if(g_SIMICS) {
|
|
||||||
cout << "Establishing Contiguous Address Space Mappings..." << flush;
|
|
||||||
g_p_ca_translator = new ContiguousAddressTranslator();
|
|
||||||
assert(g_p_ca_translator!=NULL);
|
|
||||||
if(g_p_ca_translator->AddressesAreContiguous()) {
|
|
||||||
cout << "Physical Memory Addresses are already contiguous." << endl;
|
|
||||||
delete g_p_ca_translator;
|
|
||||||
g_p_ca_translator = NULL;
|
|
||||||
} else {
|
|
||||||
cout << "Done." << endl;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g_p_ca_translator = NULL;
|
|
||||||
}
|
|
||||||
#endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
|
|
||||||
cout << "Ruby initialization complete" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_opal_interface( mf_ruby_api_t *api )
|
|
||||||
{
|
|
||||||
OpalInterface::installInterface( api );
|
|
||||||
}
|
|
||||||
|
|
||||||
int init_use_snoop()
|
|
||||||
{
|
|
||||||
if (g_SIMICS) {
|
|
||||||
// The "snoop interface" defined by simics allows ruby to see store
|
|
||||||
// data values (from simics). If DATA_BLOCK is defined, we are tracking
|
|
||||||
// data, so we need to install the snoop interface.
|
|
||||||
return ((DATA_BLOCK == true) || (XACT_MEMORY));
|
|
||||||
} else {
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_simulator()
|
void destroy_simulator()
|
||||||
{
|
{
|
||||||
cout << "Deleting system..." << endl;
|
cout << "Deleting system..." << endl;
|
||||||
delete g_system_ptr;
|
delete g_system_ptr;
|
||||||
cout << "Deleting system done" << endl;
|
cout << "Deleting system done" << endl;
|
||||||
|
|
||||||
cout << "Deleting event queue..." << endl;
|
cout << "Deleting event queue..." << endl;
|
||||||
delete g_eventQueue_ptr;
|
delete g_eventQueue_ptr;
|
||||||
cout << "Deleting event queue done" << endl;
|
cout << "Deleting event queue done" << endl;
|
||||||
|
|
||||||
delete g_debug_ptr;
|
delete g_debug_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------+
|
/*-------------------------------------------------------------------------+
|
||||||
|
@ -286,19 +124,23 @@ void destroy_simulator()
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
int OnLoadRuby() {
|
int OnLoadRuby() {
|
||||||
init_variables();
|
init_variables();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
int OnInitRuby() {
|
int OnInitRuby() {
|
||||||
init_simulator();
|
init_simulator();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
int OnUnloadRuby() {
|
int OnUnloadRuby() {
|
||||||
destroy_simulator();
|
destroy_simulator();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* I have to put it somewhere for now */
|
||||||
|
void tester_main(int argc, char **argv) {
|
||||||
|
std::cout << __FILE__ << "(" << __LINE__ << "): Not implemented." << std::endl;
|
||||||
|
}
|
||||||
|
|
|
@ -39,18 +39,8 @@
|
||||||
#ifndef INIT_H
|
#ifndef INIT_H
|
||||||
#define INIT_H
|
#define INIT_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void init_variables();
|
extern void init_variables();
|
||||||
extern void init_simulator();
|
extern void init_simulator();
|
||||||
extern void init_opal_interface( mf_ruby_api_t *api );
|
|
||||||
extern int init_use_snoop();
|
|
||||||
extern void destroy_simulator();
|
extern void destroy_simulator();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //INIT_H
|
#endif //INIT_H
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -58,9 +58,6 @@ class NetworkConfig {
|
||||||
string filename = "network/garnet-flexible-pipeline/";
|
string filename = "network/garnet-flexible-pipeline/";
|
||||||
filename += NETCONFIG_DEFAULTS;
|
filename += NETCONFIG_DEFAULTS;
|
||||||
|
|
||||||
if (g_SIMICS) {
|
|
||||||
filename = "../../../ruby/"+filename;
|
|
||||||
}
|
|
||||||
ifstream NetconfigFile( filename.c_str(), ios::in);
|
ifstream NetconfigFile( filename.c_str(), ios::in);
|
||||||
if(!NetconfigFile.is_open())
|
if(!NetconfigFile.is_open())
|
||||||
{
|
{
|
||||||
|
|
|
@ -433,9 +433,6 @@ void Topology::makeFileSpecified()
|
||||||
+"_Memories-"+int_to_string(RubyConfig::numberOfMemories())
|
+"_Memories-"+int_to_string(RubyConfig::numberOfMemories())
|
||||||
+".txt";
|
+".txt";
|
||||||
|
|
||||||
if (g_SIMICS) {
|
|
||||||
filename = "../../../ruby/"+filename;
|
|
||||||
}
|
|
||||||
ifstream networkFile( filename.c_str() , ios::in);
|
ifstream networkFile( filename.c_str() , ios::in);
|
||||||
if (!networkFile.is_open()) {
|
if (!networkFile.is_open()) {
|
||||||
cerr << "Error: Could not open network file: " << filename << endl;
|
cerr << "Error: Could not open network file: " << filename << endl;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,19 +27,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file has been modified by Kevin Moore and Dan Nussbaum of the
|
This file has been modified by Kevin Moore and Dan Nussbaum of the
|
||||||
Scalable Systems Research Group at Sun Microsystems Laboratories
|
Scalable Systems Research Group at Sun Microsystems Laboratories
|
||||||
(http://research.sun.com/scalable/) to support the Adaptive
|
(http://research.sun.com/scalable/) to support the Adaptive
|
||||||
Transactional Memory Test Platform (ATMTP).
|
Transactional Memory Test Platform (ATMTP).
|
||||||
|
|
||||||
Please send email to atmtp-interest@sun.com with feedback, questions, or
|
Please send email to atmtp-interest@sun.com with feedback, questions, or
|
||||||
to request future announcements about ATMTP.
|
to request future announcements about ATMTP.
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
File modification date: 2008-02-23
|
File modification date: 2008-02-23
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -68,7 +68,6 @@
|
||||||
#include "Set.hh"
|
#include "Set.hh"
|
||||||
#include "CacheRequestType.hh"
|
#include "CacheRequestType.hh"
|
||||||
#include "GenericRequestType.hh"
|
#include "GenericRequestType.hh"
|
||||||
//#include "XactProfiler.hh" //gem5:Arka for decomissioning og log_tm
|
|
||||||
|
|
||||||
class CacheMsg;
|
class CacheMsg;
|
||||||
class CacheProfiler;
|
class CacheProfiler;
|
||||||
|
@ -78,355 +77,229 @@ template <class KEY_TYPE, class VALUE_TYPE> class Map;
|
||||||
|
|
||||||
class Profiler : public Consumer {
|
class Profiler : public Consumer {
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
Profiler();
|
Profiler();
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~Profiler();
|
~Profiler();
|
||||||
|
|
||||||
// Public Methods
|
// Public Methods
|
||||||
void wakeup();
|
void wakeup();
|
||||||
|
|
||||||
void setPeriodicStatsFile(const string& filename);
|
void setPeriodicStatsFile(const string& filename);
|
||||||
void setPeriodicStatsInterval(integer_t period);
|
void setPeriodicStatsInterval(integer_t period);
|
||||||
|
|
||||||
void setXactVisualizerFile(char* filename);
|
void printStats(ostream& out, bool short_stats=false);
|
||||||
|
void printShortStats(ostream& out) { printStats(out, true); }
|
||||||
|
void printTraceStats(ostream& out) const;
|
||||||
|
void clearStats();
|
||||||
|
void printConfig(ostream& out) const;
|
||||||
|
void printResourceUsage(ostream& out) const;
|
||||||
|
|
||||||
void printStats(ostream& out, bool short_stats=false);
|
AddressProfiler* getAddressProfiler() { return m_address_profiler_ptr; }
|
||||||
void printShortStats(ostream& out) { printStats(out, true); }
|
AddressProfiler* getInstructionProfiler() { return m_inst_profiler_ptr; }
|
||||||
void printTraceStats(ostream& out) const;
|
|
||||||
void clearStats();
|
|
||||||
void printConfig(ostream& out) const;
|
|
||||||
void printResourceUsage(ostream& out) const;
|
|
||||||
|
|
||||||
AddressProfiler* getAddressProfiler() { return m_address_profiler_ptr; }
|
void addPrimaryStatSample(const CacheMsg& msg, NodeID id);
|
||||||
AddressProfiler* getInstructionProfiler() { return m_inst_profiler_ptr; }
|
void addSecondaryStatSample(GenericRequestType requestType,
|
||||||
//XactProfiler* getXactProfiler() { return m_xact_profiler_ptr;} //gem5:Arka for decomissioning og log_tm
|
AccessModeType type, int msgSize,
|
||||||
|
PrefetchBit pfBit, NodeID id);
|
||||||
|
void addSecondaryStatSample(CacheRequestType requestType,
|
||||||
|
AccessModeType type, int msgSize,
|
||||||
|
PrefetchBit pfBit, NodeID id);
|
||||||
|
void addAddressTraceSample(const CacheMsg& msg, NodeID id);
|
||||||
|
|
||||||
void addPrimaryStatSample(const CacheMsg& msg, NodeID id);
|
void profileRequest(const string& requestStr);
|
||||||
void addSecondaryStatSample(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id);
|
void profileSharing(const Address& addr, AccessType type,
|
||||||
void addSecondaryStatSample(CacheRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id);
|
NodeID requestor, const Set& sharers,
|
||||||
void addAddressTraceSample(const CacheMsg& msg, NodeID id);
|
const Set& owner);
|
||||||
|
|
||||||
void profileRequest(const string& requestStr);
|
void profileMulticastRetry(const Address& addr, int count);
|
||||||
void profileSharing(const Address& addr, AccessType type, NodeID requestor, const Set& sharers, const Set& owner);
|
|
||||||
|
|
||||||
void profileMulticastRetry(const Address& addr, int count);
|
void profileFilterAction(int action);
|
||||||
|
|
||||||
void profileFilterAction(int action);
|
void profileConflictingRequests(const Address& addr);
|
||||||
|
void profileOutstandingRequest(int outstanding) {
|
||||||
|
m_outstanding_requests.add(outstanding);
|
||||||
|
}
|
||||||
|
|
||||||
void profileConflictingRequests(const Address& addr);
|
void profileOutstandingPersistentRequest(int outstanding) {
|
||||||
void profileOutstandingRequest(int outstanding) { m_outstanding_requests.add(outstanding); }
|
m_outstanding_persistent_requests.add(outstanding);
|
||||||
void profileOutstandingPersistentRequest(int outstanding) { m_outstanding_persistent_requests.add(outstanding); }
|
}
|
||||||
void profileAverageLatencyEstimate(int latency) { m_average_latency_estimate.add(latency); }
|
void profileAverageLatencyEstimate(int latency) {
|
||||||
|
m_average_latency_estimate.add(latency);
|
||||||
|
}
|
||||||
|
|
||||||
void countBAUnicast() { m_num_BA_unicasts++; }
|
void countBAUnicast() { m_num_BA_unicasts++; }
|
||||||
void countBABroadcast() { m_num_BA_broadcasts++; }
|
void countBABroadcast() { m_num_BA_broadcasts++; }
|
||||||
|
|
||||||
void recordPrediction(bool wasGood, bool wasPredicted);
|
void recordPrediction(bool wasGood, bool wasPredicted);
|
||||||
|
|
||||||
void startTransaction(int cpu);
|
void startTransaction(int cpu);
|
||||||
void endTransaction(int cpu);
|
void endTransaction(int cpu);
|
||||||
void profilePFWait(Time waitTime);
|
void profilePFWait(Time waitTime);
|
||||||
|
|
||||||
void controllerBusy(MachineID machID);
|
void controllerBusy(MachineID machID);
|
||||||
void bankBusy();
|
void bankBusy();
|
||||||
void missLatency(Time t, CacheRequestType type, GenericMachineType respondingMach);
|
void missLatency(Time t, CacheRequestType type,
|
||||||
void swPrefetchLatency(Time t, CacheRequestType type, GenericMachineType respondingMach);
|
GenericMachineType respondingMach);
|
||||||
void stopTableUsageSample(int num) { m_stopTableProfile.add(num); }
|
void swPrefetchLatency(Time t, CacheRequestType type,
|
||||||
void L1tbeUsageSample(int num) { m_L1tbeProfile.add(num); }
|
GenericMachineType respondingMach);
|
||||||
void L2tbeUsageSample(int num) { m_L2tbeProfile.add(num); }
|
void stopTableUsageSample(int num) { m_stopTableProfile.add(num); }
|
||||||
void sequencerRequests(int num) { m_sequencer_requests.add(num); }
|
void L1tbeUsageSample(int num) { m_L1tbeProfile.add(num); }
|
||||||
void storeBuffer(int size, int blocks) { m_store_buffer_size.add(size); m_store_buffer_blocks.add(blocks);}
|
void L2tbeUsageSample(int num) { m_L2tbeProfile.add(num); }
|
||||||
|
void sequencerRequests(int num) { m_sequencer_requests.add(num); }
|
||||||
|
void storeBuffer(int size, int blocks) {
|
||||||
|
m_store_buffer_size.add(size);
|
||||||
|
m_store_buffer_blocks.add(blocks);
|
||||||
|
}
|
||||||
|
|
||||||
void profileGetXMaskPrediction(const Set& pred_set);
|
void profileGetXMaskPrediction(const Set& pred_set);
|
||||||
void profileGetSMaskPrediction(const Set& pred_set);
|
void profileGetSMaskPrediction(const Set& pred_set);
|
||||||
void profileTrainingMask(const Set& pred_set);
|
void profileTrainingMask(const Set& pred_set);
|
||||||
void profileTransition(const string& component, NodeID id, NodeID version, Address addr,
|
void profileTransition(const string& component, NodeID id, NodeID version,
|
||||||
const string& state, const string& event,
|
Address addr, const string& state,
|
||||||
const string& next_state, const string& note);
|
const string& event, const string& next_state,
|
||||||
void profileMsgDelay(int virtualNetwork, int delayCycles);
|
const string& note);
|
||||||
|
void profileMsgDelay(int virtualNetwork, int delayCycles);
|
||||||
|
|
||||||
void print(ostream& out) const;
|
void print(ostream& out) const;
|
||||||
|
|
||||||
int64 getTotalInstructionsExecuted() const;
|
int64 getTotalInstructionsExecuted() const;
|
||||||
int64 getTotalTransactionsExecuted() const;
|
int64 getTotalTransactionsExecuted() const;
|
||||||
|
|
||||||
//---- begin Transactional Memory CODE
|
Time getRubyStartTime(){
|
||||||
#if 0 //gem5:Arka for decomissioning og log_tm
|
return m_ruby_start;
|
||||||
void profileTransCycles(int proc, int cycles) { getXactProfiler()->profileTransCycles(proc, cycles);}
|
}
|
||||||
void profileNonTransCycles(int proc, int cycles) { getXactProfiler()->profileNonTransCycles(proc, cycles);}
|
|
||||||
void profileStallTransCycles(int proc, int cycles) { getXactProfiler()->profileStallTransCycles(proc, cycles); }
|
|
||||||
void profileStallNonTransCycles(int proc, int cycles) { getXactProfiler()->profileStallNonTransCycles(proc, cycles); }
|
|
||||||
void profileAbortingTransCycles(int proc, int cycles) { getXactProfiler()->profileAbortingTransCycles(proc, cycles); }
|
|
||||||
void profileCommitingTransCycles(int proc, int cycles) { getXactProfiler()->profileCommitingTransCycles(proc, cycles); }
|
|
||||||
void profileBarrierCycles(int proc, int cycles) { getXactProfiler()->profileBarrierCycles(proc, cycles);}
|
|
||||||
void profileBackoffTransCycles(int proc, int cycles) { getXactProfiler()->profileBackoffTransCycles(proc, cycles); }
|
|
||||||
void profileGoodTransCycles(int proc, int cycles) {getXactProfiler()->profileGoodTransCycles(proc, cycles); }
|
|
||||||
|
|
||||||
#endif //gem5:Arka TODO clean up the rest of this functions as well
|
// added for MemoryControl:
|
||||||
void profileTransaction(int size, int logSize, int readS, int writeS, int overflow_readS, int overflow_writeS, int retries, int cycles, bool nacked, int loadMisses, int storeMisses, int instrCount, int xid);
|
void profileMemReq(int bank);
|
||||||
void profileBeginTransaction(NodeID id, int tid, int xid, int thread, Address pc, bool isOpen);
|
void profileMemBankBusy();
|
||||||
void profileCommitTransaction(NodeID id, int tid, int xid, int thread, Address pc, bool isOpen);
|
void profileMemBusBusy();
|
||||||
void profileLoadTransaction(NodeID id, int tid, int xid, int thread, Address addr, Address logicalAddress, Address pc);
|
void profileMemTfawBusy();
|
||||||
void profileLoad(NodeID id, int tid, int xid, int thread, Address addr, Address logicalAddress, Address pc);
|
void profileMemReadWriteBusy();
|
||||||
void profileStoreTransaction(NodeID id, int tid, int xid, int thread, Address addr, Address logicalAddress, Address pc);
|
void profileMemDataBusBusy();
|
||||||
void profileStore(NodeID id, int tid, int xid, int thread, Address addr, Address logicalAddress, Address pc);
|
void profileMemRefresh();
|
||||||
void profileLoadOverflow(NodeID id, int tid, int xid, int thread, Address addr, bool l1_overflow);
|
void profileMemRead();
|
||||||
void profileStoreOverflow(NodeID id, int tid, int xid, int thread, Address addr, bool l1_overflow);
|
void profileMemWrite();
|
||||||
void profileNack(NodeID id, int tid, int xid, int thread, int nacking_thread, NodeID nackedBy, Address addr, Address logicalAddress, Address pc, uint64 seq_ts, uint64 nack_ts, bool possibleCycle);
|
void profileMemWaitCycles(int cycles);
|
||||||
void profileExposedConflict(NodeID id, int xid, int thread, Address addr, Address pc);
|
void profileMemInputQ(int cycles);
|
||||||
void profileTransWB();
|
void profileMemBankQ(int cycles);
|
||||||
void profileExtraWB();
|
void profileMemArbWait(int cycles);
|
||||||
void profileInferredAbort();
|
void profileMemRandBusy();
|
||||||
void profileAbortTransaction(NodeID id, int tid, int xid, int thread, int delay, int abortingThread, int abortingProc, Address addr, Address pc);
|
void profileMemNotOld();
|
||||||
void profileExceptionStart(bool xact, NodeID proc_no, int thread, int val, int trap_level, uinteger_t pc, uinteger_t npc);
|
|
||||||
void profileExceptionDone(bool xact, NodeID proc_no, int thread, int val, int trap_level, uinteger_t pc, uinteger_t npc, uinteger_t tpc, uinteger_t tnpc);
|
|
||||||
void profileTimerInterrupt(NodeID id,
|
|
||||||
uinteger_t tick, uinteger_t tick_cmpr,
|
|
||||||
uinteger_t stick, uinteger_t stick_cmpr,
|
|
||||||
int trap_level,
|
|
||||||
uinteger_t pc, uinteger_t npc,
|
|
||||||
uinteger_t pstate, int pil);
|
|
||||||
|
|
||||||
void profileAbortDelayConstants(int handlerStartupDelay, int handlerPerBlockDelay);
|
|
||||||
void profileXactChange(int procs, int cycles);
|
|
||||||
void profileReadSet(Address addr, bool bf_filter_result, bool perfect_filter_result, NodeID id, int thread);
|
|
||||||
void profileWriteSet(Address addr, bool bf_filter_result, bool perfect_filter_result, NodeID id, int thread);
|
|
||||||
void profileRemoteReadSet(Address addr, bool bf_filter_result, bool perfect_filter_result, NodeID id, int thread);
|
|
||||||
void profileRemoteWriteSet(Address addr, bool bf_filter_result, bool perfect_filter_result, NodeID id, int thread);
|
|
||||||
|
|
||||||
|
|
||||||
void profileReadFilterBitsSet(int xid, int bits, bool isCommit);
|
|
||||||
void profileWriteFilterBitsSet(int xid, int bits, bool isCommit);
|
|
||||||
|
|
||||||
void printTransactionState(bool can_skip);
|
|
||||||
|
|
||||||
void watchpointsFalsePositiveTrigger();
|
|
||||||
void watchpointsTrueTrigger();
|
|
||||||
|
|
||||||
void profileTransactionLogOverflow(NodeID id, Address addr, Address pc);
|
|
||||||
void profileTransactionCacheOverflow(NodeID id, Address addr, Address pc);
|
|
||||||
void profileGetCPS(NodeID id, uint32 cps, Address pc);
|
|
||||||
void profileTransactionTCC(NodeID id, Address pc);
|
|
||||||
void profileTransactionUnsupInst(NodeID id, Address pc);
|
|
||||||
void profileTransactionSaveInst(NodeID id, Address pc);
|
|
||||||
void profileTransactionRestoreInst(NodeID id, Address pc);
|
|
||||||
|
|
||||||
//---- end Transactional Memory CODE
|
|
||||||
|
|
||||||
void rubyWatch(int proc);
|
|
||||||
bool watchAddress(Address addr);
|
|
||||||
|
|
||||||
// return Ruby's start time
|
|
||||||
Time getRubyStartTime(){
|
|
||||||
return m_ruby_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// added for MemoryControl:
|
|
||||||
void profileMemReq(int bank);
|
|
||||||
void profileMemBankBusy();
|
|
||||||
void profileMemBusBusy();
|
|
||||||
void profileMemTfawBusy();
|
|
||||||
void profileMemReadWriteBusy();
|
|
||||||
void profileMemDataBusBusy();
|
|
||||||
void profileMemRefresh();
|
|
||||||
void profileMemRead();
|
|
||||||
void profileMemWrite();
|
|
||||||
void profileMemWaitCycles(int cycles);
|
|
||||||
void profileMemInputQ(int cycles);
|
|
||||||
void profileMemBankQ(int cycles);
|
|
||||||
void profileMemArbWait(int cycles);
|
|
||||||
void profileMemRandBusy();
|
|
||||||
void profileMemNotOld();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Private Methods
|
// Private Methods
|
||||||
void addL2StatSample(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id);
|
void addL2StatSample(GenericRequestType requestType, AccessModeType type,
|
||||||
void addL1DStatSample(const CacheMsg& msg, NodeID id);
|
int msgSize, PrefetchBit pfBit, NodeID id);
|
||||||
void addL1IStatSample(const CacheMsg& msg, NodeID id);
|
void addL1DStatSample(const CacheMsg& msg, NodeID id);
|
||||||
|
void addL1IStatSample(const CacheMsg& msg, NodeID id);
|
||||||
|
|
||||||
GenericRequestType CacheRequestType_to_GenericRequestType(const CacheRequestType& type);
|
GenericRequestType CacheRequestType_to_GenericRequestType(const CacheRequestType& type);
|
||||||
|
|
||||||
// Private copy constructor and assignment operator
|
// Private copy constructor and assignment operator
|
||||||
Profiler(const Profiler& obj);
|
Profiler(const Profiler& obj);
|
||||||
Profiler& operator=(const Profiler& obj);
|
Profiler& operator=(const Profiler& obj);
|
||||||
|
|
||||||
// Data Members (m_ prefix)
|
// Data Members (m_ prefix)
|
||||||
CacheProfiler* m_L1D_cache_profiler_ptr;
|
CacheProfiler* m_L1D_cache_profiler_ptr;
|
||||||
CacheProfiler* m_L1I_cache_profiler_ptr;
|
CacheProfiler* m_L1I_cache_profiler_ptr;
|
||||||
CacheProfiler* m_L2_cache_profiler_ptr;
|
CacheProfiler* m_L2_cache_profiler_ptr;
|
||||||
AddressProfiler* m_address_profiler_ptr;
|
AddressProfiler* m_address_profiler_ptr;
|
||||||
AddressProfiler* m_inst_profiler_ptr;
|
AddressProfiler* m_inst_profiler_ptr;
|
||||||
|
|
||||||
// XactProfiler* m_xact_profiler_ptr; // gem5:Arka for decomissioning of log_tm
|
Vector<int64> m_instructions_executed_at_start;
|
||||||
|
Vector<int64> m_cycles_executed_at_start;
|
||||||
|
|
||||||
Vector<int64> m_instructions_executed_at_start;
|
ostream* m_periodic_output_file_ptr;
|
||||||
Vector<int64> m_cycles_executed_at_start;
|
integer_t m_stats_period;
|
||||||
|
|
||||||
ostream* m_periodic_output_file_ptr;
|
Time m_ruby_start;
|
||||||
integer_t m_stats_period;
|
time_t m_real_time_start_time;
|
||||||
std::fstream m_xact_visualizer;
|
|
||||||
std::ostream *m_xact_visualizer_ptr;
|
|
||||||
|
|
||||||
Time m_ruby_start;
|
int m_num_BA_unicasts;
|
||||||
time_t m_real_time_start_time;
|
int m_num_BA_broadcasts;
|
||||||
|
|
||||||
int m_num_BA_unicasts;
|
Vector<integer_t> m_perProcTotalMisses;
|
||||||
int m_num_BA_broadcasts;
|
Vector<integer_t> m_perProcUserMisses;
|
||||||
|
Vector<integer_t> m_perProcSupervisorMisses;
|
||||||
|
Vector<integer_t> m_perProcStartTransaction;
|
||||||
|
Vector<integer_t> m_perProcEndTransaction;
|
||||||
|
Vector < Vector < integer_t > > m_busyControllerCount;
|
||||||
|
integer_t m_busyBankCount;
|
||||||
|
Histogram m_multicast_retry_histogram;
|
||||||
|
|
||||||
Vector<integer_t> m_perProcTotalMisses;
|
Histogram m_L1tbeProfile;
|
||||||
Vector<integer_t> m_perProcUserMisses;
|
Histogram m_L2tbeProfile;
|
||||||
Vector<integer_t> m_perProcSupervisorMisses;
|
Histogram m_stopTableProfile;
|
||||||
Vector<integer_t> m_perProcStartTransaction;
|
|
||||||
Vector<integer_t> m_perProcEndTransaction;
|
|
||||||
Vector < Vector < integer_t > > m_busyControllerCount;
|
|
||||||
integer_t m_busyBankCount;
|
|
||||||
Histogram m_multicast_retry_histogram;
|
|
||||||
|
|
||||||
Histogram m_L1tbeProfile;
|
Histogram m_filter_action_histogram;
|
||||||
Histogram m_L2tbeProfile;
|
Histogram m_tbeProfile;
|
||||||
Histogram m_stopTableProfile;
|
|
||||||
|
|
||||||
Histogram m_filter_action_histogram;
|
Histogram m_sequencer_requests;
|
||||||
Histogram m_tbeProfile;
|
Histogram m_store_buffer_size;
|
||||||
|
Histogram m_store_buffer_blocks;
|
||||||
|
Histogram m_read_sharing_histogram;
|
||||||
|
Histogram m_write_sharing_histogram;
|
||||||
|
Histogram m_all_sharing_histogram;
|
||||||
|
int64 m_cache_to_cache;
|
||||||
|
int64 m_memory_to_cache;
|
||||||
|
|
||||||
Histogram m_sequencer_requests;
|
Histogram m_prefetchWaitHistogram;
|
||||||
Histogram m_store_buffer_size;
|
|
||||||
Histogram m_store_buffer_blocks;
|
|
||||||
Histogram m_read_sharing_histogram;
|
|
||||||
Histogram m_write_sharing_histogram;
|
|
||||||
Histogram m_all_sharing_histogram;
|
|
||||||
int64 m_cache_to_cache;
|
|
||||||
int64 m_memory_to_cache;
|
|
||||||
|
|
||||||
Histogram m_prefetchWaitHistogram;
|
Vector<Histogram> m_missLatencyHistograms;
|
||||||
|
Vector<Histogram> m_machLatencyHistograms;
|
||||||
|
Histogram m_L2MissLatencyHistogram;
|
||||||
|
Histogram m_allMissLatencyHistogram;
|
||||||
|
|
||||||
Vector<Histogram> m_missLatencyHistograms;
|
Histogram m_allSWPrefetchLatencyHistogram;
|
||||||
Vector<Histogram> m_machLatencyHistograms;
|
Histogram m_SWPrefetchL2MissLatencyHistogram;
|
||||||
Histogram m_L2MissLatencyHistogram;
|
Vector<Histogram> m_SWPrefetchLatencyHistograms;
|
||||||
Histogram m_allMissLatencyHistogram;
|
Vector<Histogram> m_SWPrefetchMachLatencyHistograms;
|
||||||
|
|
||||||
Histogram m_allSWPrefetchLatencyHistogram;
|
Histogram m_delayedCyclesHistogram;
|
||||||
Histogram m_SWPrefetchL2MissLatencyHistogram;
|
Histogram m_delayedCyclesNonPFHistogram;
|
||||||
Vector<Histogram> m_SWPrefetchLatencyHistograms;
|
Vector<Histogram> m_delayedCyclesVCHistograms;
|
||||||
Vector<Histogram> m_SWPrefetchMachLatencyHistograms;
|
|
||||||
|
|
||||||
Histogram m_delayedCyclesHistogram;
|
int m_predictions;
|
||||||
Histogram m_delayedCyclesNonPFHistogram;
|
int m_predictionOpportunities;
|
||||||
Vector<Histogram> m_delayedCyclesVCHistograms;
|
int m_goodPredictions;
|
||||||
|
|
||||||
int m_predictions;
|
Histogram m_gets_mask_prediction;
|
||||||
int m_predictionOpportunities;
|
Histogram m_getx_mask_prediction;
|
||||||
int m_goodPredictions;
|
Histogram m_explicit_training_mask;
|
||||||
|
|
||||||
Histogram m_gets_mask_prediction;
|
// For profiling possibly conflicting requests
|
||||||
Histogram m_getx_mask_prediction;
|
Map<Address, Time>* m_conflicting_map_ptr;
|
||||||
Histogram m_explicit_training_mask;
|
Histogram m_conflicting_histogram;
|
||||||
|
|
||||||
// For profiling possibly conflicting requests
|
Histogram m_outstanding_requests;
|
||||||
Map<Address, Time>* m_conflicting_map_ptr;
|
Histogram m_outstanding_persistent_requests;
|
||||||
Histogram m_conflicting_histogram;
|
|
||||||
|
|
||||||
Histogram m_outstanding_requests;
|
Histogram m_average_latency_estimate;
|
||||||
Histogram m_outstanding_persistent_requests;
|
|
||||||
|
|
||||||
Histogram m_average_latency_estimate;
|
Map<Address, int>* m_watch_address_list_ptr;
|
||||||
|
// counts all initiated cache request including PUTs
|
||||||
|
int m_requests;
|
||||||
|
Map <string, int>* m_requestProfileMap_ptr;
|
||||||
|
|
||||||
//---- begin Transactional Memory CODE
|
// added for MemoryControl:
|
||||||
Map <int, int>* m_procsInXactMap_ptr;
|
long long int m_memReq;
|
||||||
|
long long int m_memBankBusy;
|
||||||
Histogram m_xactCycles;
|
long long int m_memBusBusy;
|
||||||
Histogram m_xactLogs;
|
long long int m_memTfawBusy;
|
||||||
Histogram m_xactReads;
|
long long int m_memReadWriteBusy;
|
||||||
Histogram m_xactWrites;
|
long long int m_memDataBusBusy;
|
||||||
Histogram m_xactOverflowReads;
|
long long int m_memRefresh;
|
||||||
Histogram m_xactOverflowWrites;
|
long long int m_memRead;
|
||||||
Histogram m_xactOverflowTotalReads;
|
long long int m_memWrite;
|
||||||
Histogram m_xactOverflowTotalWrites;
|
long long int m_memWaitCycles;
|
||||||
Histogram m_xactSizes;
|
long long int m_memInputQ;
|
||||||
Histogram m_xactRetries;
|
long long int m_memBankQ;
|
||||||
Histogram m_abortDelays;
|
long long int m_memArbWait;
|
||||||
Histogram m_xactLoadMisses;
|
long long int m_memRandBusy;
|
||||||
Histogram m_xactStoreMisses;
|
long long int m_memNotOld;
|
||||||
Histogram m_xactInstrCount;
|
Vector<long long int> m_memBankCount;
|
||||||
int m_xactNacked;
|
|
||||||
int m_transactionAborts;
|
|
||||||
int m_transWBs;
|
|
||||||
int m_extraWBs;
|
|
||||||
int m_abortStarupDelay;
|
|
||||||
int m_abortPerBlockDelay;
|
|
||||||
int m_inferredAborts;
|
|
||||||
Map <int, int>* m_nackXIDMap_ptr;
|
|
||||||
// pairs of XIDs involved in NACKs
|
|
||||||
Map<int, Map<int, int> * > * m_nackXIDPairMap_ptr;
|
|
||||||
Map <Address, int>* m_nackPCMap_ptr;
|
|
||||||
Map <int, int>* m_xactExceptionMap_ptr;
|
|
||||||
Map <int, int>* m_abortIDMap_ptr;
|
|
||||||
Map <int, int>* m_commitIDMap_ptr;
|
|
||||||
Map <int, int>* m_xactRetryIDMap_ptr;
|
|
||||||
Map <int, int>* m_xactCyclesIDMap_ptr;
|
|
||||||
Map <int, int>* m_xactReadSetIDMap_ptr;
|
|
||||||
Map <int, int>* m_xactWriteSetIDMap_ptr;
|
|
||||||
Map <int, int>* m_xactLoadMissIDMap_ptr;
|
|
||||||
Map <int, int>* m_xactStoreMissIDMap_ptr;
|
|
||||||
Map <int, integer_t> *m_xactInstrCountIDMap_ptr;
|
|
||||||
Map <Address, int>* m_abortPCMap_ptr;
|
|
||||||
Map <Address, int>* m_abortAddressMap_ptr;
|
|
||||||
Map <Address, int>* m_readSetMatch_ptr;
|
|
||||||
Map <Address, int>* m_readSetNoMatch_ptr;
|
|
||||||
Map <Address, int>* m_writeSetMatch_ptr;
|
|
||||||
Map <Address, int>* m_writeSetNoMatch_ptr;
|
|
||||||
Map <Address, int>* m_remoteReadSetMatch_ptr;
|
|
||||||
Map <Address, int>* m_remoteReadSetNoMatch_ptr;
|
|
||||||
Map <Address, int>* m_remoteWriteSetMatch_ptr;
|
|
||||||
Map <Address, int>* m_remoteWriteSetNoMatch_ptr;
|
|
||||||
long long int m_readSetEmptyChecks;
|
|
||||||
long long int m_readSetMatch;
|
|
||||||
long long int m_readSetNoMatch;
|
|
||||||
long long int m_writeSetEmptyChecks;
|
|
||||||
long long int m_writeSetMatch;
|
|
||||||
long long int m_writeSetNoMatch;
|
|
||||||
Map<int, Histogram> * m_xactReadFilterBitsSetOnCommit;
|
|
||||||
Map<int, Histogram> * m_xactReadFilterBitsSetOnAbort;
|
|
||||||
Map<int, Histogram> * m_xactWriteFilterBitsSetOnCommit;
|
|
||||||
Map<int, Histogram> * m_xactWriteFilterBitsSetOnAbort;
|
|
||||||
|
|
||||||
unsigned int m_watchpointsFalsePositiveTrigger;
|
|
||||||
unsigned int m_watchpointsTrueTrigger;
|
|
||||||
|
|
||||||
int m_transactionUnsupInsts;
|
|
||||||
int m_transactionSaveRestAborts;
|
|
||||||
|
|
||||||
int m_transactionLogOverflows;
|
|
||||||
int m_transactionCacheOverflows;
|
|
||||||
|
|
||||||
//---- end Transactional Memory CODE
|
|
||||||
|
|
||||||
Map<Address, int>* m_watch_address_list_ptr;
|
|
||||||
// counts all initiated cache request including PUTs
|
|
||||||
int m_requests;
|
|
||||||
Map <string, int>* m_requestProfileMap_ptr;
|
|
||||||
|
|
||||||
Time m_xact_visualizer_last;
|
|
||||||
|
|
||||||
// added for MemoryControl:
|
|
||||||
long long int m_memReq;
|
|
||||||
long long int m_memBankBusy;
|
|
||||||
long long int m_memBusBusy;
|
|
||||||
long long int m_memTfawBusy;
|
|
||||||
long long int m_memReadWriteBusy;
|
|
||||||
long long int m_memDataBusBusy;
|
|
||||||
long long int m_memRefresh;
|
|
||||||
long long int m_memRead;
|
|
||||||
long long int m_memWrite;
|
|
||||||
long long int m_memWaitCycles;
|
|
||||||
long long int m_memInputQ;
|
|
||||||
long long int m_memBankQ;
|
|
||||||
long long int m_memArbWait;
|
|
||||||
long long int m_memRandBusy;
|
|
||||||
long long int m_memNotOld;
|
|
||||||
Vector<long long int> m_memBankCount;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -439,9 +312,9 @@ ostream& operator<<(ostream& out, const Profiler& obj);
|
||||||
extern inline
|
extern inline
|
||||||
ostream& operator<<(ostream& out, const Profiler& obj)
|
ostream& operator<<(ostream& out, const Profiler& obj)
|
||||||
{
|
{
|
||||||
obj.print(out);
|
obj.print(out);
|
||||||
out << flush;
|
out << flush;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //PROFILER_H
|
#endif //PROFILER_H
|
||||||
|
|
|
@ -36,40 +36,44 @@
|
||||||
#include "TraceRecord.hh"
|
#include "TraceRecord.hh"
|
||||||
#include "RubyEventQueue.hh"
|
#include "RubyEventQueue.hh"
|
||||||
#include "PrioHeap.hh"
|
#include "PrioHeap.hh"
|
||||||
#include "gzstream.hh"
|
|
||||||
|
|
||||||
CacheRecorder::CacheRecorder()
|
CacheRecorder::CacheRecorder()
|
||||||
{
|
{
|
||||||
m_records_ptr = new PrioHeap<TraceRecord>;
|
std::cout << __FILE__ << "(" << __LINE__ << "): Not implemented" << std::endl;
|
||||||
|
// m_records_ptr = new PrioHeap<TraceRecord>;
|
||||||
}
|
}
|
||||||
|
|
||||||
CacheRecorder::~CacheRecorder()
|
CacheRecorder::~CacheRecorder()
|
||||||
{
|
{
|
||||||
delete m_records_ptr;
|
std::cout << __FILE__ << "(" << __LINE__ << "): Not implemented" << std::endl;
|
||||||
|
// delete m_records_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CacheRecorder::addRecord(NodeID id, const Address& data_addr, const Address& pc_addr, CacheRequestType type, Time time)
|
void CacheRecorder::addRecord(NodeID id, const Address& data_addr, const Address& pc_addr, CacheRequestType type, Time time)
|
||||||
{
|
{
|
||||||
m_records_ptr->insert(TraceRecord(id, data_addr, pc_addr, type, time));
|
std::cout << __FILE__ << "(" << __LINE__ << "): Not implemented" << std::endl;
|
||||||
|
// m_records_ptr->insert(TraceRecord(id, data_addr, pc_addr, type, time));
|
||||||
}
|
}
|
||||||
|
|
||||||
int CacheRecorder::dumpRecords(string filename)
|
int CacheRecorder::dumpRecords(string filename)
|
||||||
{
|
{
|
||||||
ogzstream out(filename.c_str());
|
std::cout << __FILE__ << "(" << __LINE__ << "): Not implemented" << std::endl;
|
||||||
if (out.fail()) {
|
// ogzstream out(filename.c_str());
|
||||||
cout << "Error: error opening file '" << filename << "'" << endl;
|
// if (out.fail()) {
|
||||||
return 0;
|
// cout << "Error: error opening file '" << filename << "'" << endl;
|
||||||
}
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
int counter = 0;
|
// int counter = 0;
|
||||||
while (m_records_ptr->size() != 0) {
|
// while (m_records_ptr->size() != 0) {
|
||||||
TraceRecord record = m_records_ptr->extractMin();
|
// TraceRecord record = m_records_ptr->extractMin();
|
||||||
record.output(out);
|
// record.output(out);
|
||||||
counter++;
|
// counter++;
|
||||||
}
|
// }
|
||||||
return counter;
|
// return counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CacheRecorder::print(ostream& out) const
|
void CacheRecorder::print(ostream& out) const
|
||||||
{
|
{
|
||||||
|
std::cout << __FILE__ << "(" << __LINE__ << "): Not implemented" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,867 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file has been modified by Kevin Moore and Dan Nussbaum of the
|
|
||||||
Scalable Systems Research Group at Sun Microsystems Laboratories
|
|
||||||
(http://research.sun.com/scalable/) to support the Adaptive
|
|
||||||
Transactional Memory Test Platform (ATMTP).
|
|
||||||
|
|
||||||
Please send email to atmtp-interest@sun.com with feedback, questions, or
|
|
||||||
to request future announcements about ATMTP.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
File modification date: 2008-02-23
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "protocol_name.hh"
|
|
||||||
#include "Global.hh"
|
|
||||||
#include "System.hh"
|
|
||||||
#include "CacheRecorder.hh"
|
|
||||||
//#include "Tracer.hh"
|
|
||||||
#include "RubyConfig.hh"
|
|
||||||
#include "interface.hh"
|
|
||||||
#include "Network.hh"
|
|
||||||
// #include "TransactionInterfaceManager.hh"
|
|
||||||
// #include "TransactionVersionManager.hh"
|
|
||||||
// #include "TransactionIsolationManager.hh"
|
|
||||||
//#include "XactCommitArbiter.hh" // gem5:Arka for decomissioning of log_tm
|
|
||||||
#include "Chip.hh"
|
|
||||||
//#include "XactVisualizer.hh" // gem5:Arka for decomissioning of log_tm
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "commands.hh"
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
#include "ContiguousAddressTranslator.hh"
|
|
||||||
|
|
||||||
/* Declared in interface.C */
|
|
||||||
extern ContiguousAddressTranslator * g_p_ca_translator;
|
|
||||||
|
|
||||||
memory_transaction_t local_memory_transaction_t_shadow;
|
|
||||||
|
|
||||||
#endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
|
|
||||||
//////////////////////// extern "C" api ////////////////////////////////
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ruby_dump_cache(int cpuNumber)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->dumpCaches(cout);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ruby_dump_cache_data(int cpuNumber, char* tag)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
if (tag == NULL) {
|
|
||||||
// No filename, dump to screen
|
|
||||||
g_system_ptr->printConfig(cout);
|
|
||||||
g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->dumpCacheData(cout);
|
|
||||||
} else {
|
|
||||||
// File name, dump to file
|
|
||||||
string filename(tag);
|
|
||||||
|
|
||||||
cout << "Dumping stats to output file '" << filename << "'..." << endl;
|
|
||||||
ofstream m_outputFile;
|
|
||||||
m_outputFile.open(filename.c_str());
|
|
||||||
if(m_outputFile == NULL){
|
|
||||||
cout << endl << "Error: error opening output file '" << filename << "'" << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_system_ptr->getChip(cpuNumber/RubyConfig::numberOfProcsPerChip())->dumpCacheData(m_outputFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ruby_set_periodic_stats_file(char* filename)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
g_system_ptr->getProfiler()->setPeriodicStatsFile(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ruby_set_periodic_stats_interval(int interval)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
g_system_ptr->getProfiler()->setPeriodicStatsInterval(interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
int mh_memorytracer_possible_cache_miss(memory_transaction_t *mem_trans)
|
|
||||||
{
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
memory_transaction_t *p_mem_trans_shadow = mem_trans;
|
|
||||||
|
|
||||||
#ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
if(g_p_ca_translator!=NULL) {
|
|
||||||
memcpy( &local_memory_transaction_t_shadow, mem_trans, sizeof(memory_transaction_t) );
|
|
||||||
p_mem_trans_shadow = &local_memory_transaction_t_shadow;
|
|
||||||
uint64 contiguous_address = g_p_ca_translator->TranslateSimicsToRuby( p_mem_trans_shadow->s.physical_address );
|
|
||||||
p_mem_trans_shadow->s.physical_address = contiguous_address;
|
|
||||||
}
|
|
||||||
#endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
|
|
||||||
|
|
||||||
// Pass this request off to SimicsDriver::makeRequest()
|
|
||||||
// SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
// return simics_interface_ptr->makeRequest(p_mem_trans_shadow);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void mh_memorytracer_observe_memory(memory_transaction_t *mem_trans)
|
|
||||||
{
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
memory_transaction_t *p_mem_trans_shadow = mem_trans;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
if(g_p_ca_translator!=NULL) {
|
|
||||||
memcpy( &local_memory_transaction_t_shadow, mem_trans, sizeof(memory_transaction_t) );
|
|
||||||
p_mem_trans_shadow = &local_memory_transaction_t_shadow;
|
|
||||||
uint64 contiguous_address = g_p_ca_translator->TranslateSimicsToRuby( p_mem_trans_shadow->s.physical_address );
|
|
||||||
p_mem_trans_shadow->s.physical_address = contiguous_address;
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
|
|
||||||
|
|
||||||
// Pass this request off to SimicsDriver::makeRequest()
|
|
||||||
//SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
//simics_interface_ptr->observeMemoryAccess(p_mem_trans_shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ruby_set_g3_reg(void *cpu, void *parameter){
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
int proc_num = SIM_get_proc_no(cpu);
|
|
||||||
sparc_v9_interface_t * m_v9_interface = (sparc_v9_interface_t *) SIM_get_interface(cpu, SPARC_V9_INTERFACE);
|
|
||||||
|
|
||||||
for(int set=0; set < 4; set++) {
|
|
||||||
for(int i=0; i <8; i++) {
|
|
||||||
int registerNumber = i;
|
|
||||||
uinteger_t value = m_v9_interface->read_global_register((void *)cpu, set, registerNumber);
|
|
||||||
cout << "ruby_set_g3_reg BEFORE: proc =" << proc_num << " GSET = " << set << " GLOBAL_REG = " << i << " VALUE = " << value << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uinteger_t value_ptr = (uinteger_t) parameter;
|
|
||||||
int g3_regnum = SIM_get_register_number(cpu, "g3");
|
|
||||||
SIM_write_register(cpu, g3_regnum, (uinteger_t) value_ptr);
|
|
||||||
|
|
||||||
cout << endl;
|
|
||||||
for(int set=0; set < 4; set++) {
|
|
||||||
for(int i=0; i <8; i++) {
|
|
||||||
int registerNumber = i;
|
|
||||||
uinteger_t value = m_v9_interface->read_global_register((void *)cpu, set, registerNumber);
|
|
||||||
cout << "ruby_set_g3_reg AFTER: proc =" << proc_num << " GSET = " << set << " GLOBAL_REG = " << i << " VALUE = " << value << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// #define XACT_MGR g_system_ptr->getChip(SIMICS_current_processor_number()/RubyConfig::numberOfProcsPerChip()/RubyConfig::numberofSMTThreads())->getTransactionInterfaceManager( (SIMICS_current_processor_number()/RubyConfig::numberofSMTThreads())%RubyConfig::numberOfProcsPerChip())
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void magic_instruction_callback(void* desc, void* cpu, integer_t val)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
// Use magic callbacks to start and end transactions w/o opal
|
|
||||||
if (val > 0x10000) // older magic call numbers. Need to be right-shifted.
|
|
||||||
val = val >> 16;
|
|
||||||
int id = -1;
|
|
||||||
int proc_num = SIMICS_current_processor_number();
|
|
||||||
int sim_proc_num = proc_num / RubyConfig::numberofSMTThreads();
|
|
||||||
int thread_num = proc_num % RubyConfig::numberofSMTThreads();
|
|
||||||
int ruby_cycle = g_eventQueue_ptr->getTime();
|
|
||||||
|
|
||||||
if(proc_num < 0){
|
|
||||||
cout << "ERROR proc_num= " << proc_num << endl;
|
|
||||||
}
|
|
||||||
assert(proc_num >= 0);
|
|
||||||
if(thread_num < 0){
|
|
||||||
cout << "ERROR thread_num= " << thread_num << endl;
|
|
||||||
}
|
|
||||||
assert(thread_num >= 0);
|
|
||||||
if( sim_proc_num < 0){
|
|
||||||
cout << "ERROR sim_proc_num = " << sim_proc_num << endl;
|
|
||||||
}
|
|
||||||
assert(sim_proc_num >= 0);
|
|
||||||
|
|
||||||
if (val == 3) {
|
|
||||||
g_system_ptr->getProfiler()->startTransaction(sim_proc_num);
|
|
||||||
} else if (val == 4) {
|
|
||||||
; // magic breakpoint
|
|
||||||
} else if (val == 5) {
|
|
||||||
g_system_ptr->getProfiler()->endTransaction(sim_proc_num);
|
|
||||||
} else if (val == 6){ // Begin Exposed Action
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Begin exposed action for thread " << thread_num << " of proc " << proc_num << " PC " << SIMICS_get_program_counter(proc_num) << endl;
|
|
||||||
XACT_MGR->beginEscapeAction(thread_num);
|
|
||||||
} else if (val == 7){ // Begin Exposed Action
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "End exposed action for thread " << thread_num << " of proc " << proc_num << " PC " << SIMICS_get_program_counter(proc_num) << endl;
|
|
||||||
XACT_MGR->endEscapeAction(thread_num);
|
|
||||||
} else if (val == 8) {
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Set log Base Address for thread " << thread_num << " of proc " << proc_num << endl;
|
|
||||||
XACT_MGR->setLogBase(thread_num);
|
|
||||||
} else if (val == 9) {
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Setting Handler Address for thread " << thread_num << " of proc " << proc_num << endl;
|
|
||||||
XACT_MGR->setHandlerAddress(thread_num);
|
|
||||||
} else if (val == 10) {
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Release Isolation for thread " << thread_num << " of proc " << proc_num << endl;
|
|
||||||
XACT_MGR->releaseIsolation(thread_num);
|
|
||||||
} else if (val == 11) {
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Restart transaction for thread " << thread_num << " of proc " << proc_num << endl;
|
|
||||||
XACT_MGR->restartTransaction(thread_num);
|
|
||||||
} else if (val == 12) {
|
|
||||||
// NOTE: this is a functional magic call for the Java VM
|
|
||||||
// It is used by mfacet.py to check whether to use TM macros or JVM locking
|
|
||||||
return;
|
|
||||||
} else if (val == 13) {
|
|
||||||
// NOTE: this is a debug magic call for the Java VM
|
|
||||||
// Indicates BEGIN XACT
|
|
||||||
return;
|
|
||||||
} else if (val == 14) {
|
|
||||||
// NOTE: this is a debug magic call for the Java VM
|
|
||||||
// Indicates COMMIT_XACT
|
|
||||||
return;
|
|
||||||
} else if (val == 15) {
|
|
||||||
cout << "SIMICS SEG FAULT for thread " << thread_num << " of proc " << proc_num << endl;
|
|
||||||
SIM_break_simulation("SIMICS SEG FAULT");
|
|
||||||
return;
|
|
||||||
} else if (val == 16) {
|
|
||||||
// NOTE : this is a debug magic call for the Java VM
|
|
||||||
// Indicates LOCKING object
|
|
||||||
return;
|
|
||||||
} else if (val == 17) {
|
|
||||||
// NOTE : this is a debug magic call for the Java VM
|
|
||||||
// Indicates UNLOCKING object
|
|
||||||
return;
|
|
||||||
} else if (val == 18) {
|
|
||||||
// NOTE: this is a magic call to enable the xact mem macros in the Java VM
|
|
||||||
// The functionality is implemented in gen-scripts/mfacet.py because it can be independent of Ruby
|
|
||||||
return;
|
|
||||||
} else if (val == 19){
|
|
||||||
cout << "RUBY WATCH: " << endl;
|
|
||||||
g_system_ptr->getProfiler()->rubyWatch(SIMICS_current_processor_number());
|
|
||||||
} else if (val == 20) {
|
|
||||||
//XACT_MGR->setJavaPtrs(thread_num);
|
|
||||||
} else if (val == 21){
|
|
||||||
// NOTE : this is a debug magic call used to dump the registers for a processor
|
|
||||||
// Functionality is implemented in gen-scripts/mfacet.py because it can be independent of Ruby
|
|
||||||
return;
|
|
||||||
} else if (val == 23){
|
|
||||||
// register compensating action
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << proc_num << "," << thread_num << " REGISTER COMPENSATING ACTION " << endl;
|
|
||||||
XACT_MGR->registerCompensatingAction(thread_num);
|
|
||||||
} else if (val == 24){
|
|
||||||
// register commit action
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << proc_num << "," << thread_num << " REGISTER COMMIT ACTION " << endl;
|
|
||||||
XACT_MGR->registerCommitAction(thread_num);
|
|
||||||
} else if (val == 27){
|
|
||||||
// xmalloc
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << proc_num << "," << thread_num << " XMALLOC " << endl;
|
|
||||||
XACT_MGR->xmalloc(thread_num);
|
|
||||||
} else if (val == 29){
|
|
||||||
// Begin Barrier
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << proc_num << "," << thread_num << " BEGIN BARRIER " << endl;
|
|
||||||
g_system_ptr->getXactVisualizer()->moveToBarrier(proc_num);
|
|
||||||
} else if (val == 30){
|
|
||||||
// End Barrier
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << proc_num << "," << thread_num << " END BARRIER " << endl;
|
|
||||||
g_system_ptr->getXactVisualizer()->moveToNonXact(proc_num);
|
|
||||||
} else if (val == 28) {
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Continue execution for thread " << thread_num << " of proc " << proc_num << endl;
|
|
||||||
XACT_MGR->continueExecution(thread_num);
|
|
||||||
} else if (val == 31){
|
|
||||||
// Begin Timer
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << proc_num << "," << thread_num << " BEGIN TIMER " << endl;
|
|
||||||
g_system_ptr->getProfiler()->getXactProfiler()->profileBeginTimer(proc_num);
|
|
||||||
} else if (val == 32){
|
|
||||||
// End Timer
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << proc_num << "," << thread_num << " END TIMER " << endl;
|
|
||||||
g_system_ptr->getProfiler()->getXactProfiler()->profileEndTimer(proc_num);
|
|
||||||
} else if (val == 40) {
|
|
||||||
// register a thread for virtualization
|
|
||||||
if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
|
|
||||||
SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
simics_interface_ptr->getHypervisor()->registerThreadWithHypervisor(proc_num);
|
|
||||||
}
|
|
||||||
} else if (val == 41) {
|
|
||||||
// get information about the last summary conflict
|
|
||||||
if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
|
|
||||||
Address addr = XACT_MGR->getXactIsolationManager()->getSummaryConflictAddress();
|
|
||||||
unsigned int conflictAddress = addr.getAddress();
|
|
||||||
unsigned int conflictType = XACT_MGR->getXactIsolationManager()->getSummaryConflictType();
|
|
||||||
SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g2"), conflictAddress);
|
|
||||||
SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g3"), conflictType);
|
|
||||||
}
|
|
||||||
} else if (val == 42) {
|
|
||||||
// resolve summary conflict magic callback
|
|
||||||
if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
|
|
||||||
SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
simics_interface_ptr->getHypervisor()->resolveSummarySignatureConflict(proc_num);
|
|
||||||
}
|
|
||||||
} else if (val == 50) {
|
|
||||||
// set summary signature bit
|
|
||||||
int index = SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2"));
|
|
||||||
XACT_MGR->writeBitSummaryWriteSetFilter(thread_num, index, 1);
|
|
||||||
} else if (val == 51) {
|
|
||||||
// unset summary signature bit
|
|
||||||
int index = SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2"));
|
|
||||||
XACT_MGR->writeBitSummaryWriteSetFilter(thread_num, index, 0);
|
|
||||||
} else if (val == 52) {
|
|
||||||
// add address in summary signature
|
|
||||||
Address addr = Address(SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2")));
|
|
||||||
cout << "Add to summary write set filter: " << addr << endl;
|
|
||||||
XACT_MGR->addToSummaryWriteSetFilter(thread_num, addr);
|
|
||||||
} else if (val == 53) {
|
|
||||||
// remove address from summary signature
|
|
||||||
Address addr = Address(SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2")));
|
|
||||||
XACT_MGR->removeFromSummaryWriteSetFilter(thread_num, addr);
|
|
||||||
} else if (val == 54) {
|
|
||||||
// translate address to summary signature index
|
|
||||||
Address addr = Address(SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2")));
|
|
||||||
SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g3"), XACT_MGR->getIndexSummaryFilter(thread_num, addr));
|
|
||||||
} else if (val == 55) {
|
|
||||||
XACT_MGR->setIgnoreWatchpointFlag(thread_num, true);
|
|
||||||
} else if (val == 56) {
|
|
||||||
g_system_ptr->getProfiler()->watchpointsFalsePositiveTrigger();
|
|
||||||
} else if (val == 57) {
|
|
||||||
g_system_ptr->getProfiler()->watchpointsTrueTrigger();
|
|
||||||
} else if (val == 60) {
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2) {
|
|
||||||
cout << "Set restorePC for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
|
|
||||||
}
|
|
||||||
unsigned int pc = SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "g2"));
|
|
||||||
XACT_MGR->setRestorePC(thread_num, pc);
|
|
||||||
} else if (val == 61) {
|
|
||||||
// get log size
|
|
||||||
SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g2"), XACT_MGR->getXactVersionManager()->getLogSize(thread_num));
|
|
||||||
} else if (val == 62) {
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2){
|
|
||||||
cout << " GET THREAD ID " << thread_num << " of proc " << proc_num << " TID " << XACT_MGR->getTID(thread_num) << endl;
|
|
||||||
}
|
|
||||||
// get thread id
|
|
||||||
SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "g2"), XACT_MGR->getTID(thread_num));
|
|
||||||
} else if (val == 100) {
|
|
||||||
dump_registers((void*)cpu);
|
|
||||||
} else if (val >= 1024 && val < 2048) {
|
|
||||||
// begin closed
|
|
||||||
id = val - 1024;
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Begin CLOSED transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
|
|
||||||
XACT_MGR->beginTransaction(thread_num, id, false);
|
|
||||||
//} else if (val >= min_closed_commit && val < XACT_OPEN_MIN_ID) {
|
|
||||||
} else if (val >= 2048 && val < 3072) {
|
|
||||||
// commit closed
|
|
||||||
id = val - 2048;
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Commit CLOSED transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
|
|
||||||
XACT_MGR->commitTransaction(thread_num, id, false);
|
|
||||||
} else if (val >= 3072 && val < 4096) {
|
|
||||||
// begin open
|
|
||||||
id = val - 3072;
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "Begin OPEN transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
|
|
||||||
XACT_MGR->beginTransaction(thread_num, id, true);
|
|
||||||
} else if (val >= 4096 && val < 5120) {
|
|
||||||
// commit open
|
|
||||||
id = val - 4096;
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "COMMIT OPEN transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
|
|
||||||
XACT_MGR->commitTransaction(thread_num, id, true);
|
|
||||||
} else if (val >= 5120 && val < 6144){
|
|
||||||
|
|
||||||
cout << " SYSCALL " << val - 5120 << " of proc " << proc_num << " " << thread_num << " time = " << ruby_cycle << endl;
|
|
||||||
} else if (val >= 6144 && val < 7168) {
|
|
||||||
// commit open
|
|
||||||
id = val - 6144;
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2)
|
|
||||||
cout << "ABORT transaction for thread " << thread_num << " of proc " << proc_num << " XID " << id << endl;
|
|
||||||
XACT_MGR->abortTransaction(thread_num, id);
|
|
||||||
} else if (val == 8000) {
|
|
||||||
// transaction level
|
|
||||||
if (XACT_DEBUG && XACT_DEBUG_LEVEL > 2) {
|
|
||||||
id = val - 8000;
|
|
||||||
cout << "Transaction Level for thread " << thread_num << " of proc " << proc_num << " XID " << id << " : "
|
|
||||||
<< XACT_MGR->getTransactionLevel(thread_num)<< endl;
|
|
||||||
}
|
|
||||||
SIMICS_write_register(proc_num, SIMICS_get_register_number(proc_num, "i0"),(unsigned int) XACT_MGR->getTransactionLevel(thread_num));
|
|
||||||
} else if (val==8001) {
|
|
||||||
cout << " " << g_eventQueue_ptr->getTime() << " " << dec << proc_num << " [" << proc_num << "," << thread_num << " ]"
|
|
||||||
<< " TID " << XACT_MGR->getTID(0)
|
|
||||||
<< " DEBUGMSG " << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i0")) << " "
|
|
||||||
<< SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i1")) << " "
|
|
||||||
<< "(0x" << hex << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i1")) << ") "
|
|
||||||
<< dec << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i2")) << " "
|
|
||||||
<< "(0x" << hex << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i2")) << ")" << dec
|
|
||||||
<< " break = " << SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i3")) << endl;
|
|
||||||
if (SIMICS_read_register(proc_num, SIMICS_get_register_number(proc_num, "i3")) == 1) {
|
|
||||||
SIM_break_simulation("DEBUGMSG");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
WARN_EXPR(val);
|
|
||||||
WARN_EXPR(SIMICS_get_program_counter(proc_num));
|
|
||||||
WARN_MSG("Unexpected magic call");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Handle command to change the debugging verbosity for Ruby */
|
|
||||||
extern "C"
|
|
||||||
void ruby_change_debug_verbosity(char* new_verbosity_str)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
g_debug_ptr->setVerbosityString(new_verbosity_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Handle command to change the debugging filter for Ruby */
|
|
||||||
extern "C"
|
|
||||||
void ruby_change_debug_filter(char* new_filter_str)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
g_debug_ptr->setFilterString(new_filter_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Handle command to set the debugging output file for Ruby */
|
|
||||||
extern "C"
|
|
||||||
void ruby_set_debug_output_file (const char * new_filename)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
string filename(new_filename);
|
|
||||||
|
|
||||||
filename += "-";
|
|
||||||
filename += CURRENT_PROTOCOL;
|
|
||||||
// get the date and time to label the debugging file
|
|
||||||
const time_t T = time(NULL);
|
|
||||||
tm *localTime = localtime(&T);
|
|
||||||
char buf[100];
|
|
||||||
strftime(buf, 100, ".%b%d.%Y-%H.%M.%S", localTime);
|
|
||||||
|
|
||||||
filename += buf;
|
|
||||||
filename += ".debug";
|
|
||||||
|
|
||||||
cout << "Dumping debugging output to file '" << filename << "'...";
|
|
||||||
g_debug_ptr->setDebugOutputFile (filename.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ruby_set_debug_start_time(char* start_time_str)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
int startTime = atoi(start_time_str);
|
|
||||||
g_debug_ptr->setDebugTime(startTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Clear stats */
|
|
||||||
extern "C"
|
|
||||||
void ruby_clear_stats()
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
cout << "Clearing stats...";
|
|
||||||
fflush(stdout);
|
|
||||||
g_system_ptr->clearStats();
|
|
||||||
cout << "Done." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Dump stats */
|
|
||||||
extern "C"
|
|
||||||
// File name, dump to file
|
|
||||||
void ruby_dump_stats(char* filename)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
/*g_debug_ptr->closeDebugOutputFile();*/
|
|
||||||
if (filename == NULL) {
|
|
||||||
// No output file, dump to screen
|
|
||||||
cout << "Dumping stats to standard output..." << endl;
|
|
||||||
g_system_ptr->printConfig(cout);
|
|
||||||
g_system_ptr->printStats(cout);
|
|
||||||
} else {
|
|
||||||
cout << "Dumping stats to output file '" << filename << "'..." << endl;
|
|
||||||
ofstream m_outputFile;
|
|
||||||
m_outputFile.open(filename);
|
|
||||||
if(m_outputFile == NULL) {
|
|
||||||
cout << "Error: error opening output file '" << filename << "'" << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_system_ptr->printConfig(m_outputFile);
|
|
||||||
g_system_ptr->printStats(m_outputFile);
|
|
||||||
}
|
|
||||||
cout << "Dumping stats completed." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Dump stats */
|
|
||||||
extern "C"
|
|
||||||
// File name, dump to file
|
|
||||||
void ruby_dump_short_stats(char* filename)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
g_debug_ptr->closeDebugOutputFile();
|
|
||||||
if (filename == NULL) {
|
|
||||||
// No output file, dump to screen
|
|
||||||
//cout << "Dumping short stats to standard output..." << endl;
|
|
||||||
//g_system_ptr->printConfig(cout);
|
|
||||||
g_system_ptr->getProfiler()->printStats(cout, true);
|
|
||||||
} else {
|
|
||||||
cout << "Dumping stats to output file '" << filename << "'..." << endl;
|
|
||||||
ofstream m_outputFile;
|
|
||||||
m_outputFile.open(filename);
|
|
||||||
if(m_outputFile == NULL) {
|
|
||||||
cout << "Error: error opening output file '" << filename << "'" << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_system_ptr->getProfiler()->printShortStats(m_outputFile);
|
|
||||||
cout << "Dumping stats completed." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ruby_load_caches(char* name)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
if (name == NULL) {
|
|
||||||
cout << "Error: ruby_load_caches requires a file name" << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "Reading cache contents from '" << name << "'...";
|
|
||||||
/* gem5:Binkert for decomissiong of tracer
|
|
||||||
int read = Tracer::playbackTrace(name);
|
|
||||||
cout << "done. (" << read << " cache lines read)" << endl;
|
|
||||||
*/
|
|
||||||
cout << "done. (TRACER DISABLED!)" << endl;
|
|
||||||
ruby_clear_stats();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ruby_save_caches(char* name)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
if (name == NULL) {
|
|
||||||
cout << "Error: ruby_save_caches requires a file name" << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "Writing cache contents to '" << name << "'...";
|
|
||||||
CacheRecorder recorder;
|
|
||||||
g_system_ptr->recordCacheContents(recorder);
|
|
||||||
int written = recorder.dumpRecords(name);
|
|
||||||
cout << "done. (" << written << " cache lines written)" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ruby_set_tracer_output_file (const char * new_filename)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
//g_system_ptr->getTracer()->startTrace(string(new_filename));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Handle command to set the xact visualizer file for Ruby */
|
|
||||||
extern "C"
|
|
||||||
void ruby_xact_visualizer_file (char * new_filename)
|
|
||||||
{
|
|
||||||
cout << "Dumping xact visualizer output to file '" << new_filename << "'...";
|
|
||||||
// g_system_ptr->getProfiler()->setXactVisualizerFile (new_filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ctrl_exception_start(void* desc, void* cpu, integer_t val)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
int proc_no = SIM_get_proc_no((void*) cpu);
|
|
||||||
void* cpu_obj = (void*) cpu;
|
|
||||||
uinteger_t trap_level = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tl"));
|
|
||||||
|
|
||||||
if (!XACT_MEMORY) return;
|
|
||||||
TransactionInterfaceManager *xact_mgr = XACT_MGR;
|
|
||||||
|
|
||||||
// level {10,14} interrupt
|
|
||||||
//
|
|
||||||
if (val == 0x4a || val == 0x4e) {
|
|
||||||
int rn_tick = SIM_get_register_number(cpu_obj, "tick");
|
|
||||||
uinteger_t tick = SIM_read_register(cpu_obj, rn_tick);
|
|
||||||
int rn_tick_cmpr = SIM_get_register_number(cpu_obj, "tick_cmpr");
|
|
||||||
uinteger_t tick_cmpr = SIM_read_register(cpu_obj, rn_tick_cmpr);
|
|
||||||
int rn_stick = SIM_get_register_number(cpu_obj, "stick");
|
|
||||||
uinteger_t stick = SIM_read_register(cpu_obj, rn_stick);
|
|
||||||
int rn_stick_cmpr = SIM_get_register_number(cpu_obj, "stick_cmpr");
|
|
||||||
uinteger_t stick_cmpr = SIM_read_register(cpu_obj, rn_stick_cmpr);
|
|
||||||
int rn_pc = SIM_get_register_number(cpu_obj, "pc");
|
|
||||||
uinteger_t pc = SIM_read_register(cpu_obj, rn_pc);
|
|
||||||
int rn_npc = SIM_get_register_number(cpu_obj, "npc");
|
|
||||||
uinteger_t npc = SIM_read_register(cpu_obj, rn_npc);
|
|
||||||
int rn_pstate = SIM_get_register_number(cpu_obj, "pstate");
|
|
||||||
uinteger_t pstate = SIM_read_register(cpu_obj, rn_pstate);
|
|
||||||
int rn_pil = SIM_get_register_number(cpu_obj, "pil");
|
|
||||||
int pil = SIM_read_register(cpu_obj, rn_pil);
|
|
||||||
g_system_ptr->getProfiler()->profileTimerInterrupt(proc_no,
|
|
||||||
tick, tick_cmpr,
|
|
||||||
stick, stick_cmpr,
|
|
||||||
trap_level,
|
|
||||||
pc, npc,
|
|
||||||
pstate, pil);
|
|
||||||
}
|
|
||||||
|
|
||||||
int smt_thread_num = proc_no % RubyConfig::numberofSMTThreads();
|
|
||||||
// The simulated processor number
|
|
||||||
int sim_proc_no = proc_no / RubyConfig::numberofSMTThreads();
|
|
||||||
|
|
||||||
uinteger_t pc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "pc"));
|
|
||||||
uinteger_t npc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "npc"));
|
|
||||||
|
|
||||||
g_system_ptr->getProfiler()->profileExceptionStart(xact_mgr->getTransactionLevel(smt_thread_num) > 0, sim_proc_no, smt_thread_num, val, trap_level, pc, npc);
|
|
||||||
|
|
||||||
if((val >= 0x80 && val <= 0x9f) || (val >= 0xc0 && val <= 0xdf)){
|
|
||||||
//xact_mgr->setLoggedException(smt_thread_num);
|
|
||||||
}
|
|
||||||
// CORNER CASE - You take an exception while stalling for a commit token
|
|
||||||
if (XACT_LAZY_VM && !XACT_EAGER_CD){
|
|
||||||
if (g_system_ptr->getXactCommitArbiter()->getTokenOwner() == proc_no)
|
|
||||||
g_system_ptr->getXactCommitArbiter()->releaseCommitToken(proc_no);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void ctrl_exception_done(void* desc, void* cpu, integer_t val)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
int proc_no = SIM_get_proc_no((void*) cpu);
|
|
||||||
void* cpu_obj = (void*) cpu;
|
|
||||||
uinteger_t trap_level = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tl"));
|
|
||||||
uinteger_t pc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "pc"));
|
|
||||||
uinteger_t npc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "npc"));
|
|
||||||
uinteger_t tpc = 0;
|
|
||||||
uinteger_t tnpc = 0;
|
|
||||||
//get the return PC,NPC pair based on the trap level
|
|
||||||
ASSERT(1 <= trap_level && trap_level <= 5);
|
|
||||||
if(trap_level == 1){
|
|
||||||
tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc1"));
|
|
||||||
tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc1"));
|
|
||||||
}
|
|
||||||
if(trap_level == 2){
|
|
||||||
tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc2"));
|
|
||||||
tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc2"));
|
|
||||||
}
|
|
||||||
if(trap_level == 3){
|
|
||||||
tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc3"));
|
|
||||||
tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc3"));
|
|
||||||
}
|
|
||||||
if(trap_level == 4){
|
|
||||||
tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc4"));
|
|
||||||
tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc4"));
|
|
||||||
}
|
|
||||||
if(trap_level == 5){
|
|
||||||
tpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tpc5"));
|
|
||||||
tnpc = SIM_read_register(cpu_obj, SIM_get_register_number(cpu_obj, "tnpc5"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!XACT_MEMORY) return;
|
|
||||||
TransactionInterfaceManager *xact_mgr = XACT_MGR;
|
|
||||||
|
|
||||||
int smt_thread_num = proc_no % RubyConfig::numberofSMTThreads();
|
|
||||||
// The simulated processor number
|
|
||||||
int sim_proc_no = proc_no / RubyConfig::numberofSMTThreads();
|
|
||||||
|
|
||||||
if (proc_no != SIMICS_current_processor_number()){
|
|
||||||
WARN_EXPR(proc_no);
|
|
||||||
WARN_EXPR(SIMICS_current_processor_number());
|
|
||||||
WARN_MSG("Callback for a different processor");
|
|
||||||
}
|
|
||||||
|
|
||||||
g_system_ptr->getProfiler()->profileExceptionDone(xact_mgr->getTransactionLevel(smt_thread_num) > 0, sim_proc_no, smt_thread_num, val, trap_level, pc, npc, tpc, tnpc);
|
|
||||||
|
|
||||||
if((val >= 0x80 && val <= 0x9f) || (val >= 0xc0 && val <= 0xdf)){
|
|
||||||
//xact_mgr->clearLoggedException(smt_thread_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((val == 0x122) && xact_mgr->shouldTrap(smt_thread_num)){
|
|
||||||
// use software handler
|
|
||||||
if (xact_mgr->shouldUseHardwareAbort(smt_thread_num)){
|
|
||||||
xact_mgr->hardwareAbort(smt_thread_num);
|
|
||||||
} else {
|
|
||||||
xact_mgr->trapToHandler(smt_thread_num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void change_mode_callback(void* desc, void* cpu, integer_t old_mode, integer_t new_mode)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
|
|
||||||
SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
simics_interface_ptr->getHypervisor()->change_mode_callback(desc, cpu, old_mode, new_mode);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void dtlb_map_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg){
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
|
|
||||||
SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
simics_interface_ptr->getHypervisor()->dtlb_map_callback(desc, chmmu, tag_reg, data_reg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void dtlb_demap_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg){
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
|
|
||||||
SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
simics_interface_ptr->getHypervisor()->dtlb_demap_callback(desc, chmmu, tag_reg, data_reg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void dtlb_replace_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg){
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
|
|
||||||
SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
simics_interface_ptr->getHypervisor()->dtlb_replace_callback(desc, chmmu, tag_reg, data_reg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void dtlb_overwrite_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg){
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
if (XACT_ENABLE_VIRTUALIZATION_LOGTM_SE) {
|
|
||||||
SimicsDriver* simics_interface_ptr = static_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
simics_interface_ptr->getHypervisor()->dtlb_overwrite_callback(desc, chmmu, tag_reg, data_reg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void core_control_register_write_callback(void* desc, void* cpu, integer_t register_number, integer_t value) {
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
int proc_no = SIM_get_proc_no((void*) cpu);
|
|
||||||
void* cpu_obj = (void*) cpu;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
integer_t
|
|
||||||
read_reg(void *cpu, const char* reg_name)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
int reg_num = SIM_get_register_number(SIM_current_processor(), reg_name);
|
|
||||||
if (SIM_clear_exception()) {
|
|
||||||
fprintf(stderr, "read_reg: SIM_get_register_number(%s, %s) failed!\n",
|
|
||||||
cpu->name, reg_name);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
integer_t val = SIM_read_register(cpu, reg_num);
|
|
||||||
if (SIM_clear_exception()) {
|
|
||||||
fprintf(stderr, "read_reg: SIM_read_register(%s, %d) failed!\n",
|
|
||||||
cpu->name, reg_num);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
void dump_registers(void *cpu)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
#if 0
|
|
||||||
const char* reg_names[] = {
|
|
||||||
"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
|
||||||
"i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
|
|
||||||
"l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
|
|
||||||
"o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
|
|
||||||
"ccr", "pc", "npc"
|
|
||||||
};
|
|
||||||
|
|
||||||
printf("Registers for %s\n", cpu->name);
|
|
||||||
printf("------------------\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < (sizeof(reg_names) / sizeof(char*)); i++) {
|
|
||||||
const char* reg_name = reg_names[i];
|
|
||||||
printf(" %3s: 0x%016llx\n", reg_name, read_reg(cpu, reg_name));
|
|
||||||
if (i % 8 == 7) {
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int myID = SIMICS_get_proc_no(cpu);
|
|
||||||
Address myPC = SIMICS_get_program_counter(myID);
|
|
||||||
physical_address_t myPhysPC = SIMICS_translate_address(myID, myPC);
|
|
||||||
integer_t myInst = SIMICS_read_physical_memory(myID, myPhysPC, 4);
|
|
||||||
const char *myInstStr = SIMICS_disassemble_physical(myID, myPhysPC);
|
|
||||||
printf("\n *pc: 0x%llx: %s\n", myInst, myInstStr);
|
|
||||||
|
|
||||||
printf("\n\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,106 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file has been modified by Kevin Moore and Dan Nussbaum of the
|
|
||||||
Scalable Systems Research Group at Sun Microsystems Laboratories
|
|
||||||
(http://research.sun.com/scalable/) to support the Adaptive
|
|
||||||
Transactional Memory Test Platform (ATMTP).
|
|
||||||
|
|
||||||
Please send email to atmtp-interest@sun.com with feedback, questions, or
|
|
||||||
to request future announcements about ATMTP.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
File modification date: 2008-02-23
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef COMMANDS_H
|
|
||||||
#define COMMANDS_H
|
|
||||||
|
|
||||||
#ifdef SPARC
|
|
||||||
#define MEMORY_TRANSACTION_TYPE void
|
|
||||||
#else
|
|
||||||
#define MEMORY_TRANSACTION_TYPE void
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int mh_memorytracer_possible_cache_miss(MEMORY_TRANSACTION_TYPE *mem_trans);
|
|
||||||
void mh_memorytracer_observe_memory(MEMORY_TRANSACTION_TYPE *mem_trans);
|
|
||||||
|
|
||||||
void magic_instruction_callback(void* desc, void * cpu, integer_t val);
|
|
||||||
|
|
||||||
void ruby_change_debug_verbosity(char* new_verbosity_str);
|
|
||||||
void ruby_change_debug_filter(char* new_filter_str);
|
|
||||||
void ruby_set_debug_output_file (const char * new_filename);
|
|
||||||
void ruby_set_debug_start_time(char* start_time_str);
|
|
||||||
|
|
||||||
void ruby_clear_stats();
|
|
||||||
void ruby_dump_stats(char* tag);
|
|
||||||
void ruby_dump_short_stats(char* tag);
|
|
||||||
|
|
||||||
void ruby_set_periodic_stats_file(char* filename);
|
|
||||||
void ruby_set_periodic_stats_interval(int interval);
|
|
||||||
|
|
||||||
void ruby_load_caches(char* name);
|
|
||||||
void ruby_save_caches(char* name);
|
|
||||||
|
|
||||||
void ruby_dump_cache(int cpuNumber);
|
|
||||||
void ruby_dump_cache_data(int cpuNumber, char *tag);
|
|
||||||
|
|
||||||
void ruby_set_tracer_output_file (const char * new_filename);
|
|
||||||
void ruby_xact_visualizer_file (char * new_filename);
|
|
||||||
|
|
||||||
void ctrl_exception_start(void* desc, void* cpu, integer_t val);
|
|
||||||
void ctrl_exception_done(void* desc, void* cpu, integer_t val);
|
|
||||||
|
|
||||||
void change_mode_callback(void* desc, void* cpu, integer_t old_mode, integer_t new_mode);
|
|
||||||
void dtlb_map_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg);
|
|
||||||
void dtlb_demap_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg);
|
|
||||||
void dtlb_replace_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg);
|
|
||||||
void dtlb_overwrite_callback(void* desc, void* chmmu, integer_t tag_reg, integer_t data_reg);
|
|
||||||
|
|
||||||
integer_t read_reg(void *cpu, const char* reg_name);
|
|
||||||
void dump_registers(void *cpu);
|
|
||||||
|
|
||||||
// Needed so that the ruby module will compile, but functions are
|
|
||||||
// implemented in Rock.C.
|
|
||||||
//
|
|
||||||
void rock_exception_start(void* desc, void* cpu, integer_t val);
|
|
||||||
void rock_exception_done(void* desc, void* cpu, integer_t val);
|
|
||||||
|
|
||||||
#endif //COMMANDS_H
|
|
|
@ -1,935 +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: interface.C 1.39 05/01/19 13:12:31-06:00 mikem@maya.cs.wisc.edu $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Global.hh"
|
|
||||||
#include "System.hh"
|
|
||||||
#include "OpalInterface.hh"
|
|
||||||
#include "RubyEventQueue.hh"
|
|
||||||
#include "mf_api.hh"
|
|
||||||
#include "interface.hh"
|
|
||||||
#include "Sequencer.hh"
|
|
||||||
// #include "TransactionInterfaceManager.hh"
|
|
||||||
|
|
||||||
#ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
#include "ContiguousAddressTranslator.hh"
|
|
||||||
|
|
||||||
/* Also used in init.C, commands.C */
|
|
||||||
ContiguousAddressTranslator * g_p_ca_translator = NULL;
|
|
||||||
|
|
||||||
#endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
|
|
||||||
//////////////////////// Local helper functions //////////////////////
|
|
||||||
|
|
||||||
// Callback when exception occur
|
|
||||||
static void core_exception_callback(void *data, void *cpu,
|
|
||||||
integer_t exc)
|
|
||||||
{
|
|
||||||
// SimicsDriver *simics_intf = dynamic_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
// ASSERT( simics_intf );
|
|
||||||
// simics_intf->exceptionCallback(cpu, exc);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SPARC
|
|
||||||
// Callback when asi accesses occur
|
|
||||||
// static exception_type_t core_asi_callback(void * cpu, generic_transaction_t *g)
|
|
||||||
// {
|
|
||||||
// SimicsDriver *simics_intf = dynamic_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
// assert( simics_intf );
|
|
||||||
// return simics_intf->asiCallback(cpu, g);
|
|
||||||
// }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void runRubyEventQueue(void* obj, void* arg)
|
|
||||||
{
|
|
||||||
Time time = g_eventQueue_ptr->getTime() + 1;
|
|
||||||
DEBUG_EXPR(NODE_COMP, HighPrio, time);
|
|
||||||
g_eventQueue_ptr->triggerEvents(time);
|
|
||||||
// void* obj_ptr = (void*) SIM_proc_no_2_ptr(0); // Maurice
|
|
||||||
// SIM_time_post_cycle(obj_ptr, SIMICS_RUBY_MULTIPLIER, Sim_Sync_Processor, &runRubyEventQueue, NULL); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////// Simics API functions //////////////////////
|
|
||||||
|
|
||||||
int SIMICS_number_processors()
|
|
||||||
{
|
|
||||||
// return SIM_number_processors(); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_wakeup_ruby()
|
|
||||||
{
|
|
||||||
// void* obj_ptr = (void*) SIM_proc_no_2_ptr(0); // Maurice
|
|
||||||
// SIM_time_post_cycle(obj_ptr, SIMICS_RUBY_MULTIPLIER, Sim_Sync_Processor, &runRubyEventQueue, NULL); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// an analogue to wakeup ruby, this function ends the callbacks ruby normally
|
|
||||||
// recieves from simics. (it removes ruby from simics's event queue). This
|
|
||||||
// function should only be called when opal is installed. Opal advances ruby's
|
|
||||||
// event queue independently of simics.
|
|
||||||
void SIMICS_remove_ruby_callback( void )
|
|
||||||
{
|
|
||||||
// void* obj_ptr = (void*) SIM_proc_no_2_ptr(0); // Maurice
|
|
||||||
// SIM_time_clean( obj_ptr, Sim_Sync_Processor, &runRubyEventQueue, NULL); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install ruby as the timing model (analogous code exists in ruby/ruby.c)
|
|
||||||
void SIMICS_install_timing_model( void )
|
|
||||||
{
|
|
||||||
// // void *phys_mem0 = SIM_get_object("phys_mem0"); // Maurice
|
|
||||||
// attr_value_t val;
|
|
||||||
// // val.kind = Sim_Val_String; // Maurice
|
|
||||||
// val.u.string = "ruby0";
|
|
||||||
// set_error_t install_error;
|
|
||||||
//
|
|
||||||
// if(phys_mem0==NULL) {
|
|
||||||
// /* Look for "phys_mem" instead */
|
|
||||||
// // SIM_clear_exception(); // Maurice
|
|
||||||
// // phys_mem0 = SIM_get_object("phys_mem"); // Maurice
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if(phys_mem0==NULL) {
|
|
||||||
// /* Okay, now panic... can't install ruby without a physical memory object */
|
|
||||||
// WARN_MSG( "Cannot Install Ruby... no phys_mem0 or phys_mem object found" );
|
|
||||||
// WARN_MSG( "Ruby is NOT installed." );
|
|
||||||
// // SIM_clear_exception(); // Maurice
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // install_error = SIM_set_attribute(phys_mem0, "timing_model", &val); // Maurice
|
|
||||||
//
|
|
||||||
// // if (install_error == Sim_Set_Ok) { // Maurice
|
|
||||||
// WARN_MSG( "successful installation of the ruby timing model" );
|
|
||||||
// } else {
|
|
||||||
// WARN_MSG( "error installing ruby timing model" );
|
|
||||||
// // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// }
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes ruby as the timing model interface
|
|
||||||
void SIMICS_remove_timing_model( void )
|
|
||||||
{
|
|
||||||
// void *phys_mem0 = SIM_get_object("phys_mem0"); // Maurice
|
|
||||||
// attr_value_t val;
|
|
||||||
// memset( &val, 0, sizeof(attr_value_t) );
|
|
||||||
// // val.kind = Sim_Val_Nil; // Maurice
|
|
||||||
//
|
|
||||||
// if(phys_mem0==NULL) {
|
|
||||||
// /* Look for "phys_mem" instead */
|
|
||||||
// // SIM_clear_exception(); // Maurice
|
|
||||||
// // phys_mem0 = SIM_get_object("phys_mem"); // Maurice
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if(phys_mem0==NULL) {
|
|
||||||
// /* Okay, now panic... can't uninstall ruby without a physical memory object */
|
|
||||||
// WARN_MSG( "Cannot Uninstall Ruby... no phys_mem0 or phys_mem object found" );
|
|
||||||
// WARN_MSG( "Uninstall NOT performed." );
|
|
||||||
// // SIM_clear_exception(); // Maurice
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // SIM_set_attribute(phys_mem0, "timing_model", &val); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Installs the (SimicsDriver) function to recieve the exeception callback
|
|
||||||
void SIMICS_install_exception_callback( void )
|
|
||||||
{
|
|
||||||
// install exception callback
|
|
||||||
// s_exception_hap_handle =
|
|
||||||
// SIM_hap_add_callback("Core_Exception", // Maurice
|
|
||||||
// (obj_hap_func_t)core_exception_callback, NULL );
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// removes the exception callback
|
|
||||||
void SIMICS_remove_exception_callback( void )
|
|
||||||
{
|
|
||||||
// uninstall exception callback
|
|
||||||
// SIM_hap_delete_callback_id( "Core_Exception", // Maurice
|
|
||||||
// s_exception_hap_handle );
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SPARC
|
|
||||||
// Installs the (SimicsDriver) function to recieve the asi callback
|
|
||||||
void SIMICS_install_asi_callback( void )
|
|
||||||
{
|
|
||||||
// for(int i = 0; i < SIM_number_processors(); i++) { // Maurice
|
|
||||||
// sparc_v9_interface_t *v9_interface = (sparc_v9_interface_t *)
|
|
||||||
// SIM_get_interface(SIM_proc_no_2_ptr(i), SPARC_V9_INTERFACE); // Maurice
|
|
||||||
|
|
||||||
// init asi callbacks, 16bit ASI
|
|
||||||
// for(int j = 0; j < MAX_ADDRESS_SPACE_ID; j++) {
|
|
||||||
// v9_interface->install_user_asi_handler(core_asi_callback, j);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// removes the asi callback
|
|
||||||
void SIMICS_remove_asi_callback( void )
|
|
||||||
{
|
|
||||||
// for(int i = 0; i < SIM_number_processors(); i++) { // Maurice
|
|
||||||
// sparc_v9_interface_t *v9_interface = (sparc_v9_interface_t *)
|
|
||||||
// SIM_get_interface(SIM_proc_no_2_ptr(i), SPARC_V9_INTERFACE); // Maurice
|
|
||||||
|
|
||||||
// disable asi callback
|
|
||||||
// for(int j = 0; j < MAX_ADDRESS_SPACE_ID; j++) {
|
|
||||||
// v9_interface->remove_user_asi_handler(core_asi_callback, j);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Query simics for the presence of the opal object.
|
|
||||||
// returns its interface if found, NULL otherwise
|
|
||||||
mf_opal_api_t *SIMICS_get_opal_interface( void )
|
|
||||||
{
|
|
||||||
// void *opal = SIM_get_object("opal0"); // Maurice
|
|
||||||
//if (opal != NULL) {
|
|
||||||
// mf_opal_api_t *opal_intf = (mf_opal_api_t *) SIM_get_interface( opal, "mf-opal-api" ); // Maurice
|
|
||||||
// if ( opal_intf != NULL ) {
|
|
||||||
// return opal_intf;
|
|
||||||
// } else {
|
|
||||||
// WARN_MSG("error: OpalInterface: opal does not implement mf-opal-api interface.\n");
|
|
||||||
// return NULL;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// SIM_clear_exception(); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * SIMICS_current_processor(){
|
|
||||||
// return SIM_current_processor(); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SIMICS_current_processor_number()
|
|
||||||
{
|
|
||||||
// return (SIM_get_proc_no((processor_t *) SIM_current_processor())); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
integer_t SIMICS_get_insn_count(int cpuNumber)
|
|
||||||
{
|
|
||||||
// NOTE: we already pass in the logical cpuNumber (ie Simics simulated cpu number)
|
|
||||||
int num_smt_threads = RubyConfig::numberofSMTThreads();
|
|
||||||
integer_t total_insn = 0;
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// total_insn += SIM_step_count((void*) cpu); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return total_insn;
|
|
||||||
}
|
|
||||||
|
|
||||||
integer_t SIMICS_get_cycle_count(int cpuNumber)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// integer_t result = SIM_cycle_count((void*) cpu); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_unstall_proc(int cpuNumber)
|
|
||||||
{
|
|
||||||
// void* proc_ptr = (void *) SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// SIM_stall_cycle(proc_ptr, 0); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_unstall_proc(int cpuNumber, int cycles)
|
|
||||||
{
|
|
||||||
// void* proc_ptr = (void *) SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// SIM_stall_cycle(proc_ptr, cycles); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_stall_proc(int cpuNumber, int cycles)
|
|
||||||
{
|
|
||||||
// void* proc_ptr = (void*) SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// if (SIM_stalled_until(proc_ptr) != 0){ // Maurice
|
|
||||||
// cout << cpuNumber << " Trying to stall. Stall Count currently at " << SIM_stalled_until(proc_ptr) << endl; // Maurice
|
|
||||||
// }
|
|
||||||
// SIM_stall_cycle(proc_ptr, cycles); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_post_stall_proc(int cpuNumber, int cycles)
|
|
||||||
{
|
|
||||||
// void* proc_ptr = (void*) SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// SIM_stacked_post(proc_ptr, ruby_stall_proc, (void *) cycles); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
integer_t SIMICS_read_physical_memory( int procID, physical_address_t address,
|
|
||||||
int len )
|
|
||||||
{
|
|
||||||
// // SIM_clear_exception(); // Maurice
|
|
||||||
// ASSERT( len <= 8 );
|
|
||||||
// #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// if(g_p_ca_translator != NULL) {
|
|
||||||
// address = g_p_ca_translator->TranslateRubyToSimics( address );
|
|
||||||
// }
|
|
||||||
// #endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// // integer_t result = SIM_read_phys_memory( SIM_proc_no_2_ptr(procID), // Maurice
|
|
||||||
// // // address, len );
|
|
||||||
// //
|
|
||||||
// // // int isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// // if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// // // sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
// // WARN_MSG( "SIMICS_read_physical_memory: raised exception." );
|
|
||||||
// // // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// // WARN_MSG( Address(address) );
|
|
||||||
// // WARN_MSG( procID );
|
|
||||||
// // ASSERT(0);
|
|
||||||
// // }
|
|
||||||
// // return ( result );
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// /*
|
|
||||||
// * Read data into a buffer and assume the buffer is already allocated
|
|
||||||
// */
|
|
||||||
void SIMICS_read_physical_memory_buffer(int procID, physical_address_t addr,
|
|
||||||
char* buffer, int len ) {
|
|
||||||
// // // processor_t* obj = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// //
|
|
||||||
// // assert( obj != NULL);
|
|
||||||
// // assert( buffer != NULL );
|
|
||||||
// //
|
|
||||||
// // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// // if(g_p_ca_translator != NULL) {
|
|
||||||
// // addr = g_p_ca_translator->TranslateRubyToSimics( addr );
|
|
||||||
// // }
|
|
||||||
// // #endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// //
|
|
||||||
// // int buffer_pos = 0;
|
|
||||||
// // physical_address_t start = addr;
|
|
||||||
// // do {
|
|
||||||
// // int size = (len < 8)? len:8;
|
|
||||||
// // // integer_t result = SIM_read_phys_memory( obj, start, size ); // Maurice
|
|
||||||
// // // int isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// // if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// // // sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
// // WARN_MSG( "SIMICS_read_physical_memory_buffer: raised exception." );
|
|
||||||
// // // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// // WARN_MSG( addr );
|
|
||||||
// // WARN_MSG( procID );
|
|
||||||
// // ASSERT( 0 );
|
|
||||||
// // }
|
|
||||||
// //
|
|
||||||
// // #ifdef SPARC
|
|
||||||
// // // assume big endian (i.e. SPARC V9 target)
|
|
||||||
// // for(int i = size-1; i >= 0; i--) {
|
|
||||||
// // #else
|
|
||||||
// // // assume little endian (i.e. x86 target)
|
|
||||||
// // for(int i = 0; i<size; i++) {
|
|
||||||
// // #endif
|
|
||||||
// // buffer[buffer_pos++] = (char) ((result>>(i<<3))&0xff);
|
|
||||||
// // }
|
|
||||||
// //
|
|
||||||
// // len -= size;
|
|
||||||
// // start += size;
|
|
||||||
// // } while(len != 0);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
void SIMICS_write_physical_memory( int procID, physical_address_t address,
|
|
||||||
integer_t value, int len )
|
|
||||||
{
|
|
||||||
// // ASSERT( len <= 8 );
|
|
||||||
// //
|
|
||||||
// // // SIM_clear_exception(); // Maurice
|
|
||||||
// //
|
|
||||||
// // // processor_t* obj = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// //
|
|
||||||
// // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// // if(g_p_ca_translator != NULL) {
|
|
||||||
// // address = g_p_ca_translator->TranslateRubyToSimics( address );
|
|
||||||
// // }
|
|
||||||
// // #endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// //
|
|
||||||
// // // int isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// // if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// // // sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
// // WARN_MSG( "SIMICS_write_physical_memory 1: raised exception." );
|
|
||||||
// // // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// // WARN_MSG( address );
|
|
||||||
// // }
|
|
||||||
// //
|
|
||||||
// // // SIM_write_phys_memory(obj, address, value, len ); // Maurice
|
|
||||||
// //
|
|
||||||
// // // isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// // if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// // // sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
// // WARN_MSG( "SIMICS_write_physical_memory 2: raised exception." );
|
|
||||||
// // // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// // WARN_MSG( address );
|
|
||||||
// // }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// /*
|
|
||||||
// * write data to simics memory from a buffer (assumes the buffer is valid)
|
|
||||||
// */
|
|
||||||
void SIMICS_write_physical_memory_buffer(int procID, physical_address_t addr,
|
|
||||||
char* buffer, int len ) {
|
|
||||||
// // processor_t* obj = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
//
|
|
||||||
// assert( obj != NULL);
|
|
||||||
// assert( buffer != NULL );
|
|
||||||
//
|
|
||||||
// #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// if(g_p_ca_translator != NULL) {
|
|
||||||
// addr = g_p_ca_translator->TranslateRubyToSimics( addr );
|
|
||||||
// }
|
|
||||||
// #endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
//
|
|
||||||
// int buffer_pos = 0;
|
|
||||||
// physical_address_t start = addr;
|
|
||||||
// do {
|
|
||||||
// int size = (len < 8)? len:8;
|
|
||||||
// // //integer_t result = SIM_read_phys_memory( obj, start, size ); // Maurice
|
|
||||||
// integer_t value = 0;
|
|
||||||
// #ifdef SPARC
|
|
||||||
// // assume big endian (i.e. SPARC V9 target)
|
|
||||||
// for(int i = size-1; i >= 0; i--) {
|
|
||||||
// #else
|
|
||||||
// // assume little endian (i.e. x86 target)
|
|
||||||
// for(int i = 0; i<size; i++) {
|
|
||||||
// #endif
|
|
||||||
// integer_t mask = buffer[buffer_pos++];
|
|
||||||
// value |= ((mask)<<(i<<3));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// // SIM_write_phys_memory( obj, start, value, size); // Maurice
|
|
||||||
// // int isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// // sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
// WARN_MSG( "SIMICS_write_physical_memory_buffer: raised exception." );
|
|
||||||
// // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// WARN_MSG( addr );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// len -= size;
|
|
||||||
// start += size;
|
|
||||||
// } while(len != 0);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SIMICS_check_memory_value(int procID, physical_address_t addr,
|
|
||||||
char* buffer, int len) {
|
|
||||||
char buf[len];
|
|
||||||
SIMICS_read_physical_memory_buffer(procID, addr, buf, len);
|
|
||||||
assert(0);
|
|
||||||
return (memcmp(buffer, buf, len) == 0)? true:false;
|
|
||||||
}
|
|
||||||
|
|
||||||
physical_address_t SIMICS_translate_address( int procID, Address address ) {
|
|
||||||
// SIM_clear_exception(); // Maurice
|
|
||||||
// physical_address_t physical_addr = SIM_logical_to_physical(SIM_proc_no_2_ptr(procID), Sim_DI_Instruction, address.getAddress() ); // Maurice
|
|
||||||
// int isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
// /*
|
|
||||||
// WARN_MSG( "SIMICS_translate_address: raised exception." );
|
|
||||||
// WARN_MSG( procID );
|
|
||||||
// WARN_MSG( address );
|
|
||||||
// // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// */
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// if(g_p_ca_translator != NULL) {
|
|
||||||
// physical_addr = g_p_ca_translator->TranslateSimicsToRuby( physical_addr );
|
|
||||||
// }
|
|
||||||
// #endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
//
|
|
||||||
// return physical_addr;
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
physical_address_t SIMICS_translate_data_address( int procID, Address address ) {
|
|
||||||
// SIM_clear_exception(); // Maurice
|
|
||||||
// physical_address_t physical_addr = SIM_logical_to_physical(SIM_proc_no_2_ptr(procID), Sim_DI_Data, address.getAddress() ); // Maurice
|
|
||||||
// int isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
/*
|
|
||||||
WARN_MSG( "SIMICS_translate_data_address: raised exception." );
|
|
||||||
WARN_MSG( procID );
|
|
||||||
WARN_MSG( address );
|
|
||||||
// WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
*/
|
|
||||||
// }
|
|
||||||
// return physical_addr;
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SPARC
|
|
||||||
bool SIMICS_is_ldda(const memory_transaction_t *mem_trans) {
|
|
||||||
// void *cpu = mem_trans->s.ini_ptr;
|
|
||||||
// int proc= SIMICS_get_proc_no(cpu);
|
|
||||||
// Address addr = SIMICS_get_program_counter(cpu);
|
|
||||||
// physical_address_t phys_addr = SIMICS_translate_address( proc, addr );
|
|
||||||
// uint32 instr= SIMICS_read_physical_memory( proc, phys_addr, 4 );
|
|
||||||
//
|
|
||||||
// // determine if this is a "ldda" instruction (non-exclusive atomic)
|
|
||||||
// // ldda bit mask: 1100 0001 1111 1000 == 0xc1f80000
|
|
||||||
// // ldda match : 1100 0000 1001 1000 == 0xc0980000
|
|
||||||
// if ( (instr & 0xc1f80000) == 0xc0980000 ) {
|
|
||||||
// // should exactly be ldda instructions
|
|
||||||
// ASSERT(!strncmp(SIMICS_disassemble_physical(proc, phys_addr), "ldda", 4));
|
|
||||||
// //cout << "SIMICS_is_ldda END" << endl;
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
assert(0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *SIMICS_disassemble_physical( int procID, physical_address_t pa ) {
|
|
||||||
//#ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// if(g_p_ca_translator != NULL) {
|
|
||||||
// pa = g_p_ca_translator->TranslateRubyToSimics( pa );
|
|
||||||
// }
|
|
||||||
//#endif // #ifdef CONTIGUOUS_ADDRESSES
|
|
||||||
// return SIM_disassemble( SIM_proc_no_2_ptr(procID), pa , /* physical */ 0)->string; // Maurice
|
|
||||||
assert(0);
|
|
||||||
return "There is no spoon";
|
|
||||||
}
|
|
||||||
|
|
||||||
Address SIMICS_get_program_counter(void *cpu) {
|
|
||||||
assert(cpu != NULL);
|
|
||||||
// return Address(SIM_get_program_counter((processor_t *) cpu)); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return Address(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Address SIMICS_get_npc(int procID) {
|
|
||||||
// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// return Address(SIM_read_register(cpu, SIM_get_register_number(cpu, "npc"))); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return Address(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Address SIMICS_get_program_counter(int procID) {
|
|
||||||
// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// assert(cpu != NULL);
|
|
||||||
|
|
||||||
// Address addr = Address(SIM_get_program_counter(cpu)); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return Address(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// /* NOTE: SIM_set_program_counter sets NPC to PC+4 */ // Maurice
|
|
||||||
void SIMICS_set_program_counter(int procID, Address newPC) {
|
|
||||||
// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// assert(cpu != NULL);
|
|
||||||
|
|
||||||
// SIM_stacked_post(cpu, ruby_set_program_counter, (void*) newPC.getAddress()); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_set_pc(int procID, Address newPC) {
|
|
||||||
// IMPORTANT: procID is the SIMICS simulated proc number (takes into account SMT)
|
|
||||||
// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// assert(cpu != NULL);
|
|
||||||
//
|
|
||||||
// if(OpalInterface::isOpalLoaded() == false){
|
|
||||||
// // SIM_set_program_counter(cpu, newPC.getAddress()); // Maurice
|
|
||||||
// } else {
|
|
||||||
// // explicitly change PC
|
|
||||||
// ruby_set_pc( cpu, (void *) newPC.getAddress() );
|
|
||||||
// }
|
|
||||||
// // int isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// // sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
// WARN_MSG( "SIMICS_set_pc: raised exception." );
|
|
||||||
// // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// ASSERT(0);
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_set_next_program_counter(int procID, Address newNPC) {
|
|
||||||
// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// assert(cpu != NULL);
|
|
||||||
|
|
||||||
// SIM_stacked_post(cpu, ruby_set_npc, (void*) newNPC.getAddress()); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_set_npc(int procID, Address newNPC) {
|
|
||||||
// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// assert(cpu != NULL);
|
|
||||||
//
|
|
||||||
// if(OpalInterface::isOpalLoaded() == false){
|
|
||||||
// // SIM_write_register(cpu, SIM_get_register_number(cpu, "npc"), newNPC.getAddress()); // Maurice
|
|
||||||
// } else {
|
|
||||||
// // explicitly change NPC
|
|
||||||
// ruby_set_npc( cpu, (void *) newNPC.getAddress() );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // int isexcept = SIM_get_pending_exception(); // Maurice
|
|
||||||
// if ( !(isexcept == SimExc_No_Exception || isexcept == SimExc_Break) ) {
|
|
||||||
// // sim_exception_t except_code = SIM_clear_exception(); // Maurice
|
|
||||||
// WARN_MSG( "SIMICS_set_npc: raised exception " );
|
|
||||||
// // WARN_MSG( SIM_last_error() ); // Maurice
|
|
||||||
// ASSERT(0);
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_post_continue_execution(int procID){
|
|
||||||
// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// assert(cpu != NULL);
|
|
||||||
//
|
|
||||||
// if(OpalInterface::isOpalLoaded() == false){
|
|
||||||
// // SIM_stacked_post(cpu, ruby_continue_execution, (void *) NULL); // Maurice
|
|
||||||
// } else{
|
|
||||||
// ruby_continue_execution( cpu, (void *) NULL );
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_post_restart_transaction(int procID){
|
|
||||||
// void *cpu = SIM_proc_no_2_ptr(procID); // Maurice
|
|
||||||
// assert(cpu != NULL);
|
|
||||||
//
|
|
||||||
// if(OpalInterface::isOpalLoaded() == false){
|
|
||||||
// // SIM_stacked_post(cpu, ruby_restart_transaction, (void *) NULL); // Maurice
|
|
||||||
// } else{
|
|
||||||
// ruby_restart_transaction( cpu, (void *) NULL );
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return -1 when fail
|
|
||||||
int SIMICS_get_proc_no(void *cpu) {
|
|
||||||
// int proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
|
|
||||||
// return proc_no;
|
|
||||||
assert(0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_disable_processor( int cpuNumber ) {
|
|
||||||
// if(SIM_cpu_enabled(SIMICS_get_proc_ptr(cpuNumber))) { // Maurice
|
|
||||||
// SIM_disable_processor(SIMICS_get_proc_ptr(cpuNumber)); // Maurice
|
|
||||||
// } else {
|
|
||||||
// WARN_MSG(cpuNumber);
|
|
||||||
// WARN_MSG( "Tried to disable a 'disabled' processor");
|
|
||||||
// ASSERT(0);
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_post_disable_processor( int cpuNumber ) {
|
|
||||||
// SIM_stacked_post(SIMICS_get_proc_ptr(cpuNumber), ruby_disable_processor, (void*) NULL); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_enable_processor( int cpuNumber ) {
|
|
||||||
// if(!SIM_cpu_enabled(SIMICS_get_proc_ptr(cpuNumber))) { // Maurice
|
|
||||||
// SIM_enable_processor(SIMICS_get_proc_ptr(cpuNumber)); // Maurice
|
|
||||||
// } else {
|
|
||||||
// WARN_MSG(cpuNumber);
|
|
||||||
// WARN_MSG( "Tried to enable an 'enabled' processor");
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SIMICS_processor_enabled( int cpuNumber ) {
|
|
||||||
// return SIM_cpu_enabled(SIMICS_get_proc_ptr(cpuNumber)); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return NULL when fail
|
|
||||||
void* SIMICS_get_proc_ptr(int cpuNumber) {
|
|
||||||
// return (void *) SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
assert(0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_print_version(ostream& out) {
|
|
||||||
// const char* version = SIM_version(); // Maurice
|
|
||||||
// if (version != NULL) {
|
|
||||||
// out << "simics_version: " << SIM_version() << endl; // Maurice
|
|
||||||
// }
|
|
||||||
out << "Mwa ha ha this is not Simics!!";
|
|
||||||
}
|
|
||||||
|
|
||||||
// KM -- From Nikhil's SN code
|
|
||||||
//these functions should be in interface.C ??
|
|
||||||
|
|
||||||
uinteger_t SIMICS_read_control_register(int cpuNumber, int registerNumber)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// uinteger_t result = SIM_read_register(cpu, registerNumber); // Maurice
|
|
||||||
// return result;
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uinteger_t SIMICS_read_window_register(int cpuNumber, int window, int registerNumber)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// uinteger_t result = SIM_read_register(cpu, registerNumber); // Maurice
|
|
||||||
// return result;
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uinteger_t SIMICS_read_global_register(int cpuNumber, int globals, int registerNumber)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// uinteger_t result = SIM_read_register(cpu, registerNumber); // Maurice
|
|
||||||
// return result;
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
uint64 SIMICS_read_fp_register_x(int cpuNumber, int registerNumber)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// return SIM_read_fp_register_x(cpu, registerNumber); // Maurice
|
|
||||||
}
|
|
||||||
**/
|
|
||||||
|
|
||||||
void SIMICS_write_control_register(int cpuNumber, int registerNumber, uinteger_t value)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// SIM_write_register(cpu, registerNumber, value); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_write_window_register(int cpuNumber, int window, int registerNumber, uinteger_t value)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// SIM_write_register(cpu, registerNumber, value); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_write_global_register(int cpuNumber, int globals, int registerNumber, uinteger_t value)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// SIM_write_register(cpu, registerNumber, value); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
void SIMICS_write_fp_register_x(int cpuNumber, int registerNumber, uint64 value)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// SIM_write_fp_register_x(cpu, registerNumber, value); // Maurice
|
|
||||||
}
|
|
||||||
***/
|
|
||||||
|
|
||||||
// KM -- Functions using new APIs (update from Nikhil's original)
|
|
||||||
|
|
||||||
int SIMICS_get_register_number(int cpuNumber, const char * reg_name){
|
|
||||||
// int result = SIM_get_register_number(SIM_proc_no_2_ptr(cpuNumber), reg_name); // Maurice
|
|
||||||
// return result;
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * SIMICS_get_register_name(int cpuNumber, int reg_num){
|
|
||||||
// const char * result = SIM_get_register_name(SIM_proc_no_2_ptr(cpuNumber), reg_num); // Maurice
|
|
||||||
// return result;
|
|
||||||
assert(0);
|
|
||||||
return "Then we shall fight in the shade";
|
|
||||||
}
|
|
||||||
|
|
||||||
uinteger_t SIMICS_read_register(int cpuNumber, int registerNumber)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// uinteger_t result = SIM_read_register(cpu, registerNumber); // Maurice
|
|
||||||
// return result;
|
|
||||||
assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SIMICS_write_register(int cpuNumber, int registerNumber, uinteger_t value)
|
|
||||||
{
|
|
||||||
// processor_t* cpu = SIM_proc_no_2_ptr(cpuNumber); // Maurice
|
|
||||||
// SIM_write_register(cpu, registerNumber, value); // Maurice
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This version is called whenever we are about to jump to the SW handler
|
|
||||||
void ruby_set_pc(void *cpu, void *parameter){
|
|
||||||
// physical_address_t paddr;
|
|
||||||
// paddr = (physical_address_t) parameter;
|
|
||||||
// // Simics' processor number
|
|
||||||
// // int proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
|
|
||||||
// int smt_proc_no = proc_no / RubyConfig::numberofSMTThreads();
|
|
||||||
// // SIM_set_program_counter(cpu, paddr); // Maurice
|
|
||||||
// //cout << "ruby_set_pc setting cpu[ " << proc_no << " ] smt_cpu[ " << smt_proc_no << " ] PC[ " << hex << paddr << " ]" << dec << endl;
|
|
||||||
// // physical_address_t newpc = SIM_get_program_counter(cpu); // Maurice
|
|
||||||
// // int pc_reg = SIM_get_register_number(cpu, "pc"); // Maurice
|
|
||||||
// // int npc_reg = SIM_get_register_number( cpu, "npc"); // Maurice
|
|
||||||
// // uinteger_t pc = SIM_read_register(cpu, pc_reg); // Maurice
|
|
||||||
// // uinteger_t npc = SIM_read_register(cpu, npc_reg); // Maurice
|
|
||||||
// //cout << "NEW PC[ 0x" << hex << newpc << " ]" << " PC REG[ 0x" << pc << " ] NPC REG[ 0x" << npc << " ]" << dec << endl;
|
|
||||||
//
|
|
||||||
// if(XACT_MEMORY){
|
|
||||||
// if( !OpalInterface::isOpalLoaded() ){
|
|
||||||
// // using SimicsDriver
|
|
||||||
// ASSERT( proc_no == smt_proc_no );
|
|
||||||
// SimicsDriver *simics_intf = dynamic_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
// ASSERT( simics_intf );
|
|
||||||
// simics_intf->notifyTrapStart( proc_no, Address(paddr), 0 /*dummy threadID*/, 0 /* Simics uses 1 thread */ );
|
|
||||||
// }
|
|
||||||
// else{
|
|
||||||
// // notify Opal about changing pc to SW handler
|
|
||||||
// //cout << "informing Opal via notifyTrapStart proc = " << proc_no << endl;
|
|
||||||
// //g_system_ptr->getSequencer(smt_proc_no)->notifyTrapStart( proc_no, Address(paddr) );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (XACT_DEBUG && XACT_DEBUG_LEVEL > 1){
|
|
||||||
// cout << g_eventQueue_ptr->getTime() << " " << proc_no
|
|
||||||
// << " ruby_set_pc PC: " << hex
|
|
||||||
// // << SIM_get_program_counter(cpu) << // Maurice
|
|
||||||
// // " NPC is: " << hex << SIM_read_register(cpu, 33) << " pc_val: " << paddr << dec << endl; // Maurice
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This version is called whenever we are about to return from SW handler
|
|
||||||
void ruby_set_program_counter(void *cpu, void *parameter){
|
|
||||||
// physical_address_t paddr;
|
|
||||||
// paddr = (physical_address_t) parameter;
|
|
||||||
// // Simics' processor number
|
|
||||||
//// int proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
|
|
||||||
// // SMT proc number
|
|
||||||
// int smt_proc_no = proc_no / RubyConfig::numberofSMTThreads();
|
|
||||||
//
|
|
||||||
//// // SIM_set_program_counter() also sets the NPC to PC+4. // Maurice
|
|
||||||
// // Need to ensure that NPC doesn't change especially for PCs in the branch delay slot
|
|
||||||
//// uinteger_t npc_val = SIM_read_register(cpu, SIM_get_register_number(cpu, "npc")); // Maurice
|
|
||||||
//// SIM_set_program_counter(cpu, paddr); // Maurice
|
|
||||||
//// SIM_write_register(cpu, SIM_get_register_number(cpu, "npc"), npc_val); // Maurice
|
|
||||||
//
|
|
||||||
// //LUKE - notify Opal of PC change (ie end of all register updates and abort complete)
|
|
||||||
// // I moved the register checkpoint restoration to here also, to jointly update the PC and the registers at the same time
|
|
||||||
// if(XACT_MEMORY){
|
|
||||||
// if( !OpalInterface::isOpalLoaded() ){
|
|
||||||
// //using SimicsDriver
|
|
||||||
// //we should only be running with 1 thread with Simics
|
|
||||||
// ASSERT( proc_no == smt_proc_no );
|
|
||||||
// SimicsDriver *simics_intf = dynamic_cast<SimicsDriver*>(g_system_ptr->getDriver());
|
|
||||||
// ASSERT( simics_intf );
|
|
||||||
// simics_intf->notifyTrapComplete(proc_no, Address( paddr ), 0 /* Simics uses 1 thread */ );
|
|
||||||
// }
|
|
||||||
// else{
|
|
||||||
// //using OpalInterface
|
|
||||||
// // g_system_ptr->getSequencer(smt_proc_no)->notifyTrapComplete( proc_no, Address(paddr) );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (XACT_DEBUG && XACT_DEBUG_LEVEL > 1){
|
|
||||||
// cout << g_eventQueue_ptr->getTime() << " " << proc_no
|
|
||||||
// << " ruby_set_program_counter PC: " << hex
|
|
||||||
//// << SIM_get_program_counter(cpu) << // Maurice
|
|
||||||
//// " NPC is: " << hex << SIM_read_register(cpu, 33) << " pc_val: " << paddr << " npc_val: " << npc_val << dec << endl; // Maurice
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ruby_set_npc(void *cpu, void *parameter){
|
|
||||||
// physical_address_t paddr;
|
|
||||||
// paddr = (physical_address_t) parameter;
|
|
||||||
// // int proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
|
|
||||||
// // SMT proc number
|
|
||||||
// int smt_proc_no = proc_no / RubyConfig::numberofSMTThreads();
|
|
||||||
//
|
|
||||||
// // SIM_write_register(cpu, SIM_get_register_number(cpu, "npc"), paddr); // Maurice
|
|
||||||
// if (XACT_DEBUG && XACT_DEBUG_LEVEL > 1){
|
|
||||||
// cout << g_eventQueue_ptr->getTime() << " " << proc_no
|
|
||||||
// << " ruby_set_npc val: " << hex << paddr << " PC: " << hex
|
|
||||||
// // << SIM_get_program_counter(cpu) << // Maurice
|
|
||||||
// // " NPC is: " << hex << SIM_read_register(cpu, 33) << dec << endl; // Maurice
|
|
||||||
// }
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ruby_continue_execution(void *cpu, void *parameter){
|
|
||||||
// int logical_proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
|
|
||||||
// int thread = logical_proc_no % RubyConfig::numberofSMTThreads();
|
|
||||||
// int proc_no = logical_proc_no / RubyConfig::numberofSMTThreads();
|
|
||||||
// g_system_ptr->getTransactionInterfaceManager(proc_no)->continueExecutionCallback(thread);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ruby_restart_transaction(void *cpu, void *parameter){
|
|
||||||
// int logical_proc_no = SIM_get_proc_no((processor_t *) cpu); // Maurice
|
|
||||||
// int thread = logical_proc_no % RubyConfig::numberofSMTThreads();
|
|
||||||
// int proc_no = logical_proc_no / RubyConfig::numberofSMTThreads();
|
|
||||||
// g_system_ptr->getTransactionInterfaceManager(proc_no)->restartTransactionCallback(thread);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ruby_stall_proc(void *cpu, void *parameter){
|
|
||||||
// int logical_proc_no = SIM_get_proc_no((processor_t*)cpu); // Maurice
|
|
||||||
// int cycles = (uint64)parameter;
|
|
||||||
|
|
||||||
// SIMICS_stall_proc(logical_proc_no, cycles);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ruby_disable_processor(void *cpu, void *parameter){
|
|
||||||
// int logical_proc_no = SIM_get_proc_no((processor_t*)cpu); // Maurice
|
|
||||||
// SIMICS_disable_processor(logical_proc_no);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,152 +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: interface.h 1.33 05/01/19 13:12:32-06:00 mikem@maya.cs.wisc.edu $
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef INTERFACE_H
|
|
||||||
#define INTERFACE_H
|
|
||||||
|
|
||||||
#include "Global.hh"
|
|
||||||
#include "mf_api.hh"
|
|
||||||
#include "Address.hh"
|
|
||||||
|
|
||||||
// // Simics includes
|
|
||||||
// extern "C" {
|
|
||||||
// #include "simics/api.hh"
|
|
||||||
// }
|
|
||||||
|
|
||||||
typedef void memory_transaction_t;
|
|
||||||
|
|
||||||
// simics memory access
|
|
||||||
integer_t SIMICS_read_physical_memory(int procID, physical_address_t address,
|
|
||||||
int len );
|
|
||||||
void SIMICS_read_physical_memory_buffer(int procID, physical_address_t addr,
|
|
||||||
char* buffer, int len );
|
|
||||||
void SIMICS_write_physical_memory( int procID, physical_address_t address,
|
|
||||||
integer_t value, int len );
|
|
||||||
void SIMICS_write_physical_memory_buffer(int procID, physical_address_t addr,
|
|
||||||
char* buffer, int len );
|
|
||||||
bool SIMICS_check_memory_value(int procID, physical_address_t addr,
|
|
||||||
char* buffer, int len);
|
|
||||||
const char *SIMICS_disassemble_physical( int procID, physical_address_t pa );
|
|
||||||
|
|
||||||
// simics VM translation, decoding, etc.
|
|
||||||
physical_address_t SIMICS_translate_address( int procID, Address address );
|
|
||||||
physical_address_t SIMICS_translate_data_address( int procID, Address address );
|
|
||||||
#ifdef SPARC
|
|
||||||
bool SIMICS_is_ldda(const memory_transaction_t *mem_trans);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// simics timing
|
|
||||||
void SIMICS_unstall_proc(int cpuNumber);
|
|
||||||
void SIMICS_unstall_proc(int cpuNumber, int cycles);
|
|
||||||
void SIMICS_stall_proc(int cpuNumber, int cycles);
|
|
||||||
void SIMICS_post_stall_proc(int cpuNumber, int cycles);
|
|
||||||
void SIMICS_wakeup_ruby();
|
|
||||||
|
|
||||||
// simics callbacks
|
|
||||||
void SIMICS_remove_ruby_callback( void );
|
|
||||||
void SIMICS_install_timing_model( void );
|
|
||||||
void SIMICS_remove_timing_model( void );
|
|
||||||
void SIMICS_install_exception_callback( void );
|
|
||||||
void SIMICS_remove_exception_callback( void );
|
|
||||||
#ifdef SPARC
|
|
||||||
void SIMICS_install_asi_callback( void );
|
|
||||||
void SIMICS_remove_asi_callback( void );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// simics PC, IC
|
|
||||||
integer_t SIMICS_get_insn_count( int cpuNumber );
|
|
||||||
integer_t SIMICS_get_cycle_count(int cpuNumber);
|
|
||||||
Address SIMICS_get_program_counter( void *cpu );
|
|
||||||
Address SIMICS_get_program_counter( int procID );
|
|
||||||
Address SIMICS_get_npc(int procID);
|
|
||||||
void SIMICS_set_program_counter( int procID, Address newPC );
|
|
||||||
void SIMICS_set_next_program_counter( int procID, Address newPC );
|
|
||||||
void SIMICS_set_pc( int procID, Address newPC );
|
|
||||||
void SIMICS_set_npc( int procID, Address newNPC );
|
|
||||||
|
|
||||||
void SIMICS_post_continue_execution(int procID);
|
|
||||||
void SIMICS_post_restart_transaction(int procID);
|
|
||||||
|
|
||||||
// simics processor number
|
|
||||||
int SIMICS_number_processors( void );
|
|
||||||
void * SIMICS_current_processor( void );
|
|
||||||
int SIMICS_current_processor_number( void );
|
|
||||||
int SIMICS_get_proc_no( void *cpu );
|
|
||||||
void* SIMICS_get_proc_ptr( int cpuNumber );
|
|
||||||
|
|
||||||
// simics version
|
|
||||||
void SIMICS_print_version(ostream& out);
|
|
||||||
|
|
||||||
// opal
|
|
||||||
mf_opal_api_t *SIMICS_get_opal_interface( void );
|
|
||||||
|
|
||||||
// STC related, should not be used anymore!
|
|
||||||
void SIMICS_flush_STC(int cpuNumber);
|
|
||||||
void SIMICS_invalidate_from_STC(const Address& address, int cpuNumber);
|
|
||||||
void SIMICS_downgrade_from_STC(const Address& address, int cpuNumber);
|
|
||||||
|
|
||||||
// KM -- from Nikhil's SN code
|
|
||||||
uinteger_t SIMICS_read_control_register(int cpuNumber, int registerNumber);
|
|
||||||
uinteger_t SIMICS_read_window_register(int cpuNumber, int window, int registerNumber);
|
|
||||||
uinteger_t SIMICS_read_global_register(int cpuNumber, int globals, int registerNumber);
|
|
||||||
//uint64 SIMICS_read_fp_register_x(int cpuNumber, int registerNumber);
|
|
||||||
|
|
||||||
// KM -- new version based on reg names
|
|
||||||
int SIMICS_get_register_number(int cpuNumber, const char * reg_name);
|
|
||||||
const char * SIMICS_get_register_name(int cpuNumber, int reg_num);
|
|
||||||
uinteger_t SIMICS_read_register(int cpuNumber, int registerNumber);
|
|
||||||
void SIMICS_write_register(int cpuNumber, int registerNumber, uinteger_t value);
|
|
||||||
|
|
||||||
void SIMICS_write_control_register(int cpuNumber, int registerNumber, uinteger_t value);
|
|
||||||
void SIMICS_write_window_register(int cpuNumber, int window, int registerNumber, uinteger_t value);
|
|
||||||
void SIMICS_write_global_register(int cpuNumber, int globals, int registerNumber, uinteger_t value);
|
|
||||||
void SIMICS_write_fp_register_x(int cpuNumber, int registerNumber, uint64 value);
|
|
||||||
void SIMICS_enable_processor(int cpuNumber);
|
|
||||||
void SIMICS_disable_processor(int cpuNumber);
|
|
||||||
void SIMICS_post_disable_processor(int cpuNumber);
|
|
||||||
bool SIMICS_processor_enabled(int cpuNumber);
|
|
||||||
|
|
||||||
void ruby_abort_transaction(void *cpu, void *parameter);
|
|
||||||
void ruby_set_program_counter(void *cpu, void *parameter);
|
|
||||||
void ruby_set_pc(void *cpu, void *parameter);
|
|
||||||
void ruby_set_npc(void *cpu, void *parameter);
|
|
||||||
void ruby_continue_execution(void *cpu, void *parameter);
|
|
||||||
void ruby_restart_transaction(void *cpu, void *parameter);
|
|
||||||
void ruby_stall_proc(void *cpu, void *parameter);
|
|
||||||
void ruby_disable_processor(void *cpu, void *parameter);
|
|
||||||
|
|
||||||
#endif //INTERFACE_H
|
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
typedef int generic_transaction_t;
|
|
||||||
typedef int generic_transaction;
|
|
||||||
typedef int la_t;
|
|
||||||
typedef int integer_t;
|
|
||||||
typedef int uint64;
|
|
||||||
typedef int attr_value_t;
|
|
||||||
typedef int data_or_instr_t;
|
|
||||||
typedef int sim_exception_t;
|
|
||||||
typedef int processor_t;
|
|
||||||
typedef int conf_object_t;
|
|
||||||
typedef int conf_object;
|
|
||||||
typedef int physical_address_t;
|
|
||||||
typedef int logical_address_t;
|
|
||||||
typedef int read_or_write_t;
|
|
||||||
typedef int interface_t;
|
|
||||||
typedef int set_error_t;
|
|
||||||
typedef int ireg_t;
|
|
||||||
typedef int pc_step_t;
|
|
||||||
typedef int event_handler_t;
|
|
||||||
typedef int lang_void;
|
|
||||||
typedef int cycles_t;
|
|
||||||
typedef int sync_t;
|
|
||||||
typedef int FILE;
|
|
||||||
typedef int va_list;
|
|
||||||
typedef int log_object;
|
|
||||||
typedef int hap_handle_t;
|
|
||||||
typedef int str_hap_func_t;
|
|
||||||
typedef int hap_type_t;
|
|
||||||
typedef int cb_func_em_t;
|
|
||||||
typedef int sync_t;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void SIM_number_processors() { assert(0); return; };
|
|
||||||
void SIM_c_set_mem_op_value_buf(generic_transaction_t *mem_op, char *buf) { assert(0); return; };
|
|
||||||
void SIM_c_get_mem_op_value_buf(generic_transaction_t *mem_op, char *buf) { assert(0); return; };
|
|
||||||
sim_exception_t SIM_clear_exception(void) { assert(0); return 0; };
|
|
||||||
processor_t *SIM_conf_object_to_processor(conf_object_t* obj) { assert(0); return 0; };
|
|
||||||
processor_t *SIM_current_processor(void) { assert(0); return 0; };
|
|
||||||
const char *SIM_disassemble(processor_t *cpu_ptr, physical_address_t pa, int type) { assert(0); return 0; };
|
|
||||||
interface_t *SIM_get_interface(conf_object const *object, const char *interface_name) { assert(0); return 0; };
|
|
||||||
conf_object_t *SIM_get_object(const char *name) { assert(0); return 0; };
|
|
||||||
sim_exception_t SIM_get_pending_exception(void) { assert(0); return 0; };
|
|
||||||
int SIM_get_proc_no(const processor_t *cpu_ptr) { assert(0); return 0; };
|
|
||||||
la_t SIM_get_program_counter(processor_t *cpu) { assert(0); return 0; };
|
|
||||||
const char *SIM_last_error(void) { assert(0); return 0; };
|
|
||||||
physical_address_t SIM_logical_to_physical(conf_object *cpu_ptr, data_or_instr_t data_or_instr, logical_address_t address) { assert(0); return 0; };
|
|
||||||
const char * SIM_get_exception_name( processor_t * p, int exc ) { assert(0); return 0;};
|
|
||||||
processor_t *SIM_proc_no_2_ptr(int cpu_nr) { assert(0); return 0; };
|
|
||||||
conf_object_t *SIM_processor_to_conf_object(processor_t* p) { assert(0); return 0; };
|
|
||||||
ireg_t SIM_read_control_register(processor_t *cpu_ptr, int reg) { assert(0); return 0; };
|
|
||||||
double SIM_read_fp_register_d(processor_t *cpu_ptr, int reg) { assert(0); return 0; };
|
|
||||||
uint64 SIM_read_fp_register_x(processor_t *cpu_ptr, int reg) { assert(0); return 0; };
|
|
||||||
ireg_t SIM_read_global_register(processor_t *cpu_ptr, int globals, int reg) { assert(0); return 0; };
|
|
||||||
integer_t SIM_read_phys_memory(conf_object *cpu, physical_address_t address, int len) { assert(0); return 0; };
|
|
||||||
ireg_t SIM_read_window_register(processor_t *cpu_ptr, int window, int reg) { assert(0); return 0; };
|
|
||||||
set_error_t SIM_set_attribute(conf_object_t *object, char const *name, attr_value_t *value) { assert(0); return 0; };
|
|
||||||
void SIM_free_attribute(attr_value_t *value) { assert(0); };
|
|
||||||
void SIM_stall_cycle(conf_object_t *obj, cycles_t stall) { assert(0); return; };
|
|
||||||
cycles_t SIM_stall_count(conf_object_t *obj) { assert(0); return 0; };
|
|
||||||
void SIM_stall(conf_object_t *obj, cycles_t stall) { assert(0); return; };
|
|
||||||
pc_step_t SIM_step_count(conf_object_t *p) { assert(0); return 0; };
|
|
||||||
cycles_t SIM_cycle_count(conf_object_t *p) { assert(0); return 0; };
|
|
||||||
cycles_t SIM_stalled_until(conf_object_t *p) { assert(0); return 0; };
|
|
||||||
void SIM_time_clean(conf_object_t *obj, sync_t t, event_handler_t handler, lang_void * arg) { assert(0); return; };
|
|
||||||
void SIM_time_post_cycle(conf_object_t * obj, cycles_t delta, sync_t sync, event_handler_t handler, lang_void * arg) { assert(0); return; };
|
|
||||||
const char *SIM_version(void) { return 0; };
|
|
||||||
void SIM_set_program_counter(conf_object_t *cpu, logical_address_t pc){assert(0);};
|
|
||||||
void SIM_write_control_register(processor_t *cpu_ptr, int reg, ireg_t value) { assert(0); return; };
|
|
||||||
void SIM_write_fp_register_x(processor_t *cpu_ptr, int reg, uint64 value) { assert(0); return; };
|
|
||||||
void SIM_write_global_register(processor_t *cpu_ptr, int globals, int reg, ireg_t value) { assert(0); return; };
|
|
||||||
void SIM_write_window_register(processor_t *cpu_ptr, int window, int reg, ireg_t value) { assert(0); return; };
|
|
||||||
void SIM_write_phys_memory(conf_object *cpu, physical_address_t address, integer_t value, int len) { assert(0); };
|
|
||||||
int __sparc_v9_vtvfprintf(FILE *stream, const char *format, va_list va) { assert(0); return 0; };
|
|
||||||
int __l32_p32_vtvfprintf(FILE *stream, const char *format, va_list va) { assert(0); return 0; };
|
|
||||||
int __l32_p64_vtvfprintf(FILE *stream, const char *format, va_list va) { assert(0); return 0; };
|
|
||||||
int __l64_p64_vtvfprintf(FILE *stream, const char *format, va_list va) { assert(0); return 0; };
|
|
||||||
void __sparc_v9_vtdebug_log_vararg(int lvl, log_object *dev, char const *str, va_list va) { assert (0); return; };
|
|
||||||
hap_handle_t SIM_hap_add_callback(const char *id, str_hap_func_t cb, lang_void *data) { assert(0); return 0; };
|
|
||||||
hap_type_t SIM_hap_get_number(const char *id) { assert(0); return 0; };
|
|
||||||
void SIM_hap_delete_callback_id(hap_type_t hap, hap_handle_t hdl) { assert (0); return; };
|
|
||||||
int SIM_flush(void) { assert(0); return 0; };
|
|
||||||
void SIM_write_register(processor_t *cpu_ptr, int registerNumber, integer_t value){ assert(0); };
|
|
||||||
integer_t SIM_read_register(processor_t *cpu_ptr, int registerNumber) { assert(0); return 0; };
|
|
||||||
int SIM_get_register_number(processor_t *cpu_ptr, const char * register_name){ assert(0); return 0; }
|
|
||||||
const char * SIM_get_register_name(processor_t *cpu_ptr, int reg_num){ assert(0); return 0; }
|
|
||||||
|
|
||||||
void SIM_break_simulation(const char * msg){ assert(0); }
|
|
||||||
void SIM_printf(const char *format, va_list ap){ assert(0); }
|
|
||||||
set_error_t ruby_session_set( void *id, conf_object_t *obj,
|
|
||||||
attr_value_t *val, attr_value_t *idx ) { assert (0); return 0; };
|
|
||||||
attr_value_t ruby_session_get( void *id, conf_object_t *obj,
|
|
||||||
attr_value_t *idx ) { assert (0); return 0; };
|
|
||||||
void SIM_stacked_post(conf_object_t *obj, event_handler_t, lang_void *arg){};
|
|
||||||
pc_step_t SIM_step_next_occurrence( conf_object_t * obj, event_handler_t, lang_void * arg){ assert(0); return 0;};
|
|
||||||
void SIM_enable_processor(conf_object_t *p) { assert(0); };
|
|
||||||
void SIM_disable_processor(conf_object_t *p) { assert(0); };
|
|
||||||
int SIM_cpu_enabled(conf_object_t *p) { assert(0); };
|
|
||||||
|
|
||||||
attr_value_t SIM_get_attribute(conf_object_t *object, const char *name) { assert(0); };
|
|
||||||
} // extern "C"
|
|
|
@ -42,7 +42,6 @@
|
||||||
#include "RubySlicc_Util.hh"
|
#include "RubySlicc_Util.hh"
|
||||||
#include "RubyConfig.hh"
|
#include "RubyConfig.hh"
|
||||||
#include "Chip.hh"
|
#include "Chip.hh"
|
||||||
#include "interface.hh"
|
|
||||||
|
|
||||||
DirectoryMemory::DirectoryMemory(Chip* chip_ptr, int version)
|
DirectoryMemory::DirectoryMemory(Chip* chip_ptr, int version)
|
||||||
{
|
{
|
||||||
|
@ -122,14 +121,15 @@ Directory_Entry& DirectoryMemory::lookup(PhysAddress address)
|
||||||
// entry->getDirOwner() = true; // FIXME - This should not be hard-coded
|
// entry->getDirOwner() = true; // FIXME - This should not be hard-coded
|
||||||
|
|
||||||
// load the data from SimICS when first initalizing
|
// load the data from SimICS when first initalizing
|
||||||
if (g_SIMICS) {
|
if (g_SIMULATING) {
|
||||||
if (DATA_BLOCK) {
|
if (DATA_BLOCK) {
|
||||||
physical_address_t physAddr = address.getAddress();
|
//physical_address_t physAddr = address.getAddress();
|
||||||
|
|
||||||
for(int j=0; j < RubyConfig::dataBlockBytes(); j++) {
|
for(int j=0; j < RubyConfig::dataBlockBytes(); j++) {
|
||||||
int8 data_byte = (int8) SIMICS_read_physical_memory( m_chip_ptr->getID(),
|
//int8 data_byte = (int8) SIMICS_read_physical_memory( m_chip_ptr->getID(),
|
||||||
physAddr + j, 1 );
|
// physAddr + j, 1 );
|
||||||
//printf("SimICS, byte %d: %lld\n", j, data_byte );
|
//printf("SimICS, byte %d: %lld\n", j, data_byte );
|
||||||
|
int8 data_byte = 0;
|
||||||
entry->getDataBlk().setByte(j, data_byte);
|
entry->getDataBlk().setByte(j, data_byte);
|
||||||
}
|
}
|
||||||
DEBUG_EXPR(NODE_COMP, MedPrio,entry->getDataBlk());
|
DEBUG_EXPR(NODE_COMP, MedPrio,entry->getDataBlk());
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
#include "AccessPermission.hh"
|
#include "AccessPermission.hh"
|
||||||
#include "RubyConfig.hh"
|
#include "RubyConfig.hh"
|
||||||
#include "Address.hh"
|
#include "Address.hh"
|
||||||
#include "interface.hh"
|
|
||||||
#include "AbstractChip.hh"
|
#include "AbstractChip.hh"
|
||||||
|
|
||||||
template<class ENTRY>
|
template<class ENTRY>
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
#include "AccessType.hh"
|
#include "AccessType.hh"
|
||||||
#include "RubyConfig.hh"
|
#include "RubyConfig.hh"
|
||||||
#include "Address.hh"
|
#include "Address.hh"
|
||||||
#include "interface.hh"
|
|
||||||
|
|
||||||
struct ArbiterEntry {
|
struct ArbiterEntry {
|
||||||
bool valid;
|
bool valid;
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
#include "SubBlock.hh"
|
#include "SubBlock.hh"
|
||||||
#include "Protocol.hh"
|
#include "Protocol.hh"
|
||||||
#include "Map.hh"
|
#include "Map.hh"
|
||||||
#include "interface.hh"
|
|
||||||
|
|
||||||
Sequencer::Sequencer(AbstractChip* chip_ptr, int version) {
|
Sequencer::Sequencer(AbstractChip* chip_ptr, int version) {
|
||||||
m_chip_ptr = chip_ptr;
|
m_chip_ptr = chip_ptr;
|
||||||
|
@ -597,14 +596,6 @@ void Sequencer::hitCallback(const CacheMsg& request, DataBlock& data, GenericMac
|
||||||
if (miss_latency != 0) {
|
if (miss_latency != 0) {
|
||||||
g_system_ptr->getProfiler()->missLatency(miss_latency, type, respondingMach);
|
g_system_ptr->getProfiler()->missLatency(miss_latency, type, respondingMach);
|
||||||
|
|
||||||
#if 0
|
|
||||||
uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick"));
|
|
||||||
uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr"));
|
|
||||||
uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick"));
|
|
||||||
uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr"));
|
|
||||||
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;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write =
|
bool write =
|
||||||
|
@ -624,7 +615,7 @@ void Sequencer::hitCallback(const CacheMsg& request, DataBlock& data, GenericMac
|
||||||
m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->updateSubBlock(subblock);
|
m_chip_ptr->m_L1Cache_storeBuffer_vec[m_version]->updateSubBlock(subblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call into the Driver (Tester or Simics) and let it read and/or modify the sub-block
|
// Call into the Driver and let it read and/or modify the sub-block
|
||||||
g_system_ptr->getDriver()->hitCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID);
|
g_system_ptr->getDriver()->hitCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID);
|
||||||
|
|
||||||
// If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock
|
// If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock
|
||||||
|
@ -636,6 +627,130 @@ void Sequencer::hitCallback(const CacheMsg& request, DataBlock& data, GenericMac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sequencer::readConflictCallback(const Address& address) {
|
||||||
|
// process oldest thread first
|
||||||
|
int thread = -1;
|
||||||
|
Time oldest_time = 0;
|
||||||
|
int smt_threads = RubyConfig::numberofSMTThreads();
|
||||||
|
for(int t=0; t < smt_threads; ++t){
|
||||||
|
if(m_readRequestTable_ptr[t]->exist(address)){
|
||||||
|
CacheMsg & request = m_readRequestTable_ptr[t]->lookup(address);
|
||||||
|
if(thread == -1 || (request.getTime() < oldest_time) ){
|
||||||
|
thread = t;
|
||||||
|
oldest_time = request.getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// make sure we found an oldest thread
|
||||||
|
ASSERT(thread != -1);
|
||||||
|
|
||||||
|
CacheMsg & request = m_readRequestTable_ptr[thread]->lookup(address);
|
||||||
|
|
||||||
|
readConflictCallback(address, GenericMachineType_NULL, thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequencer::readConflictCallback(const Address& address, GenericMachineType respondingMach, int thread) {
|
||||||
|
assert(address == line_address(address));
|
||||||
|
assert(m_readRequestTable_ptr[thread]->exist(line_address(address)));
|
||||||
|
|
||||||
|
CacheMsg request = m_readRequestTable_ptr[thread]->lookup(address);
|
||||||
|
assert( request.getThreadID() == thread );
|
||||||
|
removeRequest(request);
|
||||||
|
|
||||||
|
assert((request.getType() == CacheRequestType_LD) ||
|
||||||
|
(request.getType() == CacheRequestType_LD_XACT) ||
|
||||||
|
(request.getType() == CacheRequestType_IFETCH)
|
||||||
|
);
|
||||||
|
|
||||||
|
conflictCallback(request, respondingMach, thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequencer::writeConflictCallback(const Address& address) {
|
||||||
|
// process oldest thread first
|
||||||
|
int thread = -1;
|
||||||
|
Time oldest_time = 0;
|
||||||
|
int smt_threads = RubyConfig::numberofSMTThreads();
|
||||||
|
for(int t=0; t < smt_threads; ++t){
|
||||||
|
if(m_writeRequestTable_ptr[t]->exist(address)){
|
||||||
|
CacheMsg & request = m_writeRequestTable_ptr[t]->lookup(address);
|
||||||
|
if(thread == -1 || (request.getTime() < oldest_time) ){
|
||||||
|
thread = t;
|
||||||
|
oldest_time = request.getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// make sure we found an oldest thread
|
||||||
|
ASSERT(thread != -1);
|
||||||
|
|
||||||
|
CacheMsg & request = m_writeRequestTable_ptr[thread]->lookup(address);
|
||||||
|
|
||||||
|
writeConflictCallback(address, GenericMachineType_NULL, thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequencer::writeConflictCallback(const Address& address, GenericMachineType respondingMach, int thread) {
|
||||||
|
assert(address == line_address(address));
|
||||||
|
assert(m_writeRequestTable_ptr[thread]->exist(line_address(address)));
|
||||||
|
CacheMsg request = m_writeRequestTable_ptr[thread]->lookup(address);
|
||||||
|
assert( request.getThreadID() == thread);
|
||||||
|
removeRequest(request);
|
||||||
|
|
||||||
|
assert((request.getType() == CacheRequestType_ST) ||
|
||||||
|
(request.getType() == CacheRequestType_ST_XACT) ||
|
||||||
|
(request.getType() == CacheRequestType_LDX_XACT) ||
|
||||||
|
(request.getType() == CacheRequestType_ATOMIC));
|
||||||
|
|
||||||
|
conflictCallback(request, respondingMach, thread);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sequencer::conflictCallback(const CacheMsg& request, GenericMachineType respondingMach, int thread) {
|
||||||
|
assert(XACT_MEMORY);
|
||||||
|
int size = request.getSize();
|
||||||
|
Address request_address = request.getAddress();
|
||||||
|
Address request_logical_address = request.getLogicalAddress();
|
||||||
|
Address request_line_address = line_address(request_address);
|
||||||
|
CacheRequestType type = request.getType();
|
||||||
|
int threadID = request.getThreadID();
|
||||||
|
Time issued_time = request.getTime();
|
||||||
|
int logical_proc_no = ((m_chip_ptr->getID() * RubyConfig::numberOfProcsPerChip()) + m_version) * RubyConfig::numberofSMTThreads() + threadID;
|
||||||
|
|
||||||
|
DEBUG_MSG(SEQUENCER_COMP, MedPrio, size);
|
||||||
|
|
||||||
|
assert(g_eventQueue_ptr->getTime() >= issued_time);
|
||||||
|
Time miss_latency = g_eventQueue_ptr->getTime() - issued_time;
|
||||||
|
|
||||||
|
if (PROTOCOL_DEBUG_TRACE) {
|
||||||
|
g_system_ptr->getProfiler()->profileTransition("Seq", (m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version), -1, request.getAddress(), "", "Conflict", "",
|
||||||
|
int_to_string(miss_latency)+" cycles "+GenericMachineType_to_string(respondingMach)+" "+CacheRequestType_to_string(request.getType())+" "+PrefetchBit_to_string(request.getPrefetch()));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_MSG(SEQUENCER_COMP, MedPrio, request_address);
|
||||||
|
DEBUG_MSG(SEQUENCER_COMP, MedPrio, request.getPrefetch());
|
||||||
|
if (request.getPrefetch() == PrefetchBit_Yes) {
|
||||||
|
DEBUG_MSG(SEQUENCER_COMP, MedPrio, "return");
|
||||||
|
g_system_ptr->getProfiler()->swPrefetchLatency(miss_latency, type, respondingMach);
|
||||||
|
return; // Ignore the software prefetch, don't callback the driver
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write =
|
||||||
|
(type == CacheRequestType_ST) ||
|
||||||
|
(type == CacheRequestType_ST_XACT) ||
|
||||||
|
(type == CacheRequestType_LDX_XACT) ||
|
||||||
|
(type == CacheRequestType_ATOMIC);
|
||||||
|
|
||||||
|
// Copy the correct bytes out of the cache line into the subblock
|
||||||
|
SubBlock subblock(request_address, request_logical_address, size);
|
||||||
|
|
||||||
|
// Call into the Driver
|
||||||
|
g_system_ptr->getDriver()->conflictCallback(m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version, subblock, type, threadID);
|
||||||
|
|
||||||
|
// If the request was a Store or Atomic, apply the changes in the SubBlock to the DataBlock
|
||||||
|
// (This is only triggered for the non-TSO case)
|
||||||
|
if (write) {
|
||||||
|
assert(!TSO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Sequencer::printDebug(){
|
void Sequencer::printDebug(){
|
||||||
//notify driver of debug
|
//notify driver of debug
|
||||||
g_system_ptr->getDriver()->printDebug();
|
g_system_ptr->getDriver()->printDebug();
|
||||||
|
@ -710,7 +825,7 @@ Sequencer::isReady(const CacheMsg& request) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by Driver (Simics or Tester).
|
// Called by Driver
|
||||||
void
|
void
|
||||||
Sequencer::makeRequest(const Packet* pkt, void* data)
|
Sequencer::makeRequest(const Packet* pkt, void* data)
|
||||||
{
|
{
|
||||||
|
@ -786,14 +901,6 @@ bool Sequencer::doRequest(const CacheMsg& request) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
uinteger_t tick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick"));
|
|
||||||
uinteger_t tick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "tick_cmpr"));
|
|
||||||
uinteger_t stick = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick"));
|
|
||||||
uinteger_t stick_cmpr = SIMICS_read_control_register(m_version, SIMICS_get_register_number(m_version, "stick_cmpr"));
|
|
||||||
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;;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (TSO && (request.getType() == CacheRequestType_LD || request.getType() == CacheRequestType_IFETCH)) {
|
if (TSO && (request.getType() == CacheRequestType_LD || request.getType() == CacheRequestType_IFETCH)) {
|
||||||
|
|
||||||
// See if we can satisfy the load entirely from the store buffer
|
// See if we can satisfy the load entirely from the store buffer
|
||||||
|
@ -936,10 +1043,11 @@ void Sequencer::checkCoherence(const Address& addr) {
|
||||||
|
|
||||||
bool Sequencer::getRubyMemoryValue(const Address& addr, char* value,
|
bool Sequencer::getRubyMemoryValue(const Address& addr, char* value,
|
||||||
unsigned int size_in_bytes ) {
|
unsigned int size_in_bytes ) {
|
||||||
if(g_SIMICS){
|
if(g_SIMULATING){
|
||||||
for(unsigned int i=0; i < size_in_bytes; i++) {
|
for(unsigned int i=0; i < size_in_bytes; i++) {
|
||||||
value[i] = SIMICS_read_physical_memory( m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version,
|
std::cerr << __FILE__ << "(" << __LINE__ << "): Not implemented. " << std::endl;
|
||||||
addr.getAddress() + i, 1 );
|
value[i] = 0; // _read_physical_memory( m_chip_ptr->getID()*RubyConfig::numberOfProcsPerChip()+m_version,
|
||||||
|
// addr.getAddress() + i, 1 );
|
||||||
}
|
}
|
||||||
return false; // Do nothing?
|
return false; // Do nothing?
|
||||||
} else {
|
} else {
|
||||||
|
@ -1006,7 +1114,7 @@ bool Sequencer::setRubyMemoryValue(const Address& addr, char *value,
|
||||||
unsigned int size_in_bytes) {
|
unsigned int size_in_bytes) {
|
||||||
char test_buffer[64];
|
char test_buffer[64];
|
||||||
|
|
||||||
if(g_SIMICS){
|
if(g_SIMULATING){
|
||||||
return false; // Do nothing?
|
return false; // Do nothing?
|
||||||
} else {
|
} else {
|
||||||
// idea here is that coherent cache should find the
|
// idea here is that coherent cache should find the
|
||||||
|
@ -1088,3 +1196,4 @@ bool Sequencer::setRubyMemoryValue(const Address& addr, char *value,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include "Tester.hh"
|
#include "Tester.hh"
|
||||||
#include "SyntheticDriver.hh"
|
#include "SyntheticDriver.hh"
|
||||||
#include "DeterministicDriver.hh"
|
#include "DeterministicDriver.hh"
|
||||||
#include "OpalInterface.hh"
|
|
||||||
#include "Chip.hh"
|
#include "Chip.hh"
|
||||||
//#include "Tracer.hh"
|
//#include "Tracer.hh"
|
||||||
#include "Protocol.hh"
|
#include "Protocol.hh"
|
||||||
|
@ -202,15 +201,6 @@ void RubySystem::recordCacheContents(CacheRecorder& tr) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void System::opalLoadNotify()
|
|
||||||
{
|
|
||||||
if (OpalInterface::isOpalLoaded()) {
|
|
||||||
// change the driver pointer to point to an opal driver
|
|
||||||
delete m_driver_ptr;
|
|
||||||
m_driver_ptr = new OpalInterface(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CHECK_COHERENCE
|
#ifdef CHECK_COHERENCE
|
||||||
// This code will check for cases if the given cache block is exclusive in
|
// This code will check for cases if the given cache block is exclusive in
|
||||||
// one node and shared in another-- a coherence violation
|
// one node and shared in another-- a coherence violation
|
||||||
|
|
|
@ -91,9 +91,6 @@ public:
|
||||||
void printStats(ostream& out);
|
void printStats(ostream& out);
|
||||||
void clearStats() const;
|
void clearStats() const;
|
||||||
|
|
||||||
// called to notify the system when opal is loaded
|
|
||||||
void opalLoadNotify();
|
|
||||||
|
|
||||||
void print(ostream& out) const;
|
void print(ostream& out) const;
|
||||||
#ifdef CHECK_COHERENCE
|
#ifdef CHECK_COHERENCE
|
||||||
void checkGlobalCoherenceInvariant(const Address& addr);
|
void checkGlobalCoherenceInvariant(const Address& addr);
|
||||||
|
|
|
@ -45,8 +45,8 @@
|
||||||
|
|
||||||
DeterministicDriver::DeterministicDriver(RubySystem* sys_ptr)
|
DeterministicDriver::DeterministicDriver(RubySystem* sys_ptr)
|
||||||
{
|
{
|
||||||
if (g_SIMICS) {
|
if (g_SIMULATING) {
|
||||||
ERROR_MSG("g_SIMICS should not be defined.");
|
ERROR_MSG("g_SIMULATING should not be defined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_finish_time = 0;
|
m_finish_time = 0;
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
|
|
||||||
RaceyDriver::RaceyDriver()
|
RaceyDriver::RaceyDriver()
|
||||||
{
|
{
|
||||||
if (g_SIMICS) {
|
if (g_SIMULATING) {
|
||||||
ERROR_MSG("g_SIMICS should not be defined.");
|
ERROR_MSG("g_SIMULATING should not be defined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug transition?
|
// debug transition?
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
SyntheticDriver::SyntheticDriver(RubySystem* sys_ptr)
|
SyntheticDriver::SyntheticDriver(RubySystem* sys_ptr)
|
||||||
{
|
{
|
||||||
cout << "SyntheticDriver::SyntheticDriver" << endl;
|
cout << "SyntheticDriver::SyntheticDriver" << endl;
|
||||||
if (g_SIMICS) {
|
if (g_SIMULATING) {
|
||||||
ERROR_MSG("g_SIMICS should not be defined.");
|
ERROR_MSG("g_SIMULATING should not be defined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_finish_time = 0;
|
m_finish_time = 0;
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
|
|
||||||
Tester::Tester(RubySystem* sys_ptr)
|
Tester::Tester(RubySystem* sys_ptr)
|
||||||
{
|
{
|
||||||
if (g_SIMICS) {
|
if (g_SIMULATING) {
|
||||||
ERROR_MSG("g_SIMICS should not be defined.");
|
ERROR_MSG("g_SIMULATING should not be defined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
g_callback_counter = 0;
|
g_callback_counter = 0;
|
||||||
|
|
|
@ -43,8 +43,8 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if (g_SIMICS) {
|
if (g_SIMULATING) {
|
||||||
ERROR_MSG("g_SIMICS should not be defined.");
|
ERROR_MSG("g_SIMULATING should not be defined.");
|
||||||
}
|
}
|
||||||
|
|
||||||
tester_main(argc, argv);
|
tester_main(argc, argv);
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include "protocol_name.hh"
|
#include "protocol_name.hh"
|
||||||
#include "test_framework.hh"
|
#include "test_framework.hh"
|
||||||
#include "System.hh"
|
#include "System.hh"
|
||||||
#include "OpalInterface.hh"
|
|
||||||
#include "init.hh"
|
#include "init.hh"
|
||||||
#include "Tester.hh"
|
#include "Tester.hh"
|
||||||
#include "RubyEventQueue.hh"
|
#include "RubyEventQueue.hh"
|
||||||
|
@ -157,11 +156,7 @@ void tester_destroy()
|
||||||
|
|
||||||
void tester_install_opal(mf_opal_api_t* opal_api, mf_ruby_api_t* ruby_api)
|
void tester_install_opal(mf_opal_api_t* opal_api, mf_ruby_api_t* ruby_api)
|
||||||
{
|
{
|
||||||
// initialize our api interface
|
std::cout << __FILE__ << "(" << __LINE__ << "): Not implemented" << std::endl;
|
||||||
OpalInterface::installInterface(ruby_api);
|
|
||||||
|
|
||||||
// update the OpalInterface object to point to opal's interface
|
|
||||||
((OpalInterface *) g_system_ptr->getDriver())->setOpalInterface(opal_api);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tester_record_cache()
|
void tester_record_cache()
|
||||||
|
|
Loading…
Reference in a new issue