/* frv cache model.
   Copyright (C) 1999-2021 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/>.  */

/* This must come before any other includes.  */
#include "defs.h"

#define WANT_CPU frvbf
#define WANT_CPU_FRVBF

#include "libiberty.h"
#include "sim-main.h"
#include "cache.h"
#include "bfd.h"
#include <stdlib.h>

void
frv_cache_init (SIM_CPU *cpu, FRV_CACHE *cache)
{
  int elements;
  int i, j;
  SIM_DESC sd;

  /* Set defaults for fields which are not initialized.  */
  sd = CPU_STATE (cpu);
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
    case bfd_mach_fr400:
    case bfd_mach_fr450:
      if (cache->configured_sets == 0)
	cache->configured_sets = 512;
      if (cache->configured_ways == 0)
	cache->configured_ways = 2;
      if (cache->line_size == 0)
	cache->line_size = 32;
      if (cache->memory_latency == 0)
	cache->memory_latency = 20;
      break;
    case bfd_mach_fr550:
      if (cache->configured_sets == 0)
	cache->configured_sets = 128;
      if (cache->configured_ways == 0)
	cache->configured_ways = 4;
      if (cache->line_size == 0)
	cache->line_size = 64;
      if (cache->memory_latency == 0)
	cache->memory_latency = 20;
      break;
    default:
      if (cache->configured_sets == 0)
	cache->configured_sets = 64;
      if (cache->configured_ways == 0)
	cache->configured_ways = 4;
      if (cache->line_size == 0)
	cache->line_size = 64;
      if (cache->memory_latency == 0)
	cache->memory_latency = 20;
      break;
    }

  frv_cache_reconfigure (cpu, cache);

  /* First allocate the cache storage based on the given dimensions.  */
  elements = cache->sets * cache->ways;
  cache->tag_storage = (FRV_CACHE_TAG *)
    zalloc (elements * sizeof (*cache->tag_storage));
  cache->data_storage = (char *) xmalloc (elements * cache->line_size);

  /* Initialize the pipelines and status buffers.  */
  for (i = LS; i < FRV_CACHE_PIPELINES; ++i)
    {
      cache->pipeline[i].requests = NULL;
      cache->pipeline[i].status.flush.valid = 0;
      cache->pipeline[i].status.return_buffer.valid = 0;
      cache->pipeline[i].status.return_buffer.data
	= (char *) xmalloc (cache->line_size);
      for (j = FIRST_STAGE; j < FRV_CACHE_STAGES; ++j)
	cache->pipeline[i].stages[j].request = NULL;
    }
  cache->BARS.valid = 0;
  cache->NARS.valid = 0;

  /* Now set the cache state.  */
  cache->cpu = cpu;
  cache->statistics.accesses = 0;
  cache->statistics.hits = 0;
}

void
frv_cache_term (FRV_CACHE *cache)
{
  /* Free the cache storage.  */
  free (cache->tag_storage);
  free (cache->data_storage);
  free (cache->pipeline[LS].status.return_buffer.data);
  free (cache->pipeline[LD].status.return_buffer.data);
}

/* Reset the cache configuration based on registers in the cpu.  */
void
frv_cache_reconfigure (SIM_CPU *current_cpu, FRV_CACHE *cache)
{
  int ihsr8;
  int icdm;
  SIM_DESC sd;

  /* Set defaults for fields which are not initialized.  */
  sd = CPU_STATE (current_cpu);
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
    case bfd_mach_fr550:
      if (cache == CPU_INSN_CACHE (current_cpu))
	{
	  ihsr8 = GET_IHSR8 ();
	  icdm = GET_IHSR8_ICDM (ihsr8);
	  /* If IHSR8.ICDM is set, then the cache becomes a one way cache.  */
	  if (icdm)
	    {
	      cache->sets = cache->sets * cache->ways;
	      cache->ways = 1;
	      break;
	    }
	}
      /* fall through */
    default:
      /* Set the cache to its original settings.  */
      cache->sets = cache->configured_sets;
      cache->ways = cache->configured_ways;
      break;
    }
}

/* Determine whether the given cache is enabled.  */
int
frv_cache_enabled (FRV_CACHE *cache)
{
  SIM_CPU *current_cpu = cache->cpu;
  int hsr0 = GET_HSR0 ();
  if (GET_HSR0_ICE (hsr0) && cache == CPU_INSN_CACHE (current_cpu))
    return 1;
  if (GET_HSR0_DCE (hsr0) && cache == CPU_DATA_CACHE (current_cpu))
    return 1;
  return 0;
}

/* Determine whether the given address is RAM access, assuming that HSR0.RME
   is set.  */
static int
ram_access (FRV_CACHE *cache, USI address) 
{
  int ihsr8;
  int cwe;
  USI start, end, way_size;
  SIM_CPU *current_cpu = cache->cpu;
  SIM_DESC sd = CPU_STATE (current_cpu);

  switch (STATE_ARCHITECTURE (sd)->mach)
    {
    case bfd_mach_fr550:
      /* IHSR8.DCWE or IHSR8.ICWE deternines which ways get RAM access.  */
      ihsr8 = GET_IHSR8 ();
      if (cache == CPU_INSN_CACHE (current_cpu))
	{
	  start = 0xfe000000;
	  end = 0xfe008000;
	  cwe = GET_IHSR8_ICWE (ihsr8);
	}
      else
	{
	  start = 0xfe400000;
	  end = 0xfe408000;
	  cwe = GET_IHSR8_DCWE (ihsr8);
	}
      way_size = (end - start) / 4;
      end -= way_size * cwe;
      return address >= start && address < end;
    default:
      break;
    }

  return 1; /* RAM access */
}

/* Determine whether the given address should be accessed without using
   the cache.  */
