Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / n2 / dev / pioasi / src / N2_PioAsi.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: N2_PioAsi.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 ============================================
#include <iostream>
#include <unistd.h>
#include "N2_PioAsi.h"
#include "N2_Model.h"
#include "SS_Io.h"
#include "N2_Cpu.h"
#include "N2_Core.h"
#include "N2_Strand.h"
using namespace std;
N2_PioAsi::N2_PioAsi( N2_Model* _model, SS_AddressMap* map, SS_Paddr lo, SS_Paddr hi )/*{{{*/
:
model(_model),
base(lo)
{
//TODO is it too much to register the entire block from 0x9001040000 to
// 0x9001cc0000?
// NCU_ASI_COREAVAIL = 0x9001040000;
// NCU_ASI_CORE_ENABLE_STATUS = 0x9001040010;
// NCU_ASI_CORE_ENABLE = 0x9001040020;
// NCU_ASI_XIR_STEERING = 0x9001040030;
// NCU_ASI_TICK_ENABLE = 0x9001040038;
// NCU_ASI_CORE_RUNNINGRW = 0x9001040050;
// NCU_ASI_CORE_RUNNING_STATUS = 0x9001040058;
// NCU_ASI_CORE_RUNNING_W1S = 0x9001040060;
// NCU_ASI_CORE_RUNNING_W1C = 0x9001040068;
// NCU_ASI_OVERLAP_MODE = 0x9001140010;
// NCU_ASI_WMR_VEC_MASK = 0x9001140018;
// NCU_ASI_INTVECDISP = 0x9001cc0000;
if ((lo != 0x9001040000) || (hi != 0x9001cc0000+7))
{
cerr << "ERROR: N2_PioAsi (0x9001040000..0x9001cc0000) being given wrong range, lo=0x" << hex << lo << " hi=0x" << hi << endl;
return;
}
map->add(lo,hi,this,SS_AddressMap::REL,N2_PioAsi::access);
}
/*}}}*/
N2_PioAsi::~N2_PioAsi()/*{{{*/
{
}
/*}}}*/
void N2_PioAsi::access( void* obj, uint_t sid, SS_Access::Type type, SS_Paddr pa, uint_t size, uint64_t* data )/*{{{*/
{
N2_PioAsi* self = (N2_PioAsi*)obj;
pa += self->base;
// PA[39:32] = 0x90
// PA[31:29] = core_id[2:0] (physical core id)
// PA[28:26] = tid[2:0] (thread id within a core)
// PA[25:18] = asi[7:0]
// PA[17:3] = VA[17:3]
// PA[2:0] = 000
int tid = (pa >> 26) & 0x3f;
int asi = (pa >> 18) & 0xff;
int va = ((pa >> 3) & 0x7fff) << 3;
SS_Strand* strand = self->model->cpu[0]->strand[tid];
switch (type)
{
case SS_Access::LOAD:
strand->asi_map.ld64(strand, asi, va, data);
break;
case SS_Access::STORE:
strand->asi_map.st64(strand, asi, va, *data);
break;
default:
assert(0);
}
}
/*}}}*/