Blame sim/frv/cache.h

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