static int
non_cache_access (FRV_CACHE *cache, USI address) 
{
  int hsr0;
  SIM_DESC sd;
  SIM_CPU *current_cpu = cache->cpu;

  sd = CPU_STATE (current_cpu);
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
    case bfd_mach_fr400:
    case bfd_mach_fr450:
      if (address >= 0xff000000
	  || (address >= 0xfe000000 && address <= 0xfeffffff))
	return 1; /* non-cache access */
      break;
    case bfd_mach_fr550:
      if (address >= 0xff000000
	  || (address >= 0xfeff0000 && address <= 0xfeffffff))
	return 1; /* non-cache access */
      if (cache == CPU_INSN_CACHE (current_cpu))
	{
	  if (address >= 0xfe000000 && address <= 0xfe007fff)
	    return 1; /* non-cache access */
	}
      else if (address >= 0xfe400000 && address <= 0xfe407fff)
	return 1; /* non-cache access */
      break;
    default:
      if (address >= 0xff000000
	  || (address >= 0xfeff0000 && address <= 0xfeffffff))
	return 1; /* non-cache access */
      if (cache == CPU_INSN_CACHE (current_cpu))
	{
	  if (address >= 0xfe000000 && address <= 0xfe003fff)
	    return 1; /* non-cache access */
	}
      else if (address >= 0xfe400000 && address <= 0xfe403fff)
	return 1; /* non-cache access */
      break;
    }

  hsr0 = GET_HSR0 ();
  if (GET_HSR0_RME (hsr0))
    return ram_access (cache, address);

  return 0; /* cache-access */
}

/* Find the cache line corresponding to the given address.
   If it is found then 'return_tag' is set to point to the tag for that line
   and 1 is returned.
   If it is not found, 'return_tag' is set to point to the tag for the least
   recently used line and 0 is returned.
*/
static int
get_tag (FRV_CACHE *cache, SI address, FRV_CACHE_TAG **return_tag)
{
  int set;
  int way;
  int bits;
  USI tag;
  FRV_CACHE_TAG *found;
  FRV_CACHE_TAG *available;

  ++cache->statistics.accesses;

  /* First calculate which set this address will fall into. Do this by
     shifting out the bits representing the offset within the line and
     then keeping enough bits to index the set.  */
  set = address & ~(cache->line_size - 1);
  for (bits = cache->line_size - 1; bits != 0; bits >>= 1)
    set >>= 1;
  set &= (cache->sets - 1);
  
  /* Now search the set for a valid tag which matches this address.  At the
     same time make note of the least recently used tag, which we will return
     if no match is found.  */
  available = NULL;
  tag = CACHE_ADDRESS_TAG (cache, address);
  for (way = 0; way < cache->ways; ++way)
    {
      found = CACHE_TAG (cache, set, way);
      /* This tag is available as the least recently used if it is the
	 least recently used seen so far and it is not locked.  */
      if (! found->locked && (available == NULL || available->lru > found->lru))
	available = found;
      if (found->valid && found->tag == tag)
	{
	  *return_tag = found;
	  ++cache->statistics.hits;
	  return 1; /* found it */
	}
    }

  *return_tag = available;
  return 0; /* not found */
}

/* Write the given data out to memory.  */
static void
write_data_to_memory (FRV_CACHE *cache, SI address, char *data, int length)
{
  SIM_CPU *cpu = cache->cpu;
  IADDR pc = CPU_PC_GET (cpu);
  int write_index = 0;

  switch (length)
    {
    case 1:
    default:
      PROFILE_COUNT_WRITE (cpu, address, MODE_QI);
      break;
    case 2:
      PROFILE_COUNT_WRITE (cpu, address, MODE_HI);
      break;
    case 4:
      PROFILE_COUNT_WRITE (cpu, address, MODE_SI);
      break;
    case 8:
      PROFILE_COUNT_WRITE (cpu, address, MODE_DI);
      break;
    }

  for (write_index = 0; write_index < length; ++write_index)
    {
      /* TODO: Better way to copy memory than a byte at a time?  */
      sim_core_write_unaligned_1 (cpu, pc, write_map, address + write_index,
				  data[write_index]);
    }
}

/* Write a cache line out to memory.  */
static void
write_line_to_memory (FRV_CACHE *cache, FRV_CACHE_TAG *tag)
{
  SI address = tag->tag;
  int set = CACHE_TAG_SET_NUMBER (cache, tag);
  int bits;
  for (bits = cache->line_size - 1; bits != 0; bits >>= 1)
    set <<= 1;
  address |= set;
  write_data_to_memory (cache, address, tag->line, cache->line_size);
}

static void
read_data_from_memory (SIM_CPU *current_cpu, SI address, char *buffer,
		       int length)
{
  PCADDR pc = CPU_PC_GET (current_cpu);
  int i;
  PROFILE_COUNT_READ (current_cpu, address, MODE_QI);
  for (i = 0; i < length; ++i)
    {
      /* TODO: Better way to copy memory than a byte at a time?  */
      buffer[i] = sim_core_read_unaligned_1 (current_cpu, pc, read_map,
					     address + i);
    }
}

/* Fill the given cache line from memory.  */
static void
fill_line_from_memory (FRV_CACHE *cache, FRV_CACHE_TAG *tag, SI address)
{
  PCADDR pc;
  int line_alignment;
  SI read_address;
  SIM_CPU *current_cpu = cache->cpu;

  /* If this line is already valid and the cache is in copy-back mode, then
     write this line to memory before refilling it.
     Check the dirty bit first, since it is less likely to be set.  */
  if (tag->dirty && tag->valid)
    {
      int hsr0 = GET_HSR0 ();
      if (GET_HSR0_CBM (hsr0))
	write_line_to_memory (cache, tag);
    }
  else if (tag->line == NULL)
    {
      int line_index = tag - cache->tag_storage;
      tag->line = cache->data_storage + (line_index * cache->line_size);
    }

  pc = CPU_PC_GET (current_cpu);
  line_alignment = cache->line_size - 1;
  read_address = address & ~line_alignment;
  read_data_from_memory (current_cpu, read_address, tag->line,
			 cache->line_size);
  tag->tag = CACHE_ADDRESS_TAG (cache, address);
  tag->valid = 1;
}

/* Update the LRU information for the tags in the same set as the given tag.  */
static void
set_most_recently_used (FRV_CACHE *cache, FRV_CACHE_TAG *tag)
{
  /* All tags in the same set are contiguous, so find the beginning of the
     set by aligning to the size of a set.  */
  FRV_CACHE_TAG *item = cache->tag_storage + CACHE_TAG_SET_START (cache, tag);
  FRV_CACHE_TAG *limit = item + cache->ways;

  while (item < limit)
    {
      if (item->lru > tag->lru)
	--item->lru;
      ++item;
    }
  tag->lru = cache->ways; /* Mark as most recently used.  */
}

