Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Tlb.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: SS_Tlb.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 <string.h>
#include "SS_Tlb.h"
#include "SS_Strand.h"
uint_t SS_Tlb::tlb_id_no = 0;
SS_Tlb::SS_Tlb( Type type, uint_t size )/*{{{*/
:
clone(ss_clone),
tlb_ident(tlb_id_no),
tlb_type(type),
tlb_size(size),
ptr_table(0),
generation_count(0),
not_a_clone(true),
strand_list(0),
no_strands(0),
tte_list(0)
{
tlb_id_no++;
ptr_table = (SS_Tte**)ss_malloc(sizeof(SS_Tte*) * tlb_size);
for (uint_t i = 0; i < tlb_size; i++)
ptr_table[i] = alloc_tte(i);
}
/*}}}*/
SS_Tlb::SS_Tlb( SS_Tlb& tlb )/*{{{*/
:
clone(tlb.clone),
tlb_type(tlb.tlb_type),
tlb_size(tlb.tlb_size),
ptr_table(0),
not_a_clone(false), // only the original not a clone tlb shoud destruct the strands list
strand_list(tlb.strand_list), // the structure can be shared ... not_a_clone controls destructing
no_strands(tlb.no_strands),
tte_list(tlb.tte_list)
{
ptr_table = (SS_Tte**)ss_malloc(sizeof(SS_Tte*) * tlb_size);
memcpy(ptr_table,tlb.ptr_table,sizeof(SS_Tte*) * tlb_size);
tlb.tte_list = 0; // Avoid having the free list at two places
}
/*}}}*/
SS_Tlb::~SS_Tlb()/*{{{*/
{
free(ptr_table);
}
/*}}}*/
SS_Tlb* SS_Tlb::ss_clone( SS_Tlb* tlb )/*{{{*/
{
return new SS_Tlb(*tlb);
}
/*}}}*/
void SS_Tlb::add_strand( SS_Strand* strand )/*{{{*/
{
tlb_access.lock();
++no_strands;
strand_list = new Node(strand,strand_list);
tlb_access.unlock();
}
/*}}}*/
void SS_Tlb::rem_strand( SS_Strand* strand )/*{{{*/
{
tlb_access.lock();
assert(no_strands);
--no_strands;
Node* head = strand_list;
if (head->strand == strand)
{
strand_list = head->next;
delete head;
tlb_access.unlock();
return;
}
else
{
int i = 0;
for (Node* next = head->next; strand && next; head = next, next = next->next)
{
assert (++i <= no_strands);
if (next->strand == strand)
{
strand = 0;
head->next = next->next;
delete next;
tlb_access.unlock();
return;
}
}
}
assert(0);
tlb_access.unlock();
}
/*}}}*/
SS_Tte* SS_Tlb::alloc_tte_block()/*{{{*/
{
const SIZE = 64;
SS_Tte* next = 0;
SS_Tte* block = (SS_Tte*)ss_malloc(sizeof(SS_Tte) * SIZE);
for (uint_t i = 1; i < SIZE; i++)
{
new(&block[i]) SS_Tte();
block[i].next = next;
next = &block[i];
}
tte_list = next;
new(block) SS_Tte();
return block;
}
/*}}}*/
void SS_Tlb::dump(FILE *fp)/*{{{*/
{
tlb_access.lock();
for (int i=0; i < size(); i++)
{
if (ptr_table[i]->valid())
{
fprintf(fp,"%04x ",i);
ptr_table[i]->dump(fp);
}
}
tlb_access.unlock();
}
/*}}}*/