Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_AsiMap.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_AsiMap.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 "SS_AsiMap.h"
#include "SS_Strand.h"
#include <stdio.h>
SS_AsiMap::SS_AsiMap()/*{{{*/
:
asi_rd(0)
{
for (int ndx = 0; ndx < SS_Asi::MAX; ++ndx)
{
table[ndx].asi = ndx;
}
}
/*}}}*/
void SS_AsiMap::merge( SS_AsiMap& asi_map )/*{{{*/
{
for (uint_t asi=0; asi < SS_Asi::MAX; asi++)
table[asi].merge(asi_map.table[asi]);
}
/*}}}*/
void SS_AsiMap::set_mask( SS_Vaddr mask )/*{{{*/
{
for (uint_t asi=0; asi < SS_Asi::MAX; asi++)
table[asi].set_mask(mask);
}
/*}}}*/
SS_AsiSpace::Error SS_AsiMap::ld64( SS_Strand* s, uint8_t asi, SS_Vaddr addr, uint64_t* data )
{
SS_AsiSpace::Error ok = table[asi].ld64(s,addr,data);
// @@ha144505, really in cosim we want control over when a loaded value can
// be blown away by value sync (follow me). ToDo: return say NO_VALUE from ld64
// whan the returned value is allowed to get the data from the DUT.
if (ok == SS_AsiSpace::OK)
{
if (asi_rd)
{
addr &= table[asi].get_mask();
std::map<SS_Vaddr,std::list<uint64_t>*>::iterator i = (*asi_rd)[asi].find(addr);
if (i != (*asi_rd)[asi].end())
{
if ((*i).second->size())
{
uint64_t temp = (*i).second->front();
// asi_read follow-me is use-once-only, remove it after use
(*i).second->pop_front();
std::map<SS_Vaddr,uint64_t>::const_iterator m = asi_mask[asi].find(addr);
if (m != asi_mask[asi].end())
*data = (temp & (*m).second) | (*data &~ ((*m).second));
else
*data = temp;
}
}
}
if (s->trc_hook)
s->trc_hook->asi_access(SS_Tracer::LD_DATA,asi,addr,data);
}
return ok;
}
SS_AsiSpace::Error SS_AsiMap::st64( SS_Strand* s, uint8_t asi, SS_Vaddr addr, uint64_t data )
{
SS_AsiSpace::Error ok = table[asi].st64(s,addr,data);
if (ok == SS_AsiSpace::OK && s->trc_hook)
s->trc_hook->asi_access(SS_Tracer::ST_DATA,asi,addr,&data);
return ok;
}