Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / simcore / xicache.c
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: xicache.c
* 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 ============================================
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "@(#)xicache.c 1.16 06/08/31 SMI"
/*
* Support routines for the execution instruction cache
*/
#include <assert.h>
#include "basics.h"
#include "allocate.h"
#include "simcore.h"
#include "config.h"
#include "xicache.h"
/*
* XI cache consists of two components ...
* trans_cache:
* A translation cache to speed I tlb and simulated I cache operation
* instn_cache:
* A cache of pre-decoded instructions - so we can handle snooping of
* writes to instruction memory.
*/
xicache_t * xicache_alloc(simcpu_t * sp)
{
xicache_t * xcp;
xicache_line_t * lp;
xicache_instn_t * xip;
ulong_t i,j;
void (*decodemep)(simcpu_t *, xicache_instn_t *);
xcp = Xcalloc(1, xicache_t);
lp = &(xcp->line[0]);
xip = &xcp->instn[0];
decodemep = sp->decodemep;
ASSERT(decodemep != NULL);
for (j=0; j<XICACHE_NUM_LINES; j++, lp++) {
lp->tag = XC_INVALID_TAG;
lp->memoryoffset = XICACHE_DEAD_MEMOFF;
}
for (i=0; i<XICACHE_NUM_INSTRS; i++, xip++) {
xip->exec_funcp = decodemep;
xip->rawi = XICACHE_DEAD_INSTN;
}
return xcp;
}
/*
* This flush resets the decode for all instructions.
*
* exec_loop does this one a per-instruction basis by
* comparing rawi to memory.
*/
void xicache_instn_flush(simcpu_t * sp)
{
ulong_t i;
xicache_t * xcp;
xicache_instn_t * xip;
void (*decodemep)(simcpu_t *, xicache_instn_t *);
XIC_FLUSH(sp);
DBGXCACHE( lprintf(sp->gid, "xicache_instn_flush: pc=0x%llx "
"[cycle=0x%llx]\n", sp->pc, sp->cycle); );
xcp = sp->xicachep;
xip = &xcp->instn[0];
decodemep = sp->decodemep;
for (i=0; i<XICACHE_NUM_INSTRS; i++, xip++) {
xip->exec_funcp = decodemep;
}
}
/*
* This flush merely forces a miss in the XI-cache by
* invalidating the translation tags.
*/
void xicache_trans_flush(simcpu_t * sp)
{
ulong_t j;
xicache_t * xcp;
xicache_line_t * lp;
XIC_FLUSH(sp);
DBGXCACHE( lprintf(sp->gid, "xicache_trans_flush: pc=0x%llx "
"[cycle=0x%llx]\n", sp->pc, sp->cycle); );
xcp = sp->xicachep;
lp = &(xcp->line[0]);
for (j=0; j<XICACHE_NUM_LINES; j++, lp++) {
if (lp->tag != XC_INVALID_TAG &&
(lp->tag & XCACHE_TAGSTATE_MASK) != XCACHE_TAGSTATE_PHYS) {
lp->tag = XC_INVALID_TAG;
lp->memoryoffset = XICACHE_DEAD_MEMOFF;
}
}
}
/*
* This function is used to clobber the instruction decodes
* in the xicache that correspond to a single xi-cache line
* that is being displaced.
* As the cache is direct-mapped you may pass in a full VA
* or a index.
* No tag check is done because we are explicitly clobbering the
* line to avoid instruction aliasing ..
*/
void xicache_clobber_line_decodes(simcpu_t * sp, tvaddr_t tagva)
{
tvaddr_t tag;
xicache_t * xcp;
xicache_instn_t * ip;
ulong_t idx, i;
void (*decodemep)(simcpu_t *, xicache_instn_t *);
DBGXCACHE( lprintf(sp->gid, "xicache_clobber_line_decodes: pc=0x%llx "
"[cycle=0x%llx]\n", sp->pc, sp->cycle); );
xcp = sp->xicachep;
tag = tagva & XICACHE_TAG_PURE_MASK;
idx = (tag >> XICACHE_INSTR_SHIFT_BITS) & XICACHE_NUM_INSTR_MASK;
decodemep = sp->decodemep;
ip = &(xcp->instn[idx]);
for (i=0; i<(XICACHE_LINE_SIZE >> XICACHE_INSTR_SHIFT_BITS); i++) {
ip->exec_funcp = decodemep;
ip++;
}
}