/* Update the LRU information for the tags in the same set as the given tag.  */
static void
set_least_recently_used (FRV_CACHE *cache, FRV_CACHE_TAG *tag)
{
  /* All tags in the same set are contiguous, so find the beginning of the
     set by aligning to the size of a set.  */
  FRV_CACHE_TAG *item = cache->tag_storage + CACHE_TAG_SET_START (cache, tag);
  FRV_CACHE_TAG *limit = item + cache->ways;

  while (item < limit)
    {
      if (item->lru != 0 && item->lru < tag->lru)
	++item->lru;
      ++item;
    }
  tag->lru = 0; /* Mark as least recently used.  */
}

/* Find the line containing the given address and load it if it is not
   already loaded.
   Returns the tag of the requested line.  */
static FRV_CACHE_TAG *
find_or_retrieve_cache_line (FRV_CACHE *cache, SI address)
{
  /* See if this data is already in the cache.  */
  FRV_CACHE_TAG *tag;
  int found = get_tag (cache, address, &tag);

  /* Fill the line from memory, if it is not valid.  */
  if (! found)
    {
      /* The tag could be NULL is all ways in the set were used and locked.  */
      if (tag == NULL)
	return tag;

      fill_line_from_memory (cache, tag, address);
      tag->dirty = 0;
    }

  /* Update the LRU information for the tags in this set.  */
  set_most_recently_used (cache, tag);

  return tag;
}

static void
copy_line_to_return_buffer (FRV_CACHE *cache, int pipe, FRV_CACHE_TAG *tag,
			    SI address)
{
  /* A cache line was available for the data.
     Copy the data from the cache line to the output buffer.  */
  memcpy (cache->pipeline[pipe].status.return_buffer.data,
	  tag->line, cache->line_size);
  cache->pipeline[pipe].status.return_buffer.address
    = address & ~(cache->line_size - 1);
  cache->pipeline[pipe].status.return_buffer.valid = 1;
}

static void
copy_memory_to_return_buffer (FRV_CACHE *cache, int pipe, SI address)
{
  address &= ~(cache->line_size - 1);
  read_data_from_memory (cache->cpu, address,
			 cache->pipeline[pipe].status.return_buffer.data,
			 cache->line_size);
  cache->pipeline[pipe].status.return_buffer.address = address;
  cache->pipeline[pipe].status.return_buffer.valid = 1;
}

static void
set_return_buffer_reqno (FRV_CACHE *cache, int pipe, unsigned reqno)
{
  cache->pipeline[pipe].status.return_buffer.reqno = reqno;
}

/* Read data from the given cache.
   Returns the number of cycles required to obtain the data.  */
int
frv_cache_read (FRV_CACHE *cache, int pipe, SI address)
{
  FRV_CACHE_TAG *tag;

  if (non_cache_access (cache, address))
    {
      copy_memory_to_return_buffer (cache, pipe, address);
      return 1;
    }
	
  tag = find_or_retrieve_cache_line (cache, address);

  if (tag == NULL)
    return 0; /* Indicate non-cache-access.  */

  /* A cache line was available for the data.
     Copy the data from the cache line to the output buffer.  */
  copy_line_to_return_buffer (cache, pipe, tag, address);

  return 1; /* TODO - number of cycles unknown */
}

/* Writes data through the given cache.
   The data is assumed to be in target endian order.
   Returns the number of cycles required to write the data.  */
int
frv_cache_write (FRV_CACHE *cache, SI address, char *data, unsigned length)
{
  int copy_back;

  /* See if this data is already in the cache.  */
  SIM_CPU *current_cpu = cache->cpu;
  USI hsr0 = GET_HSR0 ();
  FRV_CACHE_TAG *tag;
  int found;

  if (non_cache_access (cache, address))
    {
      write_data_to_memory (cache, address, data, length);
      return 1;
    }

  found = get_tag (cache, address, &tag);

  /* Write the data to the cache line if one was available and if it is
     either a hit or a miss in copy-back mode.
     The tag may be NULL if all ways were in use and locked on a miss.
  */
  copy_back = GET_HSR0_CBM (GET_HSR0 ());
  if (tag != NULL && (found || copy_back))
    {
      int line_offset;
      /* Load the line from memory first, if it was a miss.  */
      if (! found)
	fill_line_from_memory (cache, tag, address);
      line_offset = address & (cache->line_size - 1);
      memcpy (tag->line + line_offset, data, length);
      tag->dirty = 1;

      /* Update the LRU information for the tags in this set.  */
      set_most_recently_used (cache, tag);
    }

  /* Write the data to memory if there was no line available or we are in
     write-through (not copy-back mode).  */
  if (tag == NULL || ! copy_back)
    {
      write_data_to_memory (cache, address, data, length);
      if (tag != NULL)
	tag->dirty = 0;
    }

  return 1; /* TODO - number of cycles unknown */
}

/* Preload the cache line containing the given address. Lock the
   data if requested.
   Returns the number of cycles required to write the data.  */
int
frv_cache_preload (FRV_CACHE *cache, SI address, USI length, int lock)
{
  int offset;
  int lines;

  if (non_cache_access (cache, address))
    return 1;

  /* preload at least 1 line.  */
  if (length == 0)
    length = 1;

  offset = address & (cache->line_size - 1);
  lines = 1 + (offset + length - 1) / cache->line_size;

  /* Careful with this loop -- length is unsigned.  */
  for (/**/; lines > 0; --lines)
    {
      FRV_CACHE_TAG *tag = find_or_retrieve_cache_line (cache, address);
      if (lock && tag != NULL)
	tag->locked = 1;
      address += cache->line_size;
    }

  return 1; /* TODO - number of cycles unknown */
}

/* Unlock the cache line containing the given address.
   Returns the number of cycles required to unlock the line.  */
int
frv_cache_unlock (FRV_CACHE *cache, SI address)
{
  FRV_CACHE_TAG *tag;
  int found;

  if (non_cache_access (cache, address))
    return 1;

  found = get_tag (cache, address, &tag);

  if (found)
    tag->locked = 0;

  return 1; /* TODO - number of cycles unknown */
}

static void
invalidate_return_buffer (FRV_CACHE *cache, SI address)
{
  /* If this address is in one of the return buffers, then invalidate that
     return buffer.  */
  address &= ~(cache->line_size - 1);
  if (address == cache->pipeline[LS].status.return_buffer.address)
    cache->pipeline[LS].status.return_buffer.valid = 0;
  if (address == cache->pipeline[LD].status.return_buffer.address)
    cache->pipeline[LD].status.return_buffer.valid = 0;
}

