* ========== 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
* XI cache consists of two components ...
* A translation cache to speed I tlb and simulated I cache operation
* A cache of pre-decoded instructions - so we can handle snooping of
* writes to instruction memory.
xicache_t
* xicache_alloc(simcpu_t
* sp
)
void (*decodemep
)(simcpu_t
*, xicache_instn_t
*);
xcp
= Xcalloc(1, xicache_t
);
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
;
* 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
)
void (*decodemep
)(simcpu_t
*, xicache_instn_t
*);
DBGXCACHE( lprintf(sp
->gid
, "xicache_instn_flush: pc=0x%llx "
"[cycle=0x%llx]\n", sp
->pc
, sp
->cycle
); );
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
)
DBGXCACHE( lprintf(sp
->gid
, "xicache_trans_flush: pc=0x%llx "
"[cycle=0x%llx]\n", sp
->pc
, sp
->cycle
); );
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
* 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
)
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
); );
tag
= tagva
& XICACHE_TAG_PURE_MASK
;
idx
= (tag
>> XICACHE_INSTR_SHIFT_BITS
) & XICACHE_NUM_INSTR_MASK
;
decodemep
= sp
->decodemep
;
for (i
=0; i
<(XICACHE_LINE_SIZE
>> XICACHE_INSTR_SHIFT_BITS
); i
++) {
ip
->exec_funcp
= decodemep
;