1 /* Cache support for the FRV simulator 2 Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. 3 Contributed by Red Hat. 4 5 This file is part of the GNU Simulators. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License along 18 with this program; if not, write to the Free Software Foundation, Inc., 19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 20 21 #ifndef CACHE_H 22 #define CACHE_H 23 24 /* A representation of a set-associative cache with LRU replacement, 25 cache line locking, non-blocking support and multiple read ports. */ 26 27 /* An enumeration of cache pipeline request kinds. */ 28 typedef enum 29 { 30 req_load, 31 req_store, 32 req_invalidate, 33 req_flush, 34 req_preload, 35 req_unlock, 36 req_WAR 37 } FRV_CACHE_REQUEST_KIND; 38 39 /* The cache pipeline requests. */ 40 typedef struct { 41 int preload; 42 int lock; 43 } FRV_CACHE_WAR_REQUEST; 44 45 typedef struct { 46 char *data; 47 int length; 48 } FRV_CACHE_STORE_REQUEST; 49 50 typedef struct { 51 int flush; 52 int all; 53 } FRV_CACHE_INVALIDATE_REQUEST; 54 55 typedef struct { 56 int lock; 57 int length; 58 } FRV_CACHE_PRELOAD_REQUEST; 59 60 /* A cache pipeline request. */ 61 typedef struct frv_cache_request 62 { 63 struct frv_cache_request *next; 64 struct frv_cache_request *prev; 65 FRV_CACHE_REQUEST_KIND kind; 66 unsigned reqno; 67 unsigned priority; 68 SI address; 69 union { 70 FRV_CACHE_STORE_REQUEST store; 71 FRV_CACHE_INVALIDATE_REQUEST invalidate; 72 FRV_CACHE_PRELOAD_REQUEST preload; 73 FRV_CACHE_WAR_REQUEST WAR; 74 } u; 75 } FRV_CACHE_REQUEST; 76 77 /* The buffer for returning data to the caller. */ 78 typedef struct { 79 unsigned reqno; 80 SI address; 81 char *data; 82 int valid; 83 } FRV_CACHE_RETURN_BUFFER; 84 85 /* The status of flush requests. */ 86 typedef struct { 87 unsigned reqno; 88 SI address; 89 int valid; 90 } FRV_CACHE_FLUSH_STATUS; 91 92 /* Communicate status of requests to the caller. */ 93 typedef struct { 94 FRV_CACHE_FLUSH_STATUS flush; 95 FRV_CACHE_RETURN_BUFFER return_buffer; 96 } FRV_CACHE_STATUS; 97 98 /* A cache pipeline stage. */ 99 typedef struct { 100 FRV_CACHE_REQUEST *request; 101 } FRV_CACHE_STAGE; 102 103 enum { 104 FIRST_STAGE, 105 A_STAGE = FIRST_STAGE, /* Addressing stage */ 106 I_STAGE, /* Interference stage */ 107 LAST_STAGE = I_STAGE, 108 FRV_CACHE_STAGES 109 }; 110 111 /* Representation of the WAR register. */ 112 typedef struct { 113 unsigned reqno; 114 unsigned priority; 115 SI address; 116 int preload; 117 int lock; 118 int latency; 119 int valid; 120 } FRV_CACHE_WAR; 121 122 /* A cache pipeline. */ 123 #define NUM_WARS 2 124 typedef struct { 125 FRV_CACHE_REQUEST *requests; 126 FRV_CACHE_STAGE stages[FRV_CACHE_STAGES]; 127 FRV_CACHE_WAR WAR[NUM_WARS]; 128 FRV_CACHE_STATUS status; 129 } FRV_CACHE_PIPELINE; 130 131 enum {LS, LD, FRV_CACHE_PIPELINES}; 132 133 /* Representation of the xARS registers. */ 134 typedef struct { 135 int pipe; 136 unsigned reqno; 137 unsigned priority; 138 SI address; 139 int preload; 140 int lock; 141 int valid; 142 } FRV_CACHE_ARS; 143 144 /* A cache tag. */ 145 typedef struct { 146 USI tag; /* Address tag. */ 147 int lru; /* Lower values indicates less recently used. */ 148 char *line; /* Points to storage for line in data_storage. */ 149 char dirty; /* line has been written to since last stored? */ 150 char locked; /* line is locked? */ 151 char valid; /* tag is valid? */ 152 } FRV_CACHE_TAG; 153 154 /* Cache statistics. */ 155 typedef struct { 156 unsigned long accesses; /* number of cache accesses. */ 157 unsigned long hits; /* number of cache hits. */ 158 } FRV_CACHE_STATISTICS; 159 160 /* The cache itself. 161 Notes: 162 - line_size must be a power of 2 163 - sets must be a power of 2 164 - ways must be a power of 2 165 */ 166 typedef struct { 167 SIM_CPU *cpu; 168 unsigned configured_ways; /* Number of ways configured in each set. */ 169 unsigned configured_sets; /* Number of sets configured in the cache. */ 170 unsigned ways; /* Number of ways in each set. */ 171 unsigned sets; /* Number of sets in the cache. */ 172 unsigned line_size; /* Size of each cache line. */ 173 unsigned memory_latency; /* Latency of main memory in cycles. */ 174 FRV_CACHE_TAG *tag_storage; /* Storage for tags. */ 175 char *data_storage; /* Storage for data (cache lines). */ 176 FRV_CACHE_PIPELINE pipeline[2]; /* Cache pipelines. */ 177 FRV_CACHE_ARS BARS; /* BARS register. */ 178 FRV_CACHE_ARS NARS; /* BARS register. */ 179 FRV_CACHE_STATISTICS statistics; /* Operation statistics. */ 180 } FRV_CACHE; 181 182 /* The tags are stored by ways within sets in order to make computations 183 easier. */ 184 #define CACHE_TAG(cache, set, way) ( \ 185 & ((cache)->tag_storage[(set) * (cache)->ways + (way)]) \ 186 ) 187 188 /* Compute the address tag corresponding to the given address. */ 189 #define CACHE_ADDRESS_TAG(cache, address) ( \ 190 (address) & ~(((cache)->line_size * (cache)->sets) - 1) \ 191 ) 192 193 /* Determine the index at which the set containing this tag starts. */ 194 #define CACHE_TAG_SET_START(cache, tag) ( \ 195 ((tag) - (cache)->tag_storage) & ~((cache)->ways - 1) \ 196 ) 197 198 /* Determine the number of the set which this cache tag is in. */ 199 #define CACHE_TAG_SET_NUMBER(cache, tag) ( \ 200 CACHE_TAG_SET_START ((cache), (tag)) / (cache)->ways \ 201 ) 202 203 #define CACHE_RETURN_DATA(cache, slot, address, mode, N) ( \ 204 T2H_##N (*(mode *)(& (cache)->pipeline[slot].status.return_buffer.data \ 205 [((address) & ((cache)->line_size - 1))])) \ 206 ) 207 #define CACHE_RETURN_DATA_ADDRESS(cache, slot, address, N) ( \ 208 ((void *)& (cache)->pipeline[slot].status.return_buffer.data[(address) \ 209 & ((cache)->line_size - 1)]) \ 210 ) 211 212 #define DATA_CROSSES_CACHE_LINE(cache, address, size) ( \ 213 ((address) & ((cache)->line_size - 1)) + (size) > (cache)->line_size \ 214 ) 215 216 #define CACHE_INITIALIZED(cache) ((cache)->data_storage != NULL) 217 218 /* These functions are used to initialize and terminate a cache. */ 219 void 220 frv_cache_init (SIM_CPU *, FRV_CACHE *); 221 void 222 frv_cache_term (FRV_CACHE *); 223 void 224 frv_cache_reconfigure (SIM_CPU *, FRV_CACHE *); 225 int 226 frv_cache_enabled (FRV_CACHE *); 227 228 /* These functions are used to operate the cache in non-cycle-accurate mode. 229 Each request is handled individually and immediately using the current 230 cache internal state. */ 231 int 232 frv_cache_read (FRV_CACHE *, int, SI); 233 int 234 frv_cache_write (FRV_CACHE *, SI, char *, unsigned); 235 int 236 frv_cache_preload (FRV_CACHE *, SI, USI, int); 237 int 238 frv_cache_invalidate (FRV_CACHE *, SI, int); 239 int 240 frv_cache_invalidate_all (FRV_CACHE *, int); 241 242 /* These functions are used to operate the cache in cycle-accurate mode. 243 The internal operation of the cache is simulated down to the cycle level. */ 244 #define NO_REQNO 0xffffffff 245 void 246 frv_cache_request_load (FRV_CACHE *, unsigned, SI, int); 247 void 248 frv_cache_request_store (FRV_CACHE *, SI, int, char *, unsigned); 249 void 250 frv_cache_request_invalidate (FRV_CACHE *, unsigned, SI, int, int, int); 251 void 252 frv_cache_request_preload (FRV_CACHE *, SI, int, int, int); 253 void 254 frv_cache_request_unlock (FRV_CACHE *, SI, int); 255 256 void 257 frv_cache_run (FRV_CACHE *, int); 258 259 int 260 frv_cache_data_in_buffer (FRV_CACHE*, int, SI, unsigned); 261 int 262 frv_cache_data_flushed (FRV_CACHE*, int, SI, unsigned); 263 264 int 265 frv_cache_read_passive_SI (FRV_CACHE *, SI, SI *); 266 267 #endif /* CACHE_H */ 268