/* Invalidate the cache line containing the given address. Flush the
   data if requested.
   Returns the number of cycles required to write the data.  */
int
frv_cache_invalidate (FRV_CACHE *cache, SI address, int flush)
{
  /* See if this data is already in the cache.  */
  FRV_CACHE_TAG *tag;
  int found;

  /* Check for non-cache access.  This operation is still perfromed even if
     the cache is not currently enabled.  */
  if (non_cache_access (cache, address))
    return 1;

  /* If the line is found, invalidate it. If a flush is requested, then flush
     it if it is dirty.  */
  found = get_tag (cache, address, &tag);
  if (found)
    {
      SIM_CPU *cpu;
      /* If a flush is requested, then flush it if it is dirty.  */
      if (tag->dirty && flush)
	write_line_to_memory (cache, tag);
      set_least_recently_used (cache, tag);
      tag->valid = 0;
      tag->locked = 0;

      /* If this is the insn cache, then flush the cpu's scache as well.  */
      cpu = cache->cpu;
      if (cache == CPU_INSN_CACHE (cpu))
	scache_flush_cpu (cpu);
    }

  invalidate_return_buffer (cache, address);

  return 1; /* TODO - number of cycles unknown */
}

/* Invalidate the entire cache. Flush the data if requested.  */
int
frv_cache_invalidate_all (FRV_CACHE *cache, int flush)
{
  /* See if this data is already in the cache.  */
  int elements = cache->sets * cache->ways;
  FRV_CACHE_TAG *tag = cache->tag_storage;
  SIM_CPU *cpu;
  int i;

  for(i = 0; i < elements; ++i, ++tag)
    {
      /* If a flush is requested, then flush it if it is dirty.  */
      if (tag->valid && tag->dirty && flush)
	write_line_to_memory (cache, tag);
      tag->valid = 0;
      tag->locked = 0;
    }


  /* If this is the insn cache, then flush the cpu's scache as well.  */
  cpu = cache->cpu;
  if (cache == CPU_INSN_CACHE (cpu))
    scache_flush_cpu (cpu);

  /* Invalidate both return buffers.  */
  cache->pipeline[LS].status.return_buffer.valid = 0;
  cache->pipeline[LD].status.return_buffer.valid = 0;

  return 1; /* TODO - number of cycles unknown */
}

/* ---------------------------------------------------------------------------
   Functions for operating the cache in cycle accurate mode.
   -------------------------------------------------------------------------  */
/* Convert a VLIW slot to a cache pipeline index.  */
static int
convert_slot_to_index (int slot)
{
  switch (slot)
    {
    case UNIT_I0:
    case UNIT_C:
      return LS;
    case UNIT_I1:
      return LD;
    default:
      abort ();
    }
  return 0;
}

/* Allocate free chains of cache requests.  */
#define FREE_CHAIN_SIZE 16
static FRV_CACHE_REQUEST *frv_cache_request_free_chain = NULL;
static FRV_CACHE_REQUEST *frv_store_request_free_chain = NULL;

static void
allocate_new_cache_requests (void)
{
  int i;
  frv_cache_request_free_chain = xmalloc (FREE_CHAIN_SIZE
					  * sizeof (FRV_CACHE_REQUEST));
  for (i = 0; i < FREE_CHAIN_SIZE - 1; ++i)
    {
      frv_cache_request_free_chain[i].next
	= & frv_cache_request_free_chain[i + 1]; 
    }

  frv_cache_request_free_chain[FREE_CHAIN_SIZE - 1].next = NULL;
}

/* Return the next free request in the queue for the given cache pipeline.  */
static FRV_CACHE_REQUEST *
new_cache_request (void)
{
  FRV_CACHE_REQUEST *req;

  /* Allocate new elements for the free chain if necessary.  */
  if (frv_cache_request_free_chain == NULL)
    allocate_new_cache_requests ();

  req = frv_cache_request_free_chain;
  frv_cache_request_free_chain = req->next;

  return req;
}

/* Return the given cache request to the free chain.  */
static void
free_cache_request (FRV_CACHE_REQUEST *req)
{
  if (req->kind == req_store)
    {
      req->next = frv_store_request_free_chain;
      frv_store_request_free_chain = req;
    }
  else
    {
      req->next = frv_cache_request_free_chain;
      frv_cache_request_free_chain = req;
    }
}

/* Search the free chain for an existing store request with a buffer that's
   large enough.  */
static FRV_CACHE_REQUEST *
new_store_request (int length)
{
  FRV_CACHE_REQUEST *prev = NULL;
  FRV_CACHE_REQUEST *req;
  for (req = frv_store_request_free_chain; req != NULL; req = req->next)
    {
      if (req->u.store.length == length)
	break;
      prev = req;
    }
  if (req != NULL)
    {
      if (prev == NULL)
	frv_store_request_free_chain = req->next;
      else
	prev->next = req->next;
      return req;
    }

  /* No existing request buffer was found, so make a new one.  */
  req = new_cache_request ();
  req->kind = req_store;
  req->u.store.data = xmalloc (length);
  req->u.store.length = length;
  return req;
}

/* Remove the given request from the given pipeline.  */
static void
pipeline_remove_request (FRV_CACHE_PIPELINE *p, FRV_CACHE_REQUEST *request)
{
  FRV_CACHE_REQUEST *next = request->next;
  FRV_CACHE_REQUEST *prev = request->prev;

  if (prev == NULL)
    p->requests = next;
  else
    prev->next = next;

  if (next != NULL)
    next->prev = prev;
}

/* Add the given request to the given pipeline.  */
static void
pipeline_add_request (FRV_CACHE_PIPELINE *p, FRV_CACHE_REQUEST *request)
{
  FRV_CACHE_REQUEST *prev = NULL;
  FRV_CACHE_REQUEST *item;

  /* Add the request in priority order.  0 is the highest priority.  */
  for (item = p->requests; item != NULL; item = item->next)
    {
      if (item->priority > request->priority)
	break;
      prev = item;
    }

  request->next = item;
  request->prev = prev;
  if (prev == NULL)
    p->requests = request;
  else
    prev->next = request;
  if (item != NULL)
    item->prev = request;
}

