// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: LoadStoreCmd.cc
// 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 ============================================
/************************************************************************
** 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 "LoadStoreCmd.h"
////////////////////////////////////////////////
LoadStoreCmd::LoadStoreCmd() :
cmd_(MAX_MEM_CMDS
), itype_(ITYPE_NONE
), id_(0), cid_(0), tid_(0), srcTid_(0),
srcBank_(0), inv_(0), set_(0), way_(0), addr_(0), data_(0), vbyte_(0), size_(0),
dsrc_(DSRC_NONE
), cacheL1_(false), rmoStore_(false), l2hit_(false), switchData_(true),
ioaddr_(false), tsize(0),
LoadStoreCmd::LoadStoreCmd(enum MEM_CMD cmd
, enum INSTR_TYPE itype
, uint32_t cid
, uint32_t tid
,
uint32_t srcTid
, uint32_t srcBank
, uint32_t inv
, uint32_t set
,
uint32_t way
, uint64_t id
, uint64_t addr
, uint64_t data
,
uint8_t size
, enum DATA_SRC dsrc
, bool cacheL1
, bool rmoStore
,
bool l2hit
, bool switchData
, bool ioaddr
, uint64_t cycle
) :
cmd_(cmd
), itype_(itype
), id_(id
), cid_(cid
), tid_(tid
), srcTid_(srcTid
), srcBank_(srcBank
),
inv_(inv
), set_(set
), way_(way
), addr_(addr
), data_(data
), vbyte_(size_vector
), size_(size
),
dsrc_(dsrc
), cacheL1_(cacheL1
), rmoStore_(rmoStore
), l2hit_(l2hit
), switchData_(switchData
),
ioaddr_(ioaddr
), tsize(0),
////////////////////////////////////////////////
LoadStoreCmd::LoadStoreCmd( const LoadStoreCmd
& orig
)
// Replace the following line with your function body.
// RIESLING_THROW_DOMAIN_ERROR( "Unimplemented function." );
////////////////////////////////////////////////
LoadStoreCmd::~LoadStoreCmd()
////////////////////////////////////////////////
// LoadStoreCmd::operator=( const LoadStoreCmd & rhs )
// // Replace the following line with your function body.
// // RIESLING_THROW_DOMAIN_ERROR( "Unimplemented function." );
// ////////////////////////////////////////////////
// LoadStoreCmd::operator==( const LoadStoreCmd & rhs ) const
// // Replace the following line with your function body.
// // RIESLING_THROW_DOMAIN_ERROR( "Unimplemented function." );
////////////////////////////////////////////////
LoadStoreCmd::toString() const
os
<< " cmd=" << mmcmd
[cmd_
];
os
<< " i=" << mmitype
[itype_
];
os
<< " dsrc=" << mmdsrc
[dsrc_
];
os
<< " $L1=" << (int) cacheL1_
;
os
<< " io=" << (int) ioaddr_
;
os
<< " rmo=" << (int) rmoStore_
;
os
<< " l2hit=" << (int) l2hit_
;
os
<< " cid=" << dec
<< cid_
;
os
<< " stid=" << srcTid_
;
os
<< " bank=" << srcBank_
;
os
<< " inv=0x" << hex
<< inv_
;
os
<< " s=" << dec
<< set_
;
os
<< " a=0x" << hex
<< addr_
;
os
<< " vb=0x" << (int) vbyte_
;
os
<< " sz=" << dec
<< (int) size_
;
os
<< " cas=" << dec
<< (int) switchData_
;
os
<< " cycle=" << cycle_
;
LoadStoreCmd::auxInit () {
ioaddr_
= ((addr_
& IO_ADDR_BIT_MASK
) != 0);
if (!rmoStore_
) { // some command does not send rmoStore, use itype
rmoStore_
= (itype_
== ITYPE_BLOCK_STORE
|| itype_
== ITYPE_STORE_INIT
) ? true : false;
MemorySyncMessage::rtlCycle
= cycle_
;
MSYNC_DEBUG(1, "%s", toString().c_str());
/* implement big endian */
LoadStoreCmd::sz2szv (uint8_t size
, uint32_t aoffset
)
MSYNC_DEBUG(4, "sz2szv->addr_offset=0x%x size=%d", aoffset
, (int) size
);
assert((aoffset
& 0x7) == 0);
assert((aoffset
& 0x3) == 0);
size_vector
= 0xf0 >> (aoffset
& 0x7);
assert((aoffset
& 0x1) == 0);
size_vector
= 0xc0 >> (aoffset
& 0x7);
size_vector
= 0x80 >> (aoffset
& 0x7);
/* size = number of 1s for normal store, = 8 for partial store */
LoadStoreCmd::szv2sz (uint8_t size_vector
)
/* size = number of 1s for normal store, = 8 for partial store */
for (i
= 0; i
< 8; i
++) {
if ((size_vector
>> i
) & 1 == 1)
if (patn10
) { // partial store
if ((size
!= 8) && (size
!= 4) && (size
!= 2) && (size
!= 1) && (size
!= 0)) {
LoadStoreCmd::sz2szlog (uint8_t size
)
/******************************************************************************
* The data format MemorySync model expects on STOREs is as follows: (Big Edian)
* +--------+--------+------------+--------+
* data | byte 0 | byte 1 | --- | byte 7 |
* (64 bits) +--------+--------+------------+--------+
* size_vector: bit 7 bit 6 bit 0
******************************************************************************/
/******************************************************************************
* A StoreIssueCmd is issued when a store is inserted into STB after address
******************************************************************************/
StoreIssueCmd::StoreIssueCmd(enum INSTR_TYPE itype
,
uint8_t size
= szv2sz(size_vector
);
setCoreId(tid
/NSTRANDS_PER_CORE
);
/******************************************************************************
* A StoreCommitCmd is issued when a store whose data is observed by other
******************************************************************************/
StoreCommitCmd::StoreCommitCmd(uint32_t tid
,
uint8_t size
= szv2sz(size_vector
);
setCmd(MEM_STORE_COMMIT
);
setSwitchData(switchData
);
setCoreId(tid
/NSTRANDS_PER_CORE
);
setSrcBank((addr
& L2_BANK_ADDR_BITS
) >> L2_BANK_ADDR_SFT
);
/******************************************************************************
* A StoreInv is issued when an invalidation is performed on its L1 cache
******************************************************************************/
StoreInvCmd::StoreInvCmd(uint32_t cid
,
setThrdId(cid
*NSTRANDS_PER_CORE
);
/******************************************************************************
* A StoreUpdate is issued when a update is performed on its L1 cache
******************************************************************************/
StoreUpdateCmd::StoreUpdateCmd(uint32_t tid
,
setCmd(MEM_STORE_UPDATE
);
setCoreId(tid
/NSTRANDS_PER_CORE
);
/* srcTid is set to tid, which allows the handle routine to share
MemoryAccssBuffer::findStoreInvSrc() to find the corresponding
/******************************************************************************
* A StoreAck is issued when a thread receives the Ack indicating to
* remove the store from the Store Buffer.
******************************************************************************/
StoreAckCmd::StoreAckCmd(uint32_t tid
,
setCoreId(tid
/NSTRANDS_PER_CORE
);
/* srcTid is set to tid, which allows the handle routine to share
MemoryAccssBuffer::findStoreInvSrc() to find the corresponding
/******************************************************************************
* A LoadIssue is issued when in RTL a load is issued from an in-order domain
* to an out-of-order domain
******************************************************************************/
LoadIssueCmd::LoadIssueCmd(enum INSTR_TYPE itype
,
MS_ERROR("LoadIssueCmd data size should be no greater than 8 bytes. tid=%d PA=%llx", tid
, addr
);
setCoreId(tid
/NSTRANDS_PER_CORE
);
uint8_t szv
= sz2szv(size
, addr
& (~ADDR_MASK
));
/******************************************************************************
* A LoadData is issued when a load gets its data
******************************************************************************/
LoadDataCmd::LoadDataCmd(uint32_t tid
,
MS_ERROR("LoadDataCmd data size should be no greater than 8 bytes. tid=%d PA=%llx", tid
, addr
);
setCoreId(tid
/NSTRANDS_PER_CORE
);
uint8_t szv
= sz2szv(size
, addr
& (~ADDR_MASK
));
setSrcBank((addr
& L2_BANK_ADDR_BITS
) >> L2_BANK_ADDR_SFT
);
/******************************************************************************
* A LoadFill is issued when a line is filled into L1 and the new data can be
* seen by next access from the same core
******************************************************************************/
LoadFillCmd::LoadFillCmd(uint32_t tid
,
setCoreId(tid
/NSTRANDS_PER_CORE
);
/******************************************************************************
* An Evict is issued When a line is evicted from L2 which'll in turn
******************************************************************************/
EvictCmd::EvictCmd(uint32_t inv
,
setSrcBank((addr
& L2_BANK_ADDR_BITS
) >> L2_BANK_ADDR_SFT
);
/******************************************************************************
* A EvictInv is issued when an invalidation is performed on its L1 cache
******************************************************************************/
EvictInvCmd::EvictInvCmd(uint32_t cid
,
setThrdId(cid
*NSTRANDS_PER_CORE
);
/******************************************************************************
* A FetchIssue is issued when an instruction fetch is issued, every instruction
* should have one FetchIssue
******************************************************************************/
FetchIssueCmd::FetchIssueCmd(enum INSTR_TYPE itype
,
MS_ERROR("FetchIssueCmd data size should be no greater than 8 bytes. tid=%d PA=%llx", tid
, addr
);
setCoreId(tid
/NSTRANDS_PER_CORE
);
uint8_t szv
= sz2szv(size
, addr
& (~ADDR_MASK
));
/******************************************************************************
* A FetchData is issued when a fetch gets its data
******************************************************************************/
FetchDataCmd::FetchDataCmd(uint32_t tid
,
MS_ERROR("FetchDataCmd data size should be no greater than 8 bytes. tid=%d PA=%llx", tid
, addr
);
setCoreId(tid
/NSTRANDS_PER_CORE
);
uint8_t szv
= sz2szv(size
, addr
& (~ADDR_MASK
));
setSrcBank((addr
& L2_BANK_ADDR_BITS
) >> L2_BANK_ADDR_SFT
);
/******************************************************************************
* A FetchFill is issued when a fetched line is filled into L1 I$ and the
* new instruction can be seen by next access from the same core
******************************************************************************/
FetchFillCmd::FetchFillCmd(uint32_t tid
,
setCoreId(tid
/NSTRANDS_PER_CORE
);
/******************************************************************************
* A DmaStoreCmd is issued when a dma_store command is issued, it is treated
* almost like a mem_slam, but with inv_vec to handle L1 conflict.
******************************************************************************/
DmaStoreCmd::DmaStoreCmd(uint32_t tid
,
uint8_t size
= szv2sz(size_vector
);
setCoreId(tid
/NSTRANDS_PER_CORE
);
setSrcBank((addr
& L2_BANK_ADDR_BITS
) >> L2_BANK_ADDR_SFT
);