Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / include / xdcache.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: xdcache.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 ============================================
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _XDCACHE_H_
#define _XDCACHE_H_
#pragma ident "@(#)xdcache.h 1.9 06/09/01 SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Simulator's data access cache model
* Overloaded to simulate datacaches, and TLB accesses etc.
* Basically - fast tracks as many loads/stores as possible,
* then misses to handle exceptional cases.
*/
#define XDCACHE_LINE_SIZE_BITS 13 /* 8K pages unless we want a real d-cache */
#define XDCACHE_LINE_SIZE (1ULL<<XDCACHE_LINE_SIZE_BITS)
#define XDCACHE_LINE_OFFSET_MASK (XDCACHE_LINE_SIZE-1)
#define XDCACHE_TAG_MASK (~XDCACHE_LINE_OFFSET_MASK)
#define XDCACHE_NUM_LINES_BITS 8 /* log2(entries) (must be at least 4, as we need 2 bits in tag) */
#define XDCACHE_NUM_LINES (1<<XDCACHE_NUM_LINES_BITS) /* 64 entries */
/* FIXME: must deal with SPARC address masking so this goes away soon */
#if (XDCACHE_LINE_SIZE_BITS+XDCACHE_NUM_LINES_BITS)>=32
#error Total number of bits spanned by XDcache must be less than 32 for SPARC address masking to work
#endif
/*
* The tag match algorithm is design to test 3 things simultaneously:
* Tag match + alignment + access permission.
*
* We need 2 bits for access permission and validity checks in the tag field.
* We also reserve 3 bits to test the correct access alignment.
* Thus the tag field holds a maximum of 64-2-3 = 58 bits of the tag.
* These become fewer if the cache lines are larger than 32 bytes.
*
* So, suppose there is a 4 byte read to address 0x3ce000.
*
* A matching tag would look something like 0x3ce008.
*
* The check looks something like: (addr | READ_PERM) ^ tag
* If the read perm bit is not set in the tag, then tag bit field in the result is non-zero.
* If addr is not aligned correctly, then the bottom 2 bits are non zero.
* If the tag doesn't match then the upper bits are non-zero.
* So to check for a match, mask the result with a mask with the upper bits set
* (for the actual tag fields), the READ_PERM bit, and the bottom N (2) bits set for
* checking alignment.
* This mask is concocted appropriately for each type of load.
*
* Thus trivially, a suitable invalid tag is one where neither the READ_PERM nor WRITE_PERM bits
* are set .. i.e. 0.
*/
typedef struct {
tvaddr_t tag;
#define XDCACHE_INVALID_TAG 0
#define XDCACHE_ALIGN_MASK 0x7
#define XDCACHE_READ_PERM 0x8
#define XDCACHE_WRITE_PERM 0x10
uint64_t offset; /* addr + offset = location of data in simulator memory */
} xdcache_line_t;
/*
* Try to optimize locating of xdc_line by using raw values to
* avoid excess shifts and masking by compiler
*/
#define XDCACHE_RAW_LINE_BITS 4 /* 16 bytes sizeof(tvaddr_t) + sizeof(offset) */
#define XDCACHE_RAW_SHIFT (XDCACHE_LINE_SIZE_BITS - XDCACHE_RAW_LINE_BITS)
#define XDCACHE_RAW_LINE_MASK ((XDCACHE_NUM_LINES-1) << XDCACHE_RAW_LINE_BITS)
#define XDCACHE_SANITY_CHECK() do { \
ASSERT( XDCACHE_RAW_SHIFT >= 3 ); /* must ensure miss-align bits shift off */\
ASSERT( sizeof(xdcache_line_t) == (1<<XDCACHE_RAW_LINE_BITS) ); \
} while (0)
typedef struct {
config_addr_t * miss_addrp; /* cache of last memory miss address */
void (*miss)(simcpu_t * sp, uint64_t * regp, tvaddr_t addr, int op);
xdcache_line_t line[XDCACHE_NUM_LINES];
} xdcache_t;
extern void xdcache_flush(simcpu_t * sp);
#if PERFORMANCE_CHECK /* { */
#define XDC_HIT(sp) do { (sp)->xdc_hits++; } while (0)
#define XDC_MISS(sp) do { (sp)->xdc_misses++; } while (0)
#define XDC_FLUSH(sp) do { (sp)->xdc_flushes++; } while (0)
#else
#define XDC_HIT(sp) do { } while (0)
#define XDC_MISS(sp) do { } while (0)
#define XDC_FLUSH(sp) do { } while (0)
#endif /* PERFORMANCE_CHECK } */
#ifdef __cplusplus
}
#endif
#endif /* _XDCACHE_H_ */