/* Requeu the given request from the last of the given pipeline.  */
static void
pipeline_requeue_request (FRV_CACHE_PIPELINE *p)
{
  FRV_CACHE_STAGE *stage = & p->stages[LAST_STAGE];
  FRV_CACHE_REQUEST *req = stage->request;
  stage->request = NULL;
  pipeline_add_request (p, req);
}

/* Return the priority lower than the lowest one in this cache pipeline.
   0 is the highest priority.  */
static int
next_priority (FRV_CACHE *cache, FRV_CACHE_PIPELINE *pipeline)
{
  int i, j;
  int pipe;
  int lowest = 0;
  FRV_CACHE_REQUEST *req;

  /* Check the priorities of any queued items.  */
  for (req = pipeline->requests; req != NULL; req = req->next)
    if (req->priority > lowest)
      lowest = req->priority;

  /* Check the priorities of items in the pipeline stages.  */
  for (i = FIRST_STAGE; i < FRV_CACHE_STAGES; ++i)
    {
      FRV_CACHE_STAGE *stage = & pipeline->stages[i];
      if (stage->request != NULL && stage->request->priority > lowest)
        lowest = stage->request->priority;
    }

  /* Check the priorities of load requests waiting in WAR.  These are one
     higher than the request that spawned them.  */
  for (i = 0; i < NUM_WARS; ++i)
    {
      FRV_CACHE_WAR *war = & pipeline->WAR[i];
      if (war->valid && war->priority > lowest)
	lowest = war->priority + 1;
    }

  /* Check the priorities of any BARS or NARS associated with this pipeline.
     These are one higher than the request that spawned them.  */
  pipe = pipeline - cache->pipeline;
  if (cache->BARS.valid && cache->BARS.pipe == pipe 
      && cache->BARS.priority > lowest)
    lowest = cache->BARS.priority + 1;
  if (cache->NARS.valid && cache->NARS.pipe == pipe 
      && cache->NARS.priority > lowest)
    lowest = cache->NARS.priority + 1;

  /* Return a priority 2 lower than the lowest found.  This allows a WAR
     request to be generated with a priority greater than this but less than
     the next higher priority request.  */
  return lowest + 2;
}

static void
add_WAR_request (FRV_CACHE_PIPELINE* pipeline, FRV_CACHE_WAR *war)
{
  /* Add the load request to the indexed pipeline.  */
  FRV_CACHE_REQUEST *req = new_cache_request ();
  req->kind = req_WAR;
  req->reqno = war->reqno;
  req->priority = war->priority;
  req->address = war->address;
  req->u.WAR.preload = war->preload;
  req->u.WAR.lock = war->lock;
  pipeline_add_request (pipeline, req);
}

/* Remove the next request from the given pipeline and return it.  */
static FRV_CACHE_REQUEST *
pipeline_next_request (FRV_CACHE_PIPELINE *p)
{
  FRV_CACHE_REQUEST *first = p->requests;
  if (first != NULL)
    pipeline_remove_request (p, first);
  return first;
}

/* Return the request which is at the given stage of the given pipeline.  */
static FRV_CACHE_REQUEST *
pipeline_stage_request (FRV_CACHE_PIPELINE *p, int stage)
{
  return p->stages[stage].request;
}

static void
advance_pipelines (FRV_CACHE *cache)
{
  int stage;
  int pipe;
  FRV_CACHE_PIPELINE *pipelines = cache->pipeline;

  /* Free the final stage requests.  */
  for (pipe = 0; pipe < FRV_CACHE_PIPELINES; ++pipe)
    {
      FRV_CACHE_REQUEST *req = pipelines[pipe].stages[LAST_STAGE].request;
      if (req != NULL)
	free_cache_request (req);
    }

  /* Shuffle the requests along the pipeline.  */
  for (stage = LAST_STAGE; stage > FIRST_STAGE; --stage)
    {
      for (pipe = 0; pipe < FRV_CACHE_PIPELINES; ++pipe)
	pipelines[pipe].stages[stage] = pipelines[pipe].stages[stage - 1];
    }

  /* Add a new request to the pipeline.  */
  for (pipe = 0; pipe < FRV_CACHE_PIPELINES; ++pipe)
    pipelines[pipe].stages[FIRST_STAGE].request
      = pipeline_next_request (& pipelines[pipe]);
}

/* Handle a request for a load from the given address.  */
void
frv_cache_request_load (FRV_CACHE *cache, unsigned reqno, SI address, int slot)
{
  FRV_CACHE_REQUEST *req;

  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */
  int pipe = convert_slot_to_index (slot);
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];

  /* Add the load request to the indexed pipeline.  */
  req = new_cache_request ();
  req->kind = req_load;
  req->reqno = reqno;
  req->priority = next_priority (cache, pipeline);
  req->address = address;

  pipeline_add_request (pipeline, req);
}

void
frv_cache_request_store (FRV_CACHE *cache, SI address,
			 int slot, char *data, unsigned length)
{
  FRV_CACHE_REQUEST *req;

  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */
  int pipe = convert_slot_to_index (slot);
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];

  /* Add the load request to the indexed pipeline.  */
  req = new_store_request (length);
  req->kind = req_store;
  req->reqno = NO_REQNO;
  req->priority = next_priority (cache, pipeline);
  req->address = address;
  req->u.store.length = length;
  memcpy (req->u.store.data, data, length);

  pipeline_add_request (pipeline, req);
  invalidate_return_buffer (cache, address);
}

/* Handle a request to invalidate the cache line containing the given address.
   Flush the data if requested.  */
void
frv_cache_request_invalidate (FRV_CACHE *cache, unsigned reqno, SI address,
			      int slot, int all, int flush)
{
  FRV_CACHE_REQUEST *req;

  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */
  int pipe = convert_slot_to_index (slot);
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];

  /* Add the load request to the indexed pipeline.  */
  req = new_cache_request ();
  req->kind = req_invalidate;
  req->reqno = reqno;
  req->priority = next_priority (cache, pipeline);
  req->address = address;
  req->u.invalidate.all = all;
  req->u.invalidate.flush = flush;

  pipeline_add_request (pipeline, req);
}

