Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / memsync / src / TsoNode.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: TsoNode.h
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
*
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ========== Copyright Header End ============================================
*/
#ifndef _TSONODE_H
#define _TSONODE_H
/************************************************************************
**
** Copyright (C) 2002, Sun Microsystems, Inc.
**
** Sun considers its source code as an unpublished, proprietary
** trade secret and it is available only under strict license provisions.
** This copyright notice is placed here only to protect Sun in the event
** the source is deemed a published work. Disassembly, decompilation,
** or other means of reducing the object code to human readable form
** is prohibited by the license agreement under which this code is
** provided to the user or company in possession of this copy."
**
*************************************************************************/
#include <iostream>
#include "MemorySyncDefs.h"
#include <list>
#include "TsoCheckerDefs.h"
#include "TsoEdge.h"
#include "TsoCheckerCmd.h"
namespace Tso {
class TsoEdge;
class TsoNode {
public:
/**
* Default constructor
*/
TsoNode();
/**
* constructor
*/
TsoNode(const TsoCheckerCmd& cmd);
/**
* Copy constructor
*
* @param orig The TsoNode object to copy.
*/
TsoNode( const TsoNode &orig );
/**
* Destructor
*/
virtual ~TsoNode();
/**
* Equality operator
*
* @param rhs The right hand side of the equality operator
* @return Return true if this objec and rhs are equal,
* otherwise return false
*/
bool operator==( const TsoNode &rhs ) const;
/**
* Assignment operator
*
* @param rhs The right hand side of the assignment operator.
* @return The lvalue of the assignment.
*/
const TsoNode & operator=( const TsoNode &rhs );
/**
* Return a string representation of this TsoNode object.
*/
std::string toString() const;
/**
* Remove all edge pointers in the in_ list. The function also removes the
* edge pointer in the edge's source node's out_ list.
*/
void removeInEdges();
/**
* Remove all edge pointers in the out_ list. The function also removes the
* edge pointer in the edge's destination node's in_ list.
*/
void removeOutEdges();
/**
* Remove all edge pointers in the in_ & out_ list. This method calls
* removeInEdges() and removeOutEdges().
*/
void removeEdges();
/**
* Check to see if all nodes corresponding to the node's instructions has
* arrived or not.
* @return a boolean to relect this check
*/
bool allEntriesArrive();
/**
* Check to see if the node coresponds to a store instruction
* Note that atomic is also counted as a store instruction.
* @return a boolean to relect this check
*/
isStore() { return (itype_ == ITYPE_STORE ||
itype_ == ITYPE_BLOCK_STORE ||
itype_ == ITYPE_STORE_INIT ||
itype_ == ITYPE_ATOMIC); }
/**
* Check to see if the node coresponds to a load instruction
* Note that atomic is also counted as a load instruction.
* @return a boolean to relect this check
*/
isLoad() { return (itype_ == ITYPE_LOAD ||
itype_ == ITYPE_BLOCK_LOAD ||
itype_ == ITYPE_QUAD_LOAD ||
itype_ == ITYPE_DOUBLE_LOAD ||
itype_ == ITYPE_ATOMIC); }
/**
* Check to see if the node coresponds to a RMO instruction
* @return a boolean to relect this check
*/
isRMO() { return (itype_ == ITYPE_BLOCK_STORE ||
itype_ == ITYPE_STORE_INIT ||
itype_ == ITYPE_BLOCK_LOAD); }
/**
* Check to see if the node coresponds to an atomic instruction
* @return a boolean to relect this check
*/
isAtomic() { return (itype_ == ITYPE_ATOMIC); }
/**
* Check to see if the node's addres is in I/O range
* @return a boolean to relect this check
*/
isIO() { return ((addr_ & IO_ADDR_BIT_MASK) != 0); }
/**
* Check to see if the node corresponds to a TSO load instruction
* A TSO load is defined as a load whose address is not in I/O space
* and is not a RMO load
* @return a boolean
*/
isTsoLoad() { return (isLoad() && !isRMO() && !isIO()); }
/**
* Check to see if the node corresponds to a TSO store instruction
* A TSO store is defined as a store whose address is not in I/O space
* and is not a RMO store
* @return a boolean
*/
isTsoStore() { return (isStore() && !isRMO() && !isIO()); }
/**
* Check to see if the node corresponds to a TSO instruction
* A TSO instruciton is defined as an instruction whose address is not
* in I/O space and is not a RMO instruction
* @return a boolean
*/
isTSO() { return (isTsoLoad() || isTsoStore()); }
/**
* Check the if the node is MEM_STORE_COMMIT
* @return a bollena
*/
isStoreCommit() { return (cmd_ == MEM_STORE_COMMIT); }
/**
* Check the if the node is MEM_LOAD_DATA
* @return a bollena
*/
isLoadData() { return (cmd_ == MEM_LOAD_DATA); }
/**
* Get the begin iterator of the in_ list
*/
std::list<TsoEdge*>::iterator inBegin() { return in_.begin(); };
/**
* Get the end iterator of the in_ list
*/
std::list<TsoEdge*>::iterator inEnd() { return in_.end(); }
/**
* Get the begin iterator of the out_ list
*/
std::list<TsoEdge*>::iterator outBegin() { return out_.begin(); }
/**
* Get the end iterator of the out_ list
*/
std::list<TsoEdge*>::iterator outEnd() { return out_.end(); }
/**
* Get the size of in_
*/
std::list<TsoEdge*>::size_type inSize() { return in_.size(); }
/**
* Get the size of out_
*/
std::list<TsoEdge*>::size_type outSize() { return out_.size(); }
/**
* Push an edge point to the front of the in_ list
* @param edge The edge pointer to be pushed
*/
void inPushFront (TsoEdge* edge) { in_.push_front(edge); }
/**
* Push an edge point to the front of the out_ list
* @param edge The edge pointer to be pushed
*/
void outPushFront (TsoEdge* edge) { out_.push_front(edge); }
/**
* Erase in_ entry
* @param ei The iterator whose corresponding entry is to be erase
*/
void inErase(std::list<TsoEdge*>::iterator ei) { in_.erase(ei); }
/**
* Erase out_ entry
* @param ei The iterator whose corresponding entry is to be erase
*/
void outErase(std::list<TsoEdge*>::iterator ei) { out_.erase(ei); }
/**
* Clear all entries in in_ list
*/
void inClear() { in_.clear(); }
/**
* Clear all entries in out_ list
*/
void outClear() { out_.clear(); }
/**
* Push a node pointer to the back of the nodes_ list
* @param np The node pointer to be pushed
*/
void nodePush (TsoNode* np) { nodes_.push_back(np); };
/******************************************************************
* Private variable get/set methods
******************************************************************/
void setIseq (uint64_t iseq) { iseq_ = iseq; }
void setCommit (uint64_t commit) { commit_ = commit; }
void setGobs (uint64_t gobs) { gobs_ = gobs; }
void setRetire (uint64_t retire) { retire_ = retire; }
void setAddr (uint64_t addr) { addr_ = addr; }
void setData (uint64_t data) { data_ = data; }
void setNcnt (uint32_t ncnt) { ncnt_ = ncnt; }
void incNcnt () { ncnt_++; }
void setThrdId (uint32_t tid) { tid_ = tid; }
void setItype (enum INSTR_TYPE itype) { itype_ = itype; }
void setCmd (enum MEM_CMD cmd) { cmd_ = cmd; }
void setNtype (enum MEM_CMD ntype) { cmd_ = ntype; }
void setDsrc (enum DATA_SRC dsrc) { dsrc_ = dsrc; }
void setSizeV (uint8_t sizeV) { sizeV_ = sizeV; }
void setOld (uint8_t old) { old_ = old; }
void orOld (uint8_t old) { old_ = old_ | old; }
void setLastStore (bool tf) { lastStore_ = tf; }
void setLastLoad (bool tf) { lastLoad_ = tf; }
char* getNodeName() { return nodeName_; }
uint64_t getIseq() const { return iseq_; }
uint64_t getCommit() const { return commit_; }
uint64_t getGobs() const { return gobs_; }
uint64_t getRetire() const { return retire_; }
uint64_t getAddr() const { return addr_; }
uint64_t getData() const { return data_; }
uint32_t getNcnt() const { return ncnt_; }
uint32_t getThrdId() const { return tid_; }
enum INSTR_TYPE getItype() const { return itype_; }
enum MEM_CMD getCmd() const { return cmd_; }
enum MEM_CMD getNtype() const { return cmd_; }
enum DATA_SRC getDsrc() const { return dsrc_; }
uint8_t getSizeV() const { return sizeV_; }
uint8_t getOld() const { return old_; }
bool noInEdges() const { return (in_.empty()); }
bool noOutEdges() const { return (out_.empty()); }
bool hasInEdges() const { return (!in_.empty()); }
bool hasOutEdges() const { return (!out_.empty()); }
bool isAllOld() const { return ((sizeV_ ^ old_) == 0); }
bool isLastStore() const { return lastStore_; }
bool isLastLoad() const { return lastLoad_; }
protected:
private:
/**
* nodeName_, node's name, is used as the node lable in TSO digraph
*/
char nodeName_[150];
/**
* in_ contains the pointers of edges coming to this node
*/
std::list<TsoEdge*> in_;
/**
* out_ contains the pointers of edges coming from this node
*/
std::list<TsoEdge*> out_;
/**
* nodes_ contains the pointers of nodes that belong to the same instruction as this node.
*/
std::list<TsoNode*> nodes_; // additional TSO nodes for atomic/quad load, block load/store
/**
* iseq_ is the load/store instruction sequence, must consecutive
* but can be out-of-order
*/
uint64_t iseq_; // load/store instruction sequence number
/**
* commit_ has different definitions for store and load. <br>
* <p>
* For store it is the time when a store commits (for N2,
* it is the time when the data is written into L2 and can be seen
* by other L2 access). <br>
* <p>
* For load, it is any time in the duration when the whole data can
* be seen in the L2 access. Note the source of a load may come from
* several stores.
* <p> This variable has the same meaning as macc_ in TsoCheckerCmd.h
* @see TsoCheckerCmd.h
*/
uint64_t commit_;
/**
* gobs_ is the global observed time of a store. Note that a store
* may have stale data in L1 caches of other cores, or caches of
* other chips. Before a store data can be globally observed, all
* those stale data must be either invalidated or be updated. <br>
* <p>
* The gobs_ must be no earlier than its L2 commit time, commit_.
*/
uint64_t gobs_;
/**
* retire_ is the time when the node can be retired. Note that different
* byte of data may have different retire time. This records the latest.
*/
uint64_t retire_;
/**
* addr_ is the physical address.
*/
uint64_t addr_; // address
/**
* data_ is either the load data or store data.
*/
uint64_t data_; // data
/**
* ncnt_ equals nnodes_.size() + 1 (itself)
*/
uint32_t ncnt_;
/**
* tid_ is a flat thread ID; each thread must have a unique ID.
*/
uint32_t tid_; // thread ID
/**
* itype_ is the instruction type, such as load, store, block load/store,
* etc, whose definition is in
* @see MemorySyncDefs.h
*/
enum INSTR_TYPE itype_; // instruction type
/**
* cmd_ is the entry type, such as StoreCommit and LoadData, whose
* defintion is in
* @see MemorySyncDefs.h
*/
enum MEM_CMD cmd_; // command
/**
* dsrc_ is the source of a load data, which could be L1, STB, or
* L2/Memory.
* @see MemorySyncDefs.h
*/
enum DATA_SRC dsrc_; // data source
/**
* The data format is as follows: (Big Edian)
*
* bit 63 0
* +--------+--------+------------+--------+
* data | byte 0 | byte 1 | --- | byte 7 |
* (64 bits) +--------+--------+------------+--------+
*
* sizeV_: bit 7 bit 6 bit 0
* (8 bits)
*
* sizeV_ is to indicates which byte is valid: bit 0 for data_[7:0],
* bit 1 for data_[15:8], and so on.
*/
uint8_t sizeV_; // size vector: 1 -> valid byte
/**
* old_ indicates if the corresponding byte of data in this node is old or not.
* Similar to sizeV_, bit 0 is the indicator of data_[7:0]; bit 1, data_[15:8],
* and so on.
*/
uint8_t old_; // bit vector: 1 -> old data in MemoryAccessHistory
/**
* lastStore_ indicates if the node is the last store in the program order list,
* nodeList_ in TsoChecker.h, or not.
* @see TsoChecker.h
*/
bool lastStore_; // need both lastStore_ and lastLoad_ is because atomic
/**
* lastStore_ indicates if the node is the last load in the program order list,
* nodeList_ in TsoChecker.h, or not.
* @see TsoChecker.h
*/
bool lastLoad_; // can have both
};
} /* namespace Tso */
#endif /* _TSONODE_H */