Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_InstrCache.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: SS_InstrCache.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_InstrCache_h__
#define __SS_InstrCache_h__
#include "SS_Instr.h"
#include "SS_PidContext.h"
// SS_InstrCache is the decode cache (well actually instruction cache too)
// were we keep decoded instructions and few other bits and pieces.
// An instance of the class should have the opc element at offset 0 of the
// this pointer, so no virtual methods allowed here.
class SS_InstrCache
{
public:
enum
{
#if defined(COMPILE_FOR_COSIM) || defined(ARCH_V8)
BITS = 4,
#else
BITS = 11,
#endif
SIZE = 1 << BITS,
MASK = SIZE - 1,
LINE_BITS = 4,
LINE_SIZE = 1 << LINE_BITS,
LINE_MASK = LINE_SIZE - 1
};
// init() is called to initialise the decode cache. Note we do not use
// a constructor here, as that would cause all the SS_Instr guys to be
// called for the whole cache. We know that the initial cache is empty,
// and when we fill it when we initialise it.
void init( const char* _id, SS_Tte* tte )
{
id = _id;
pstate_am_flag = 0;
pstate_tct_flag = 0;
pstate_cle_flag = 0;
hpstate_ibe_flag = 0;
for (int l=0; l < SS_InstrCache::SIZE; l++)
{
tag[l].tte = tte;
tag[l].lnk.clean();
opc[l].lnk.clean();
for (int o=0; o < (SS_Instr::LINE_SIZE - 1); o++)
opc[l].stride2[o].clean();
}
inst_ctx.init();
data_ctx.init();
}
struct Tag
{
union
{
SS_Tte* tte; // The TTE associated with the cache line
uintptr_t tte_bits; // Integer access to tte for RAS_TTE_POISON
};
SS_Vaddr tag; // The tag of the cacheline
SS_Chain lnk;
};
SS_Instr opc[SIZE]; // Note LINE_SIZE SS_Instr are overlapping in the holes
Tag tag[SIZE]; // The tag (tte) of the cachelines
const char* id; // Identifier for debugging purposes
uint_t pstate_am_flag; // Current pstate.am() for this cache
uint_t pstate_tct_flag; // Current pstate.tct() for this cache
uint_t pstate_cle_flag; // Current pstate.cle() for this cache
uint_t hpstate_ibe_flag; // Current hpstate.ibe() for this cache
SS_PidContext inst_ctx; // Current partition id and primary contexts for this cache
SS_PidContext data_ctx; // Current primary and secondary contexts for this cache
// The decode cache is addressed by selecting fields from the PC. Note that
// the instruction cache line is striped (see SS_Instr).
//
// pc = xxxxxxxxllllllliiii00 where x=don'tcare l=linenumber i=lineindex
// pc_inst() returns a pointer to the instruction for given pc value
SS_Instr* pc_inst( SS_Vaddr pc )
{
SS_Vaddr base = pc << (SS_Instr::BITS - 2);
SS_Vaddr line = base & (MASK << (SS_Instr::BITS + LINE_BITS));
SS_Vaddr indx = (base >> SS_Instr::SKEW) & (LINE_MASK << (SS_Instr::BITS - SS_Instr::SKEW));
return (SS_Instr*)((char*)opc + line + indx);
}
// pc_line() returns a pointer to the cacheline for given pc value.
SS_Instr* pc_line( SS_Vaddr pc )
{
SS_Vaddr line = (pc << (SS_Instr::BITS - 2)) & (MASK << (SS_Instr::BITS + LINE_BITS));
return (SS_Instr*)((char*)opc + line);
}
// pc_tte() returns a pointer to the tte of the cacheline for given pc value.
SS_Tte* pc_tte( SS_Vaddr pc )
{
return tag[(pc >> (LINE_BITS + 2)) & MASK].tte;
}
};
#endif