/* Handle a request to preload the cache line containing the given address.  */
void
frv_cache_request_preload (FRV_CACHE *cache, SI address,
			   int slot, int length, int lock)
{
  FRV_CACHE_REQUEST *req;

  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */
  int pipe = convert_slot_to_index (slot);
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];

  /* Add the load request to the indexed pipeline.  */
  req = new_cache_request ();
  req->kind = req_preload;
  req->reqno = NO_REQNO;
  req->priority = next_priority (cache, pipeline);
  req->address = address;
  req->u.preload.length = length;
  req->u.preload.lock = lock;

  pipeline_add_request (pipeline, req);
  invalidate_return_buffer (cache, address);
}

/* Handle a request to unlock the cache line containing the given address.  */
void
frv_cache_request_unlock (FRV_CACHE *cache, SI address, int slot)
{
  FRV_CACHE_REQUEST *req;

  /* slot is a UNIT_*.  Convert it to a cache pipeline index.  */
  int pipe = convert_slot_to_index (slot);
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];

  /* Add the load request to the indexed pipeline.  */
  req = new_cache_request ();
  req->kind = req_unlock;
  req->reqno = NO_REQNO;
  req->priority = next_priority (cache, pipeline);
  req->address = address;

  pipeline_add_request (pipeline, req);
}

/* Check whether this address interferes with a pending request of
   higher priority.  */
static int
address_interference (FRV_CACHE *cache, SI address, FRV_CACHE_REQUEST *req,
		      int pipe)
{
  int i, j;
  int line_mask = ~(cache->line_size - 1);
  int other_pipe;
  int priority = req->priority;
  FRV_CACHE_REQUEST *other_req;
  SI other_address;
  SI all_address;

  address &= line_mask;
  all_address = -1 & line_mask;

  /* Check for collisions in the queue for this pipeline.  */
  for (other_req = cache->pipeline[pipe].requests;
       other_req != NULL;
       other_req = other_req->next)
    {
      other_address = other_req->address & line_mask;
      if ((address == other_address || address == all_address)
	  && priority > other_req->priority)
	return 1;
    }

  /* Check for a collision in the the other pipeline.  */
  other_pipe = pipe ^ 1;
  other_req = cache->pipeline[other_pipe].stages[LAST_STAGE].request;
  if (other_req != NULL)
    {
      other_address = other_req->address & line_mask;
      if (address == other_address || address == all_address)
	return 1;
    }

  /* Check for a collision with load requests waiting in WAR.  */
  for (i = LS; i < FRV_CACHE_PIPELINES; ++i)
    {
      for (j = 0; j < NUM_WARS; ++j)
	{
	  FRV_CACHE_WAR *war = & cache->pipeline[i].WAR[j];
	  if (war->valid
	      && (address == (war->address & line_mask) 
		  || address == all_address)
	      && priority > war->priority)
	    return 1;
	}
      /* If this is not a WAR request, then yield to any WAR requests in
	 either pipeline or to a higher priority request in the same pipeline.
      */
      if (req->kind != req_WAR)
	{
	  for (j = FIRST_STAGE; j < FRV_CACHE_STAGES; ++j)
	    {
	      other_req = cache->pipeline[i].stages[j].request;
	      if (other_req != NULL)
		{
		  if (other_req->kind == req_WAR)
		    return 1;
		  if (i == pipe
		      && (address == (other_req->address & line_mask) 
			  || address == all_address)
		      && priority > other_req->priority)
		    return 1;
		}
	    }
	}
    }

  /* Check for a collision with load requests waiting in ARS.  */
  if (cache->BARS.valid
      && (address == (cache->BARS.address & line_mask)
	  || address == all_address)
      && priority > cache->BARS.priority)
    return 1;
  if (cache->NARS.valid
      && (address == (cache->NARS.address & line_mask)
	  || address == all_address)
      && priority > cache->NARS.priority)
    return 1;

  return 0;
}

/* Wait for a free WAR register in BARS or NARS.  */
static void
wait_for_WAR (FRV_CACHE* cache, int pipe, FRV_CACHE_REQUEST *req)
{
  FRV_CACHE_WAR war;
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];

  if (! cache->BARS.valid)
    {
      cache->BARS.pipe = pipe;
      cache->BARS.reqno = req->reqno;
      cache->BARS.address = req->address;
      cache->BARS.priority = req->priority - 1;
      switch (req->kind)
	{
	case req_load:
	  cache->BARS.preload = 0;
	  cache->BARS.lock = 0;
	  break;
	case req_store:
	  cache->BARS.preload = 1;
	  cache->BARS.lock = 0;
	  break;
	case req_preload:
	  cache->BARS.preload = 1;
	  cache->BARS.lock = req->u.preload.lock;
	  break;
	}
      cache->BARS.valid = 1;
      return;
    }
  if (! cache->NARS.valid)
    {
      cache->NARS.pipe = pipe;
      cache->NARS.reqno = req->reqno;
      cache->NARS.address = req->address;
      cache->NARS.priority = req->priority - 1;
      switch (req->kind)
	{
	case req_load:
	  cache->NARS.preload = 0;
	  cache->NARS.lock = 0;
	  break;
	case req_store:
	  cache->NARS.preload = 1;
	  cache->NARS.lock = 0;
	  break;
	case req_preload:
	  cache->NARS.preload = 1;
	  cache->NARS.lock = req->u.preload.lock;
	  break;
	}
      cache->NARS.valid = 1;
      return;
    }
  /* All wait registers are busy, so resubmit this request.  */
  pipeline_requeue_request (pipeline);
}

/* Find a free WAR register and wait for memory to fetch the data.  */
static void
wait_in_WAR (FRV_CACHE* cache, int pipe, FRV_CACHE_REQUEST *req)
{
  int war;
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];

  /* Find a valid WAR to  hold this request.  */
  for (war = 0; war < NUM_WARS; ++war)
    if (! pipeline->WAR[war].valid)
      break;
  if (war >= NUM_WARS)
    {
      wait_for_WAR (cache, pipe, req);
      return;
    }

  pipeline->WAR[war].address = req->address;
  pipeline->WAR[war].reqno = req->reqno;
  pipeline->WAR[war].priority = req->priority - 1;
  pipeline->WAR[war].latency = cache->memory_latency + 1;
  switch (req->kind)
    {
    case req_load:
      pipeline->WAR[war].preload = 0;
      pipeline->WAR[war].lock = 0;
      break;
    case req_store:
      pipeline->WAR[war].preload = 1;
      pipeline->WAR[war].lock = 0;
      break;
    case req_preload:
      pipeline->WAR[war].preload = 1;
      pipeline->WAR[war].lock = req->u.preload.lock;
      break;
    }
  pipeline->WAR[war].valid = 1;
}

