Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / n2 / lib / csr / src / N2_NcuCsr.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: N2_NcuCsr.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) 2005, 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 "N2_NcuCsr.h"
#include "N2_Strand.h"
#include "N2_Csr.h"
#include "N2_Model.h"
using namespace std;
const uint64_t N2_NcuCsr::NCU_ASI_COREAVAIL;
const uint64_t N2_NcuCsr::NCU_ASI_CORE_ENABLE_STATUS;
const uint64_t N2_NcuCsr::NCU_ASI_CORE_ENABLE;
const uint64_t N2_NcuCsr::NCU_ASI_XIR_STEERING;
const uint64_t N2_NcuCsr::NCU_ASI_CORE_RUNNINGRW;
const uint64_t N2_NcuCsr::NCU_ASI_CORE_RUNNING_STATUS;
const uint64_t N2_NcuCsr::NCU_ASI_CORE_RUNNING_W1S;
const uint64_t N2_NcuCsr::NCU_ASI_CORE_RUNNING_W1C;
const uint64_t N2_NcuCsr::NCU_ASI_INTVECDISP;
const uint64_t N2_NcuCsr::NCU_ASI_TICK_ENABLE;
const uint64_t N2_NcuCsr::NCU_ASI_OVERLAP_MODE;
const uint64_t N2_NcuCsr::NCU_ASI_WMR_VEC_MASK;
RegisterAttribute N2_NcuCsr::attributeTable[] = {
{ 0x8000000000ULL,0x80000003f8ULL,0x8ULL,128,0x0ULL,0x0ULL,RegisterAttribute::RO,0xffffffffffffc0c0ULL,0x0ULL,0x3f3fULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_INTMAN","count 128 step 8" },
{ 0x8000000a00ULL,0x8000000a00ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0xffffffffffffffc0ULL,0x0ULL,0x3fULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MONDOINVEC","" },
{ 0x8000001000ULL,0x8000001000ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_SERNUM","",true },
{ 0x8000001008ULL,0x8000001008ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_FUSESTAT","" },
{ 0x8000001010ULL,0x8000001010ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_COREAVAIL","" },
{ 0x8000001018ULL,0x8000001018ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0xffffffffffffff00ULL,0x0ULL,0xffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_BANKAVAIL","" },
{ 0x8000001020ULL,0x8000001020ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0xffffffffffffff00ULL,0x0ULL,0xffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_BANK_ENABLE","", true },
{ 0x8000001028ULL,0x8000001028ULL,0x8ULL,1,0x1010ULL,0x1010ULL,RegisterAttribute::RO,0xffffffffffffe000ULL,0x0ULL,0x1fffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_BANK_ENABLE_STATUS","see the explain at end re: warm",true },
{ 0x8000001030ULL,0x8000001030ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0xfffffffffffffffeULL,0x0ULL,0x1ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_L2_IDX_HASH_EN","" },
{ 0x8000001038ULL,0x8000001038ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0xfffffffffffffffeULL,0x0ULL,0x1ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_L2_IDX_HASH_STATUS","value of L2_IDX_HASH_EN for warm",true },
{ 0x8000002000ULL,0x8000002000ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x7ffffff000ffffffULL,0x0ULL,0x8000000fff000000ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MEM32_BASE","" },
{ 0x8000002008ULL,0x8000002008ULL,0x8ULL,1,0xf000000000ULL,0xf000000000ULL,RegisterAttribute::RW,0xffffff0000ffffffULL,0xf000000000ULL,0xfff000000ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MEM32_MASK","" },
{ 0x8000002010ULL,0x8000002010ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x7ffffff000ffffffULL,0x0ULL,0x8000000fff000000ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MEM64_BASE","" },
{ 0x8000002018ULL,0x8000002018ULL,0x8ULL,1,0xf000000000ULL,0xf000000000ULL,RegisterAttribute::RW,0xffffff0000ffffffULL,0xf000000000ULL,0xfff000000ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MEM64_MASK","" },
{ 0x8000002020ULL,0x8000002020ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x7ffffff000ffffffULL,0x0ULL,0x8000000fff000000ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_IOCON_BASE","" },
{ 0x8000002028ULL,0x8000002028ULL,0x8ULL,1,0xf000000000ULL,0xf000000000ULL,RegisterAttribute::RW,0xffffff0000ffffffULL,0xf000000000ULL,0xfff000000ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_IOCON_MASK","" },
{ 0x8000002030ULL,0x8000002030ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MMUFSH","" },
{ 0x8000003000ULL,0x8000003000ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x7ffff89240000000ULL,0x0ULL,0x8000076dbfffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_ESR","" },
{ 0x8000003008ULL,0x8000003008ULL,0x8ULL,1,0x7ffffffffffULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_ELE","" },
{ 0x8000003010ULL,0x8000003010ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_EIE","" },
{ 0x8000003018ULL,0x8000003018ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_SOC_EJR","",true },
{ 0x8000003020ULL,0x8000003020ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_FEE","", true },
{ 0x8000003028ULL,0x8000003028ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_PER","" },
{ 0x8000003030ULL,0x8000003030ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x7800000000000000ULL,0x0ULL,0x87ffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_SIISYN","" },
{ 0x8000003038ULL,0x8000003038ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x300000000000000ULL,0x0ULL,0xfcffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_NCUSYN","this register have 2 format" },
{ 0x8000040000ULL,0x8000040000ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MDATA0","" },
{ 0x8000040200ULL,0x8000040200ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MDATA1","" },
{ 0x8000040400ULL,0x8000040400ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MDATA0_ALIAS","" },
{ 0x8000040600ULL,0x8000040600ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MDATA1_ALIAS","" },
{ 0x8000040800ULL,0x8000040800ULL,0x8ULL,1,0x40ULL,0x40ULL,RegisterAttribute::RW,0xffffffffffffffbfULL,0x0ULL,0x40ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MBUSY","" },
{ 0x8000040a00ULL,0x8000040a00ULL,0x8ULL,1,0x40ULL,0x40ULL,RegisterAttribute::RW,0xffffffffffffffbfULL,0x0ULL,0x40ULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_CREG_MBUSY_ALIAS","" },
{ 0x9001040000ULL,0x9001040000ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_COREAVAIL","" },
{ 0x9001040010ULL,0x9001040010ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_CORE_ENABLE_STATUS","value of CORE_ENABLE for warm" },
{ 0x9001040020ULL,0x9001040020ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_CORE_ENABLE","" },
{ 0x9001040030ULL,0x9001040030ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_XIR_STEERING","" },
{ 0x9001040050ULL,0x9001040050ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RW,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_CORE_RUNNINGRW","" },
{ 0x9001040058ULL,0x9001040058ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::RO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_CORE_RUNNING_STATUS","value of RUNNINGRW for warm" },
{ 0x9001040060ULL,0x9001040060ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::WO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_CORE_RUNNING_W1S","" },
{ 0x9001040068ULL,0x9001040068ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::WO,0x0ULL,0x0ULL,0xffffffffffffffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_CORE_RUNNING_W1C","" },
{ 0x9001cc0000ULL,0x9001cc0000ULL,0x8ULL,1,0x0ULL,0x0ULL,RegisterAttribute::WO,0xfffffffffffc0000ULL,0x0ULL,0x3ffffULL,0x0ULL,0x0ULL,0x0ULL,"N2_NCU_ASI_INTVECDISP","" }
};
const int N2_NcuCsr::NUMBER_ENTRIES = sizeof(N2_NcuCsr::attributeTable)/sizeof(N2_NcuCsr::attributeTable[0]);
//======================================================================
//======================================================================
N2_NcuCsr::N2_NcuCsr() :
SS_BaseCsr("N2_NcuCsr", attributeTable, NUMBER_ENTRIES)
{
}
//======================================================================
//======================================================================
int
N2_NcuCsr::read64( SS_Paddr paddr, uint64_t* data, int access, int sid )
{
SS_Paddr laddr;
SS_Paddr gaddr;
if (is_global_addr(paddr))
{
laddr = global2local(paddr);
gaddr = paddr;
}
else if (sid < 0)
{
// if it is not a global address, then we need a real strand-id to
// convert the address to global address, otherwise it is an error.
fprintf(stderr, "ERROR: N2_NcuCsr::read64( paddr=%#llx, sid=%d ): paddr not a global addr\n", paddr, sid);
return 0x0;
}
else
{
laddr = paddr;
gaddr = local2global(paddr, sid);
}
int nid = get_node_id(gaddr);
list<FollowMeData>::iterator iter = followme_.begin();
for (; iter != followme_.end(); iter++)
{
if (((*iter).addr == gaddr) && (((*iter).sid == sid) || (sid < 0)))
{
*data = (*iter).data;
followme_.erase(iter);
return SS_Io::FOLLOWME;
}
}
switch (paddr)
{
case NCU_ASI_COREAVAIL:
case NCU_ASI_CORE_ENABLE_STATUS:
case NCU_ASI_CORE_ENABLE:
case NCU_ASI_XIR_STEERING:
case NCU_ASI_CORE_RUNNINGRW:
case NCU_ASI_CORE_RUNNING_STATUS:
case NCU_ASI_CORE_RUNNING_W1S:
case NCU_ASI_CORE_RUNNING_W1C:
case NCU_ASI_INTVECDISP:
case NCU_ASI_TICK_ENABLE:
case NCU_ASI_OVERLAP_MODE:
case NCU_ASI_WMR_VEC_MASK:
*data = io2asiRead(paddr);
return SS_Io::OK;
break;
default:
return SS_BaseCsr::read64(paddr, data, access, sid);
break;
}
}
//======================================================================
//======================================================================
int
N2_NcuCsr::write64( SS_Paddr paddr, uint64_t data, int access, int sid )
{
SS_Paddr laddr;
SS_Paddr gaddr;
if (is_global_addr(paddr))
{
laddr = global2local(paddr);
gaddr = paddr;
}
else if (sid < 0)
{
// if it is not a global address, then we need a real strand-id to
// convert the address to global address, otherwise it is an error.
fprintf(stderr, "ERROR: Vf_CmpCsr::write64( paddr=%#llx, sid=%d ): paddr not a global addr\n", paddr, sid);
return SS_Io::NOP;
}
else
{
laddr = paddr;
gaddr = local2global(paddr, sid);
}
int nid = get_node_id(gaddr);
if (access & MemoryTransaction::FOLLOW_ME)
{
// this is a follow-me write, keep the value in followme_ list
FollowMeData fm(gaddr, data, sid);
followme_.push_back(fm);
return SS_Io::OK;
}
switch (paddr)
{
case NCU_ASI_COREAVAIL:
case NCU_ASI_CORE_ENABLE_STATUS:
case NCU_ASI_CORE_ENABLE:
case NCU_ASI_XIR_STEERING:
case NCU_ASI_CORE_RUNNINGRW:
case NCU_ASI_CORE_RUNNING_STATUS:
case NCU_ASI_CORE_RUNNING_W1S:
case NCU_ASI_CORE_RUNNING_W1C:
case NCU_ASI_INTVECDISP:
case NCU_ASI_TICK_ENABLE:
case NCU_ASI_OVERLAP_MODE:
case NCU_ASI_WMR_VEC_MASK:
io2asiWrite(paddr, data);
return SS_Io::OK;
break;
default:
return SS_BaseCsr::write64(paddr, data, access, sid);
break;
}
}
//=============================================================================
//=============================================================================
uint64_t
N2_NcuCsr::io2asiRead(SS_Paddr paddr)
{
// PA[39:32] = 0x90
// PA[31:29] = core_id[2:0] (physical core id)
// PA[28:26] = tid[2:0] (thread id)
// PA[25:18] = asi[7:0]
// PA[17:3] = VA[17:3]
// PA[2:0] = 000
int strandid = (paddr >> 26) & 0x3f;
int asi = (paddr >> 18) & 0xff;
int va = ((paddr >> 3) & 0x7fff) << 3;
N2_Strand* strand = N2_Csr::model->strand_ptr(strandid);
uint64_t data;
strand->asi_map.rd64(strand, asi, va, &data);
return data;
}
//=============================================================================
//=============================================================================
void
N2_NcuCsr::io2asiWrite(SS_Paddr paddr, uint64_t value)
{
// PA[39:32] = 0x90
// PA[31:29] = core_id[2:0] (physical core id)
// PA[28:26] = tid[2:0] (thread id)
// PA[25:18] = asi[7:0]
// PA[17:3] = VA[17:3]
// PA[2:0] = 000
int strandid = (paddr >> 26) & 0x3f;
int asi = (paddr >> 18) & 0xff;
int va = ((paddr >> 3) & 0x7fff) << 3;
N2_Strand* strand = N2_Csr::model->strand_ptr(strandid);
strand->asi_map.wr64(strand, asi, va, value);
return;
}
//======================================================================
//======================================================================
void N2_NcuCsr::regAddrSpace()
{
const static std::string descr("N2_NcuCsr address space");
for (uint i = 0; i < NUMBER_ENTRIES; ++i)
{
if (attributeTable[i].ownAddressSpace)
{
registerAddressSpace(&attributeTable[i], 1, descr);
}
}
}