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

#define WANT_CPU frvbf
#define WANT_CPU_FRVBF

#include "libiberty.h"
#include "sim-main.h"
#include "cache.h"
#include "bfd.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;
}
