123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- /* Cache support for the FRV simulator
- Copyright (C) 1999-2015 Free Software Foundation, Inc.
- Contributed by Red Hat.
- This file is part of the GNU Simulators.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This 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 program. If not, see <http://www.gnu.org/licenses/>. */
- #ifndef CACHE_H
- #define CACHE_H
- /* A representation of a set-associative cache with LRU replacement,
- cache line locking, non-blocking support and multiple read ports. */
- /* An enumeration of cache pipeline request kinds. */
- typedef enum
- {
- req_load,
- req_store,
- req_invalidate,
- req_flush,
- req_preload,
- req_unlock,
- req_WAR
- } FRV_CACHE_REQUEST_KIND;
- /* The cache pipeline requests. */
- typedef struct {
- int preload;
- int lock;
- } FRV_CACHE_WAR_REQUEST;
- typedef struct {
- char *data;
- int length;
- } FRV_CACHE_STORE_REQUEST;
- typedef struct {
- int flush;
- int all;
- } FRV_CACHE_INVALIDATE_REQUEST;
- typedef struct {
- int lock;
- int length;
- } FRV_CACHE_PRELOAD_REQUEST;
- /* A cache pipeline request. */
- typedef struct frv_cache_request
- {
- struct frv_cache_request *next;
- struct frv_cache_request *prev;
- FRV_CACHE_REQUEST_KIND kind;
- unsigned reqno;
- unsigned priority;
- SI address;
- union {
- FRV_CACHE_STORE_REQUEST store;
- FRV_CACHE_INVALIDATE_REQUEST invalidate;
- FRV_CACHE_PRELOAD_REQUEST preload;
- FRV_CACHE_WAR_REQUEST WAR;
- } u;
- } FRV_CACHE_REQUEST;
- /* The buffer for returning data to the caller. */
- typedef struct {
- unsigned reqno;
- SI address;
- char *data;
- int valid;
- } FRV_CACHE_RETURN_BUFFER;
- /* The status of flush requests. */
- typedef struct {
- unsigned reqno;
- SI address;
- int valid;
- } FRV_CACHE_FLUSH_STATUS;
- /* Communicate status of requests to the caller. */
- typedef struct {
- FRV_CACHE_FLUSH_STATUS flush;
- FRV_CACHE_RETURN_BUFFER return_buffer;
- } FRV_CACHE_STATUS;
- /* A cache pipeline stage. */
- typedef struct {
- FRV_CACHE_REQUEST *request;
- } FRV_CACHE_STAGE;
- enum {
- FIRST_STAGE,
- A_STAGE = FIRST_STAGE, /* Addressing stage */
- I_STAGE, /* Interference stage */
- LAST_STAGE = I_STAGE,
- FRV_CACHE_STAGES
- };
- /* Representation of the WAR register. */
- typedef struct {
- unsigned reqno;
- unsigned priority;
- SI address;
- int preload;
- int lock;
- int latency;
- int valid;
- } FRV_CACHE_WAR;
- /* A cache pipeline. */
- #define NUM_WARS 2
- typedef struct {
- FRV_CACHE_REQUEST *requests;
- FRV_CACHE_STAGE stages[FRV_CACHE_STAGES];
- FRV_CACHE_WAR WAR[NUM_WARS];
- FRV_CACHE_STATUS status;
- } FRV_CACHE_PIPELINE;
- enum {LS, LD, FRV_CACHE_PIPELINES};
- /* Representation of the xARS registers. */
- typedef struct {
- int pipe;
- unsigned reqno;
- unsigned priority;
- SI address;
- int preload;
- int lock;
- int valid;
- } FRV_CACHE_ARS;
- /* A cache tag. */
- typedef struct {
- USI tag; /* Address tag. */
- int lru; /* Lower values indicates less recently used. */
- char *line; /* Points to storage for line in data_storage. */
- char dirty; /* line has been written to since last stored? */
- char locked; /* line is locked? */
- char valid; /* tag is valid? */
- } FRV_CACHE_TAG;
- /* Cache statistics. */
- typedef struct {
- unsigned long accesses; /* number of cache accesses. */
- unsigned long hits; /* number of cache hits. */
- } FRV_CACHE_STATISTICS;
- /* The cache itself.
- Notes:
- - line_size must be a power of 2
- - sets must be a power of 2
- - ways must be a power of 2
- */
- typedef struct {
- SIM_CPU *cpu;
- unsigned configured_ways; /* Number of ways configured in each set. */
- unsigned configured_sets; /* Number of sets configured in the cache. */
- unsigned ways; /* Number of ways in each set. */
- unsigned sets; /* Number of sets in the cache. */
- unsigned line_size; /* Size of each cache line. */
- unsigned memory_latency; /* Latency of main memory in cycles. */
- FRV_CACHE_TAG *tag_storage; /* Storage for tags. */
- char *data_storage; /* Storage for data (cache lines). */
- FRV_CACHE_PIPELINE pipeline[2]; /* Cache pipelines. */
- FRV_CACHE_ARS BARS; /* BARS register. */
- FRV_CACHE_ARS NARS; /* BARS register. */
- FRV_CACHE_STATISTICS statistics; /* Operation statistics. */
- } FRV_CACHE;
- /* The tags are stored by ways within sets in order to make computations
- easier. */
- #define CACHE_TAG(cache, set, way) ( \
- & ((cache)->tag_storage[(set) * (cache)->ways + (way)]) \
- )
- /* Compute the address tag corresponding to the given address. */
- #define CACHE_ADDRESS_TAG(cache, address) ( \
- (address) & ~(((cache)->line_size * (cache)->sets) - 1) \
- )
- /* Determine the index at which the set containing this tag starts. */
- #define CACHE_TAG_SET_START(cache, tag) ( \
- ((tag) - (cache)->tag_storage) & ~((cache)->ways - 1) \
- )
- /* Determine the number of the set which this cache tag is in. */
- #define CACHE_TAG_SET_NUMBER(cache, tag) ( \
- CACHE_TAG_SET_START ((cache), (tag)) / (cache)->ways \
- )
- #define CACHE_RETURN_DATA(cache, slot, address, mode, N) ( \
- T2H_##N (*(mode *)(& (cache)->pipeline[slot].status.return_buffer.data \
- [((address) & ((cache)->line_size - 1))])) \
- )
- #define CACHE_RETURN_DATA_ADDRESS(cache, slot, address, N) ( \
- ((void *)& (cache)->pipeline[slot].status.return_buffer.data[(address) \
- & ((cache)->line_size - 1)]) \
- )
- #define DATA_CROSSES_CACHE_LINE(cache, address, size) ( \
- ((address) & ((cache)->line_size - 1)) + (size) > (cache)->line_size \
- )
- #define CACHE_INITIALIZED(cache) ((cache)->data_storage != NULL)
- /* These functions are used to initialize and terminate a cache. */
- void
- frv_cache_init (SIM_CPU *, FRV_CACHE *);
- void
- frv_cache_term (FRV_CACHE *);
- void
- frv_cache_reconfigure (SIM_CPU *, FRV_CACHE *);
- int
- frv_cache_enabled (FRV_CACHE *);
- /* These functions are used to operate the cache in non-cycle-accurate mode.
- Each request is handled individually and immediately using the current
- cache internal state. */
- int
- frv_cache_read (FRV_CACHE *, int, SI);
- int
- frv_cache_write (FRV_CACHE *, SI, char *, unsigned);
- int
- frv_cache_preload (FRV_CACHE *, SI, USI, int);
- int
- frv_cache_invalidate (FRV_CACHE *, SI, int);
- int
- frv_cache_invalidate_all (FRV_CACHE *, int);
- /* These functions are used to operate the cache in cycle-accurate mode.
- The internal operation of the cache is simulated down to the cycle level. */
- #define NO_REQNO 0xffffffff
- void
- frv_cache_request_load (FRV_CACHE *, unsigned, SI, int);
- void
- frv_cache_request_store (FRV_CACHE *, SI, int, char *, unsigned);
- void
- frv_cache_request_invalidate (FRV_CACHE *, unsigned, SI, int, int, int);
- void
- frv_cache_request_preload (FRV_CACHE *, SI, int, int, int);
- void
- frv_cache_request_unlock (FRV_CACHE *, SI, int);
- void
- frv_cache_run (FRV_CACHE *, int);
- int
- frv_cache_data_in_buffer (FRV_CACHE*, int, SI, unsigned);
- int
- frv_cache_data_flushed (FRV_CACHE*, int, SI, unsigned);
- int
- frv_cache_read_passive_SI (FRV_CACHE *, SI, SI *);
- #endif /* CACHE_H */
|