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:
Dan Gibson 2009-05-11 10:38:45 -07:00
parent 6ceaffd724
commit d8c592a05d
42 changed files with 442 additions and 9365 deletions

View file

@ -59,8 +59,6 @@ using namespace std;
// #endif // #endif
// }; // };
#include "FakeSimicsDataTypes.hh"
#include "confio.hh" #include "confio.hh"
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/

View file

@ -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 ));
}

View file

@ -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;
}; };

View file

@ -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

View file

@ -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;
}
}

View file

@ -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");
}
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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

View file

@ -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;

View file

@ -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 );

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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())
{ {

View file

@ -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

View file

@ -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

View file

@ -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;
} }

View file

@ -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
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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"

View file

@ -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());

View file

@ -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>

View file

@ -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;

View file

@ -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;
} }
} }

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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?

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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()