static void
handle_req_load (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
{
  FRV_CACHE_TAG *tag;
  SI address = req->address;

  /* If this address interferes with an existing request, then requeue it.  */
  if (address_interference (cache, address, req, pipe))
    {
      pipeline_requeue_request (& cache->pipeline[pipe]);
      return;
    }

  if (frv_cache_enabled (cache) && ! non_cache_access (cache, address))
    {
      int found = get_tag (cache, address, &tag);

      /* If the data was found, return it to the caller.  */
      if (found)
	{
	  set_most_recently_used (cache, tag);
	  copy_line_to_return_buffer (cache, pipe, tag, address);
	  set_return_buffer_reqno (cache, pipe, req->reqno);
	  return;
	}
    }

  /* The data is not in the cache or this is a non-cache access.  We need to
     wait for the memory unit to fetch it.  Store this request in the WAR in
     the meantime.  */
  wait_in_WAR (cache, pipe, req);
}

static void
handle_req_preload (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
{
  int found;
  FRV_CACHE_WAR war;
  FRV_CACHE_TAG *tag;
  int length;
  int lock;
  int offset;
  int lines;
  int line;
  SI address = req->address;
  SI cur_address;

  if (! frv_cache_enabled (cache) || non_cache_access (cache, address))
    return;

  /* preload at least 1 line.  */
  length = req->u.preload.length;
  if (length == 0)
    length = 1;

  /* Make sure that this request does not interfere with a pending request.  */
  offset = address & (cache->line_size - 1);
  lines = 1 + (offset + length - 1) / cache->line_size;
  cur_address = address & ~(cache->line_size - 1);
  for (line = 0; line < lines; ++line)
    {
      /* If this address interferes with an existing request,
	 then requeue it.  */
      if (address_interference (cache, cur_address, req, pipe))
	{
	  pipeline_requeue_request (& cache->pipeline[pipe]);
	  return;
	}
      cur_address += cache->line_size;
    }

  /* Now process each cache line.  */
  /* Careful with this loop -- length is unsigned.  */
  lock = req->u.preload.lock;
  cur_address = address & ~(cache->line_size - 1);
  for (line = 0; line < lines; ++line)
    {
      /* If the data was found, then lock it if requested.  */
      found = get_tag (cache, cur_address, &tag);
      if (found)
	{
	  if (lock)
	    tag->locked = 1;
	}
      else
	{
	  /* The data is not in the cache.  We need to wait for the memory
	     unit to fetch it.  Store this request in the WAR in the meantime.
	  */
	  wait_in_WAR (cache, pipe, req);
	}
      cur_address += cache->line_size;
    }
}

static void
handle_req_store (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
{
  SIM_CPU *current_cpu;
  FRV_CACHE_TAG *tag;
  int found;
  int copy_back;
  SI address = req->address;
  char *data = req->u.store.data;
  int length = req->u.store.length;

  /* If this address interferes with an existing request, then requeue it.  */
  if (address_interference (cache, address, req, pipe))
    {
      pipeline_requeue_request (& cache->pipeline[pipe]);
      return;
    }

  /* Non-cache access. Write the data directly to memory.  */
  if (! frv_cache_enabled (cache) || non_cache_access (cache, address))
    {
      write_data_to_memory (cache, address, data, length);
      return;
    }

  /* See if the data is in the cache.  */
  found = get_tag (cache, address, &tag);

  /* Write the data to the cache line if one was available and if it is
     either a hit or a miss in copy-back mode.
     The tag may be NULL if all ways were in use and locked on a miss.
  */
  current_cpu = cache->cpu;
  copy_back = GET_HSR0_CBM (GET_HSR0 ());
  if (tag != NULL && (found || copy_back))
    {
      int line_offset;
      /* Load the line from memory first, if it was a miss.  */
      if (! found)
	{
	  /* We need to wait for the memory unit to fetch the data.  
	     Store this request in the WAR and requeue the store request.  */
	  wait_in_WAR (cache, pipe, req);
	  pipeline_requeue_request (& cache->pipeline[pipe]);
	  /* Decrement the counts of accesses and hits because when the requeued
	     request is processed again, it will appear to be a new access and
	     a hit.  */
	  --cache->statistics.accesses;
	  --cache->statistics.hits;
	  return;
	}
      line_offset = address & (cache->line_size - 1);
      memcpy (tag->line + line_offset, data, length);
      invalidate_return_buffer (cache, address);
      tag->dirty = 1;

      /* Update the LRU information for the tags in this set.  */
      set_most_recently_used (cache, tag);
    }

  /* Write the data to memory if there was no line available or we are in
     write-through (not copy-back mode).  */
  if (tag == NULL || ! copy_back)
    {
      write_data_to_memory (cache, address, data, length);
      if (tag != NULL)
	tag->dirty = 0;
    }
}

static void
handle_req_invalidate (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
{
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
  SI address = req->address;
  SI interfere_address = req->u.invalidate.all ? -1 : address;

  /* If this address interferes with an existing request, then requeue it.  */
  if (address_interference (cache, interfere_address, req, pipe))
    {
      pipeline_requeue_request (pipeline);
      return;
    }

  /* Invalidate the cache line now.  This function already checks for
     non-cache access.  */
  if (req->u.invalidate.all)
    frv_cache_invalidate_all (cache, req->u.invalidate.flush);
  else
    frv_cache_invalidate (cache, address, req->u.invalidate.flush);
  if (req->u.invalidate.flush)
    {
      pipeline->status.flush.reqno = req->reqno;
      pipeline->status.flush.address = address;
      pipeline->status.flush.valid = 1;
    }
}

static void
handle_req_unlock (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
{
  FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
  SI address = req->address;

  /* If this address interferes with an existing request, then requeue it.  */
  if (address_interference (cache, address, req, pipe))
    {
      pipeline_requeue_request (pipeline);
      return;
    }

  /* Unlock the cache line.  This function checks for non-cache access.  */
  frv_cache_unlock (cache, address);
}

static void
handle_req_WAR (FRV_CACHE *cache, int pipe, FRV_CACHE_REQUEST *req)
{
  char *buffer;
  FRV_CACHE_TAG *tag;
  SI address = req->address;

  if (frv_cache_enabled (cache) && ! non_cache_access (cache, address))
    {
      /* Look for the data in the cache.  The statistics of cache hit or
	 miss have already been recorded, so save and restore the stats before
	 and after obtaining the cache line.  */
      FRV_CACHE_STATISTICS save_stats = cache->statistics;
      tag = find_or_retrieve_cache_line (cache, address);
      cache->statistics = save_stats;
      if (tag != NULL)
	{
	  if (! req->u.WAR.preload)
	    {
	      copy_line_to_return_buffer (cache, pipe, tag, address);
	      set_return_buffer_reqno (cache, pipe, req->reqno);
	    }
	  else 
	    {
	      invalidate_return_buffer (cache, address);
	      if (req->u.WAR.lock)
		tag->locked = 1;
	    }
	  return;
	}
    }

  /* All cache lines in the set were locked, so just copy the data to the
     return buffer directly.  */
  if (! req->u.WAR.preload)
    {
      copy_memory_to_return_buffer (cache, pipe, address);
      set_return_buffer_reqno (cache, pipe, req->reqno);
    }
}

/* Resolve any conflicts and/or execute the given requests.  */
static void
arbitrate_requests (FRV_CACHE *cache)
{
  int pipe;
  /* Simply execute the requests in the final pipeline stages.  */
  for (pipe = LS; pipe < FRV_CACHE_PIPELINES; ++pipe)
    {
      FRV_CACHE_REQUEST *req
	= pipeline_stage_request (& cache->pipeline[pipe], LAST_STAGE);
      /* Make sure that there is a request to handle.  */
      if (req == NULL)
	continue;

      /* Handle the request.  */
      switch (req->kind)
	{
	case req_load:
	  handle_req_load (cache, pipe, req);
	  break;
	case req_store:
	  handle_req_store (cache, pipe, req);
	  break;
	case req_invalidate:
	  handle_req_invalidate (cache, pipe, req);
	  break;
	case req_preload:
	  handle_req_preload (cache, pipe, req);
	  break;
	case req_unlock:
	  handle_req_unlock (cache, pipe, req);
	  break;
	case req_WAR:
	  handle_req_WAR (cache, pipe, req);
	  break;
	default:
	  abort ();
	}
    }
}

/* Move a waiting ARS register to a free WAR register.  */
static void
move_ARS_to_WAR (FRV_CACHE *cache, int pipe, FRV_CACHE_WAR *war)
{
  /* If BARS is valid for this pipe, then move it to the given WAR. Move
     NARS to BARS if it is valid.  */
  if (cache->BARS.valid && cache->BARS.pipe == pipe)
    {
      war->address = cache->BARS.address;
      war->reqno = cache->BARS.reqno;
      war->priority = cache->BARS.priority;
      war->preload = cache->BARS.preload;
      war->lock = cache->BARS.lock;
      war->latency = cache->memory_latency + 1;
      war->valid = 1;
      if (cache->NARS.valid)
	{
	  cache->BARS = cache->NARS;
	  cache->NARS.valid = 0;
	}
      else
	cache->BARS.valid = 0;
      return;
    }
  /* If NARS is valid for this pipe, then move it to the given WAR.  */
  if (cache->NARS.valid && cache->NARS.pipe == pipe)
    {
      war->address = cache->NARS.address;
      war->reqno = cache->NARS.reqno;
      war->priority = cache->NARS.priority;
      war->preload = cache->NARS.preload;
      war->lock = cache->NARS.lock;
      war->latency = cache->memory_latency + 1;
      war->valid = 1;
      cache->NARS.valid = 0;
    }
}

/* Decrease the latencies of the various states in the cache.  */
static void
decrease_latencies (FRV_CACHE *cache)
{
  int pipe, j;
  /* Check the WAR registers.  */
  for (pipe = LS; pipe < FRV_CACHE_PIPELINES; ++pipe)
    {
      FRV_CACHE_PIPELINE *pipeline = & cache->pipeline[pipe];
      for (j = 0; j < NUM_WARS; ++j)
	{
	  FRV_CACHE_WAR *war = & pipeline->WAR[j];
	  if (war->valid)
	    {
	      --war->latency;
	      /* If the latency has expired, then submit a WAR request to the
		 pipeline.  */
	      if (war->latency <= 0)
		{
		  add_WAR_request (pipeline, war);
		  war->valid = 0;
		  move_ARS_to_WAR (cache, pipe, war);
		}
	    }
	}
    }
}

/* Run the cache for the given number of cycles.  */
void
frv_cache_run (FRV_CACHE *cache, int cycles)
{
  int i;
  for (i = 0; i < cycles; ++i)
    {
      advance_pipelines (cache);
      arbitrate_requests (cache);
      decrease_latencies (cache);
    }
}

int
frv_cache_read_passive_SI (FRV_CACHE *cache, SI address, SI *value)
{
  SI offset;
  FRV_CACHE_TAG *tag;

  if (non_cache_access (cache, address))
    return 0;

  {
    FRV_CACHE_STATISTICS save_stats = cache->statistics;
    int found = get_tag (cache, address, &tag);
    cache->statistics = save_stats;

    if (! found)
      return 0; /* Indicate non-cache-access.  */
  }

  /* A cache line was available for the data.
     Extract the target data from the line.  */
  offset = address & (cache->line_size - 1);
  *value = T2H_4 (*(SI *)(tag->line + offset));
  return 1;
}

/* Check the return buffers of the data cache to see if the requested data is
   available.  */
int
frv_cache_data_in_buffer (FRV_CACHE* cache, int pipe, SI address,
			  unsigned reqno)
{
  return cache->pipeline[pipe].status.return_buffer.valid
    && cache->pipeline[pipe].status.return_buffer.reqno == reqno
    && cache->pipeline[pipe].status.return_buffer.address <= address
    && cache->pipeline[pipe].status.return_buffer.address + cache->line_size
       > address;
}

/* Check to see if the requested data has been flushed.  */
int
frv_cache_data_flushed (FRV_CACHE* cache, int pipe, SI address, unsigned reqno)
{
  return cache->pipeline[pipe].status.flush.valid
    && cache->pipeline[pipe].status.flush.reqno == reqno
    && cache->pipeline[pipe].status.flush.address <= address
    && cache->pipeline[pipe].status.flush.address + cache->line_size
       > address;
}
