Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_Tsb.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: SS_Tsb.h
* 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 ============================================
*/
#ifndef __SS_Tsb_h__
#define __SS_Tsb_h__
#include "SS_Types.h"
class SS_TsbConfig
{
public:
SS_TsbConfig( ) : valid(false), tsb_size_check(0)
{
// even if tsb_config is not enabled, we still need the proper values
// to calculate tsb_pointer in case like tlb miss, so set up the init
// value properly.
update(false, 0, 9, 13, false, 0);
}
// update() recomputes the tsb access values: tsb_base is the base address,
// the tsb size is 2^tsb_size, page size is number of 2^page_size
void update( bool _valid, SS_Paddr tsb_base, uint_t tsb_size, uint_t page_size, bool _ra1pa, uint_t _use_ctx )
{
valid = _valid;
ra1pa = _ra1pa;
use_ctx = _use_ctx;
match_mask = ((~((SS_Vaddr(1) << page_size) - SS_Vaddr(1))) >> 22) << 22;
index_base = (tsb_base >> (tsb_size + 4)) << (tsb_size + 4); // TSB is aligned to its own size and
// the combination of page_size and tsb_size may cover a bigger VA
// range than is supported by a particular architecture, so may have
// to adjust a bit.
int tsb_size_adjust = tsb_size;
if (tsb_size_check &&
((page_size == page_size_check) && (tsb_size > tsb_size_check)))
{
tsb_size_adjust = tsb_size_check;
}
index_mask = (SS_Paddr(0x10) << tsb_size_adjust) - 0x10; // one entry is 16 bytes ...
index_shft = page_size - 4;
tsb_psz = (page_size - 13) / 3; // Ahum ... convert back to 0..7
}
bool is_valid() { return valid; }
bool is_ra_not_pa() { return ra1pa; }
int use_context() { return use_ctx; }
int use_context_0() { return use_ctx & 2; }
int use_context_1() { return use_ctx & 1; }
bool match( SS_Vaddr va, SS_Vaddr tag ) { return (va & match_mask) == tag; }
SS_Paddr index( SS_Vaddr va ) { return index_base | ((va >> index_shft) & index_mask); }
uint_t get_page_size() { return tsb_psz; }
void set_attr( uint_t _page_size_check, uint_t _tsb_size_check )
{
page_size_check = _page_size_check;
tsb_size_check = _tsb_size_check;
}
protected:
bool valid;
bool ra1pa;
uint_t index_shft;
SS_Paddr index_mask;
SS_Paddr index_base;
SS_Vaddr match_mask;
uint_t use_ctx;
uint_t tsb_psz;
uint_t page_size_check;
uint_t tsb_size_check;
};
class SS_TsbRaToPa
{
public:
SS_TsbRaToPa() : valid(false) {}
void update( bool v, SS_Paddr _beg, SS_Paddr _end, SS_Paddr _ofs )
{
valid = v;
rpn_beg = _beg;
rpn_end = _end;
ppn_ofs = _ofs;
}
bool valid;
SS_Paddr rpn_beg;
SS_Paddr rpn_end;
SS_Paddr ppn_ofs;
};
#endif