scache.h
6.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*
* Copyright (C) 1996-1998 by the Board of Trustees
* of Leland Stanford Junior University.
*
* This file is part of the SimOS distribution.
* See LICENSE file for terms of the license.
*
*/
/*****************************************************************
* scache.h
*
* This is the interface into a second level cache. The goal is to
* separate it out from the first level cache so that other cpu
* simulators can use it.
*
* Author: $author$
* Date: $date$
*****************************************************************/
#ifndef _SCACHE_H
#define _SCACHE_H
#include "machine_params.h"
#include "pcache.h"
#include "eventcallback.h"
#include "cpu_interface.h"
#include "dma.h"
/*
* Possible return status from the SCFetch routine.
* SCSUCCESS - SCache operation completed succesfully.
* SCSTALL - SCache operation sent, must wait for it.
* SCRETRY - Need to retry this request later.
* SCBUSERROR - Request suffered a bus error (most likely a firewall violation).
*/
typedef enum { SCSUCCESS = 0, SCSTALL, SCRETRY, SCBUSERROR} SCResult;
#define SCACHE_MAXASSOC 4
#ifdef SOLO
#define EXCLUSIVE_CMD 0x40
#else
#define EXCLUSIVE_CMD EXCLUSIVE_TAG
#endif
/* Return types for IsInSCache */
#define SCACHE_PRESENT 1
typedef PA SCacheCmd;
/*
* SCache Fetch commands.
*/
#define SC_IGET 0x1 /* First level Icache miss */
#define SC_DGET 0x2 /* First level Dcache read miss */
#define SC_DGETX ((0x2|EXCLUSIVE_CMD)) /* First level Dcache GETx */
#define SC_DUGETX (0x4|EXCLUSIVE_CMD) /* First level Dcache upgrade */
#define SC_DSCUGETX (0x8|EXCLUSIVE_CMD) /* Upgrade from a SC inst */
#define SC_DLLGET 0x10
#define SC_DLLGETX (0x20|EXCLUSIVE_CMD)
#define SC_NO_CMD (0xffffffff) /* Uninitialized command */
/* Cache states -- passed to FlashLite */
/* Don't change these values -- they match the
SYSSTATE_* values in flashlite/miscbus.h */
#define SCACHE_INVALID 0
#define SCACHE_SHARED 1
#define SCACHE_CLEAN_EXCLUSIVE 2
#define SCACHE_DIRTY_EXCLUSIVE 3
#define SCACHE_TAG(a) ((a) >> (log2SCACHE_SIZE - log2SCACHE_ASSOC))
#define SCACHE_TAG_EX(a) (SCACHE_TAG(a)|EXCLUSIVE_TAG)
#define SCACHE_INDEXOF(a) ((a >>log2SCACHE_LINE_SIZE) & (SCACHE_INDEX-1))
#define STAG_TO_PA(t,i) ((((~EXCLUSIVE_TAG)&(t))*(SCACHE_SIZE/SCACHE_ASSOC))+ \
((i) <<log2SCACHE_LINE_SIZE))
typedef struct SMHT {
EventCallbackHdr evthdr; /* So we can make this an event callback */
int mode; /* Used for the bus event */
bool inuse; /* TRUE if entry active */
uint memsyscmd; /* Memory system command */
SimTime startTime; /* When memory request was started */
VA vAddr;
PA pAddr; /* Physical address of miss */
PA PC; /* PC causing the miss */
int ind; /* Index in the cache */
uint scacheLRU; /* Second level cache LRU bit */
short numMHTwait; /* Number of entries in the MHT waiting for us */
short mhtInd[MHT_SIZE]; /* Indices into MHT of waiters. */
char *lineData; /* Pointer of location to deposit fill data */
VA pfvAddr; /* If a prefetch, virtual address of line */
int formerState; /* Former state of cache line */
} SMHT;
typedef struct SCache {
struct SCacheSet {
PA tags[SCACHE_MAXASSOC];
uint LRU;
#ifdef DATA_HANDLING
char *data[SCACHE_MAXASSOC];
/* This is the actual cache line of data */
/* with one line for each tag. This memory */
/* is allocated dynamically at runtime, since */
/* the cache line size may vary*/
#endif
} *set; /* [SCACHE_INDEX]; */
/*
* Second level miss handling table.
*/
#define SMHT_SIZE 4
SMHT SMHT[SMHT_SIZE];
int SMHTnumInuse; /* Number of active SMHT entries */
struct {
SimCounter Igets;
SimCounter Dgets;
SimCounter DgetXs;
SimCounter Dupgrades;
SimCounter IgetMisses;
SimCounter DgetMisses;
SimCounter DgetXMisses;
SimCounter DupgradeMisses;
SimCounter MergeMisses;
SimCounter Writebacks;
SimCounter Replacements;
SimCounter Inval;
SimCounter Downgrade;
SimCounter LinesInval;
SimCounter LinesWriteback;
SimCounter smhtOccupancyHist[SMHT_SIZE+1];
SimCounter Prefetches;
#ifdef HWBCOPY
#define MAX_STREAM_DEPTH 8
SimCounter StreamGets[MAX_STREAM_DEPTH];
SimCounter StreamGetXs[MAX_STREAM_DEPTH];
#endif
SimCounter IGetMHTRetries;
SimCounter DGetMHTRetries;
SimCounter DGetXMHTRetries;
SimCounter DUGetXMHTRetries;
SimCounter NAKs;
} stats;
#ifdef HWBCOPY
struct {
uint last_index;
int consecutive;
} get, getx;
#endif
} SCache;
extern SCache *SCACHE;
/* Global Functions */
/* Interface from CPU into here */
extern void InitSCaches(void);
/* Interface from 1st level cache to here */
extern SCResult SCacheFetch(int cpuNum, VA, PA, SCacheCmd cmd, int mhtind);
extern int IsInSCache(int cpuNum, PA pAddr, int mode, char **data,
int *way);
extern PFResult SCachePrefetch(int cpuNum, VA vAddr, PA pAddr, MCMD mcmd);
extern int CacheInvalidate(int cpuNum, PA paddr, int size, bool writeback,
int *wasDirty);
extern int CacheInvalidateIndex(int cpuNum, PA paddr, int size, bool writeback,
int *wasDirty);
extern int CacheExtract(int cpuNum, PA paddr, int size, int *writeback,
byte *data);
/* Called by the cache op */
extern int CacheExtractIndex(int cpuNum, PA paddr, int size,
int *writeback, PA *real_paddr,
byte *data);
extern int CacheWriteback(int cpuNum, PA paddr, int size, byte *data);
extern int CacheFlush(int cpuNum, PA paddr, int size, byte *data);
#ifdef DATA_HANDLING
extern void FlushEntireCache(int cpuNum, int leaveShared);
#endif
#define GET_SCACHE_NUM(_cpunum) (_cpunum)
int EmptySMHT(int cpuNum); /* check whether SMHT empty */
#endif