Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Cpu.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_Cpu.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_Cpu.h"
#include "SS_Strand.h"
#include "SS_Model.h"
#include "SS_Signal.h"
SS_Cpu::SS_Cpu( SS_Model& _model, const char* _name )/*{{{*/
:
SS_Node(_model,_name),
model(_model),
strand_count(0)
{
clr_stepping();
}
/*}}}*/
void SS_Cpu::flush( SS_Paddr pa )/*{{{*/
{
for (uint_t i = 0; i < strand_count; i++)
strand[i]->flush(pa);
}
/*}}}*/
void SS_Cpu::flush( SS_Strand* s, SS_Paddr pa, uint_t size )/*{{{*/
{
SS_Signal::Type type;
// Currently we support three sizes, 8b (sun sparc standard)
// page flush (8k) and infinite (size == ~0). The page flush
// and infinite flush (all decode caches) are handled with
// the FLUSH_8K as that is flush all decode caches.
if (size == 8)
type = SS_Signal::FLUSH_8B;
else if (size == 8192)
type = SS_Signal::FLUSH_8K;
else
type = SS_Signal::FLUSH_ALL;
for (uint_t i = 0; i < strand_count; i++)
{
if (is_stepping(i))
{
SS_Signal* sgn = s->msg.make_signal(type);
sgn->flush_pa = pa;
strand[i]->post_signal(sgn);
}
}
}
/*}}}*/
void SS_Cpu::ras_flush( SS_Strand* requesting_strand, SS_Paddr pa, uint64_t size, SS_MemErrDetector::CacheType type )/*{{{*/
{
for (uint_t i = 0; i < strand_count; i++)
strand[i]->mem_err_detector.ras_flush(strand[i], requesting_strand, pa, size, type);
}
/*}}}*/
void SS_Cpu::snapshot( SS_SnapShot& ss )/*{{{*/
{
char prefix[32];
get_name(prefix);
// Before any snapshot is saved or loaded we ensure that the signal
// queues are handled with first. That way we don't have to snapshot
// those queues when we save and on load we don't have to restore
// them. Note that this is functioanlly correct behaviour.
for (uint_t i = 0; i < strand_count; i++)
strand[i]->peek_signal();
uint_t flush_count = 0; // Leave here so snapshot is ok
uint_t flush_strand = 0; // Leave here so snapshot is ok
uint_t strand_count_ = 0; // Regenerated during restore
uint_t strand_stepping_ = 0; // Regenerated during restore
sprintf(ss.tag,"%s.strand_count",prefix); ss.val(&strand_count);
sprintf(ss.tag,"%s.strand_stepping",prefix); ss.val(&strand_stepping[0]);
if (ss.get_version() >= 4)
{
sprintf(ss.tag,"%s.strand_stepping.1",prefix); ss.val(&strand_stepping[1]);
}
sprintf(ss.tag,"%s.flush_strand",prefix); ss.val(&flush_strand);
sprintf(ss.tag,"%s.flush_count",prefix); ss.val(&flush_count);
}
/*}}}*/
void SS_Cpu::ras_enable(char* cmd)/*{{{*/
{
for (uint_t i = 0; i < strand_count; i++)
{
strand[i]->ras_enable(strand[i], cmd);
}
}
/*}}}*/