/* Caching code.  Typically used by remote back ends for
   caching remote memory.

   Copyright 1992-1993, 1995, 1998-1999 Free Software Foundation, Inc.

   This file is part of GDB.

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "dcache.h"
#include "gdbcmd.h"
#include "gdb_string.h"
#include "gdbcore.h"

/* 
   The data cache could lead to incorrect results because it doesn't know
   about volatile variables, thus making it impossible to debug
   functions which use memory mapped I/O devices.

   set remotecache 0

   In those cases.

   In general the dcache speeds up performance, some speed improvement
   comes from the actual caching mechanism, but the major gain is in
   the reduction of the remote protocol overhead; instead of reading
   or writing a large area of memory in 4 byte requests, the cache
   bundles up the requests into 32 byte (actually LINE_SIZE) chunks.
   Reducing the overhead to an eighth of what it was.  This is very
   obvious when displaying a large amount of data,

   eg, x/200x 0 

   caching     |   no    yes 
   ---------------------------- 
   first time  |   4 sec  2 sec improvement due to chunking 
   second time |   4 sec  0 sec improvement due to caching

   The cache structure is unusual, we keep a number of cache blocks
   (DCACHE_SIZE) and each one caches a LINE_SIZEed area of memory.
   Within each line we remember the address of the line (always a
   multiple of the LINE_SIZE) and a vector of bytes over the range.
   There's another vector which contains the state of the bytes.

   ENTRY_BAD means that the byte is just plain wrong, and has no
   correspondence with anything else (as it would when the cache is
   turned on, but nothing has been done to it.

   ENTRY_DIRTY means that the byte has some data in it which should be
   written out to the remote target one day, but contains correct
   data.  ENTRY_OK means that the data is the same in the cache as it
   is in remote memory.


   The ENTRY_DIRTY state is necessary because GDB likes to write large
   lumps of memory in small bits.  If the caching mechanism didn't
   maintain the DIRTY information, then something like a two byte
   write would mean that the entire cache line would have to be read,
   the two bytes modified and then written out again.  The alternative
   would be to not read in the cache line in the first place, and just
   write the two bytes directly into target memory.  The trouble with
   that is that it really nails performance, because of the remote
   protocol overhead.  This way, all those little writes are bundled
   up into an entire cache line write in one go, without having to
   read the cache line in the first place.


 */


/* This value regulates the number of cache blocks stored.
   Smaller values reduce the time spent searching for a cache
   line, and reduce memory requirements, but increase the risk
   of a line not being in memory */

#define DCACHE_SIZE 64

/* This value regulates the size of a cache line.  Smaller values
   reduce the time taken to read a single byte, but reduce overall
   throughput.  */

#define LINE_SIZE_POWER (5)
#define LINE_SIZE (1 << LINE_SIZE_POWER)

/* Each cache block holds LINE_SIZE bytes of data
   starting at a multiple-of-LINE_SIZE address.  */

#define LINE_SIZE_MASK  ((LINE_SIZE - 1))
#define XFORM(x) 	((x) & LINE_SIZE_MASK)
#define MASK(x)         ((x) & ~LINE_SIZE_MASK)


#define ENTRY_BAD   0		/* data at this byte is wrong */
#define ENTRY_DIRTY 1		/* data at this byte needs to be written back */
#define ENTRY_OK    2		/* data at this byte is same as in memory */


struct dcache_block
  {
    struct dcache_block *p;	/* next in list */
    CORE_ADDR addr;		/* Address for which data is recorded.  */
    char data[LINE_SIZE];	/* bytes at given address */
    unsigned char state[LINE_SIZE];	/* what state the data is in */

    /* whether anything in state is dirty - used to speed up the 
       dirty scan. */
    int anydirty;

    int refs;
  };


struct dcache_struct
  {
    /* Function to actually read the target memory. */
    memxferfunc read_memory;

    /* Function to actually write the target memory */
    memxferfunc write_memory;

    /* free list */
    struct dcache_block *free_head;
    struct dcache_block *free_tail;

    /* in use list */
    struct dcache_block *valid_head;
    struct dcache_block *valid_tail;

    /* The cache itself. */
    struct dcache_block *the_cache;

    /* potentially, if the cache was enabled, and then turned off, and
       then turned on again, the stuff in it could be stale, so this is
       used to mark it */
    int cache_has_stuff;
  };

static int dcache_poke_byte PARAMS ((DCACHE * dcache, CORE_ADDR addr,
				     char *ptr));

static int dcache_peek_byte PARAMS ((DCACHE * dcache, CORE_ADDR addr,
				     char *ptr));

static struct dcache_block *dcache_hit PARAMS ((DCACHE * dcache,
						CORE_ADDR addr));

static int dcache_write_line PARAMS ((DCACHE * dcache, struct dcache_block * db));

static struct dcache_block *dcache_alloc PARAMS ((DCACHE * dcache));

static int dcache_writeback PARAMS ((DCACHE * dcache));

static void dcache_info PARAMS ((char *exp, int tty));

void _initialize_dcache PARAMS ((void));

static int dcache_enabled_p = 0;

DCACHE *last_cache;		/* Used by info dcache */


/* Free all the data cache blocks, thus discarding all cached data.  */

void
dcache_flush (dcache)
     DCACHE *dcache;
{
  int i;
  dcache->valid_head = 0;
  dcache->valid_tail = 0;

  dcache->free_head = 0;
  dcache->free_tail = 0;

  for (i = 0; i < DCACHE_SIZE; i++)
    {
      struct dcache_block *db = dcache->the_cache + i;

      if (!dcache->free_head)
	dcache->free_head = db;
      else
	dcache->free_tail->p = db;
      dcache->free_tail = db;
      db->p = 0;
    }

  dcache->cache_has_stuff = 0;

  return;
}

/* If addr is present in the dcache, return the address of the block
   containing it. */

static struct dcache_block *
dcache_hit (dcache, addr)
     DCACHE *dcache;
     CORE_ADDR addr;
{
  register struct dcache_block *db;

  /* Search all cache blocks for one that is at this address.  */
  db = dcache->valid_head;

  while (db)
    {
      if (MASK (addr) == db->addr)
	{
	  db->refs++;
	  return db;
	}
      db = db->p;
    }

  return NULL;
}

/* Make sure that anything in this line which needs to
   be written is. */

static int
dcache_write_line (dcache, db)
     DCACHE *dcache;
     register struct dcache_block *db;
{
  int s;
  int e;
  s = 0;
  if (db->anydirty)
    {
      for (s = 0; s < LINE_SIZE; s++)
	{
	  if (db->state[s] == ENTRY_DIRTY)
	    {
	      int len = 0;
	      for (e = s; e < LINE_SIZE; e++, len++)
		if (db->state[e] != ENTRY_DIRTY)
		  break;
	      {
		/* all bytes from s..s+len-1 need to
		   be written out */
		int done = 0;
		while (done < len)
		  {
		    int t = dcache->write_memory (db->addr + s + done,
						  db->data + s + done,
						  len - done);
		    if (t == 0)
		      return 0;
		    done += t;
		  }
		memset (db->state + s, ENTRY_OK, len);
		s = e;
	      }
	    }
	}
      db->anydirty = 0;
    }
  return 1;
}


/* Get a free cache block, put or keep it on the valid list,
   and return its address.  The caller should store into the block
   the address and data that it describes, then remque it from the
   free list and insert it into the valid list.  This procedure
   prevents errors from creeping in if a memory retrieval is
   interrupted (which used to put garbage blocks in the valid
   list...).  */

static struct dcache_block *
dcache_alloc (dcache)
     DCACHE *dcache;
{
  register struct dcache_block *db;

  if (dcache_enabled_p == 0)
    abort ();

  /* Take something from the free list */
  db = dcache->free_head;
  if (db)
    {
      dcache->free_head = db->p;
    }
  else
    {
      /* Nothing left on free list, so grab one from the valid list */
      db = dcache->valid_head;
      dcache->valid_head = db->p;

      dcache_write_line (dcache, db);
    }

  /* append this line to end of valid list */
  if (!dcache->valid_head)
    dcache->valid_head = db;
  else
    dcache->valid_tail->p = db;
  dcache->valid_tail = db;
  db->p = 0;

  return db;
}

/* Using the data cache DCACHE return the contents of the byte at
   address ADDR in the remote machine.  

   Returns 0 on error. */

static int
dcache_peek_byte (dcache, addr, ptr)
     DCACHE *dcache;
     CORE_ADDR addr;
     char *ptr;
{
  register struct dcache_block *db = dcache_hit (dcache, addr);
  int ok = 1;
  int done = 0;
  if (db == 0
      || db->state[XFORM (addr)] == ENTRY_BAD)
    {
      if (db)
	{
	  dcache_write_line (dcache, db);
	}
      else
	db = dcache_alloc (dcache);
      immediate_quit++;
      db->addr = MASK (addr);
      while (done < LINE_SIZE)
	{
	  int try =
	  (*dcache->read_memory)
	  (db->addr + done,
	   db->data + done,
	   LINE_SIZE - done);
	  if (try == 0)
	    return 0;
	  done += try;
	}
      immediate_quit--;

      memset (db->state, ENTRY_OK, sizeof (db->data));
      db->anydirty = 0;
    }
  *ptr = db->data[XFORM (addr)];
  return ok;
}

/* Writeback any dirty lines to the remote. */
static int
dcache_writeback (dcache)
     DCACHE *dcache;
{
  struct dcache_block *db;

  db = dcache->valid_head;

  while (db)
    {
      if (!dcache_write_line (dcache, db))
	return 0;
      db = db->p;
    }
  return 1;
}


/* Using the data cache DCACHE return the contents of the word at
   address ADDR in the remote machine.  */
int
dcache_fetch (dcache, addr)
     DCACHE *dcache;
     CORE_ADDR addr;
{
  int res;

  if (dcache_xfer_memory (dcache, addr, (char *) &res, sizeof res, 0) != sizeof res)
    memory_error (EIO, addr);

  return res;
}


/* Write the byte at PTR into ADDR in the data cache.
   Return zero on write error.
 */

static int
dcache_poke_byte (dcache, addr, ptr)
     DCACHE *dcache;
     CORE_ADDR addr;
     char *ptr;
{
  register struct dcache_block *db = dcache_hit (dcache, addr);

  if (!db)
    {
      db = dcache_alloc (dcache);
      db->addr = MASK (addr);
      memset (db->state, ENTRY_BAD, sizeof (db->data));
    }

  db->data[XFORM (addr)] = *ptr;
  db->state[XFORM (addr)] = ENTRY_DIRTY;
  db->anydirty = 1;
  return 1;
}

/* Write the word at ADDR both in the data cache and in the remote machine.  
   Return zero on write error.
 */

int
dcache_poke (dcache, addr, data)
     DCACHE *dcache;
     CORE_ADDR addr;
     int data;
{
  if (dcache_xfer_memory (dcache, addr, (char *) &data, sizeof data, 1) != sizeof data)
    return 0;

  return dcache_writeback (dcache);
}


/* Initialize the data cache.  */
DCACHE *
dcache_init (reading, writing)
     memxferfunc reading;
     memxferfunc writing;
{
  int csize = sizeof (struct dcache_block) * DCACHE_SIZE;
  DCACHE *dcache;

  dcache = (DCACHE *) xmalloc (sizeof (*dcache));
  dcache->read_memory = reading;
  dcache->write_memory = writing;

  dcache->the_cache = (struct dcache_block *) xmalloc (csize);
  memset (dcache->the_cache, 0, csize);

  dcache_flush (dcache);

  last_cache = dcache;
  return dcache;
}

/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
   to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
   nonzero. 

   Returns length of data written or read; 0 for error.  

   This routine is indended to be called by remote_xfer_ functions. */

int
dcache_xfer_memory (dcache, memaddr, myaddr, len, should_write)
     DCACHE *dcache;
     CORE_ADDR memaddr;
     char *myaddr;
     int len;
     int should_write;
{
  int i;

  if (dcache_enabled_p)
    {
      int (*xfunc) PARAMS ((DCACHE * dcache, CORE_ADDR addr, char *ptr));
      xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;

      for (i = 0; i < len; i++)
	{
	  if (!xfunc (dcache, memaddr + i, myaddr + i))
	    return 0;
	}
      dcache->cache_has_stuff = 1;
      dcache_writeback (dcache);
    }
  else
    {
      memxferfunc xfunc;
      xfunc = should_write ? dcache->write_memory : dcache->read_memory;

      if (dcache->cache_has_stuff)
	dcache_flush (dcache);

      len = xfunc (memaddr, myaddr, len);
    }
  return len;
}

static void
dcache_info (exp, tty)
     char *exp;
     int tty;
{
  struct dcache_block *p;

  if (!dcache_enabled_p)
    {
      printf_filtered ("Dcache not enabled\n");
      return;
    }
  printf_filtered ("Dcache enabled, line width %d, depth %d\n",
		   LINE_SIZE, DCACHE_SIZE);

  printf_filtered ("Cache state:\n");

  for (p = last_cache->valid_head; p; p = p->p)
    {
      int j;
      printf_filtered ("Line at %s, referenced %d times\n",
		       paddr (p->addr), p->refs);

      for (j = 0; j < LINE_SIZE; j++)
	printf_filtered ("%02x", p->data[j] & 0xFF);
      printf_filtered ("\n");

      for (j = 0; j < LINE_SIZE; j++)
	printf_filtered (" %2x", p->state[j]);
      printf_filtered ("\n");
    }
}

/* Turn dcache on or off. */
void
set_dcache_state (int what)
{
  dcache_enabled_p = !!what;
}

void
_initialize_dcache ()
{
  add_show_from_set
    (add_set_cmd ("remotecache", class_support, var_boolean,
		  (char *) &dcache_enabled_p,
		  "\
Set cache use for remote targets.\n\
When on, use data caching for remote targets.  For many remote targets\n\
this option can offer better throughput for reading target memory.\n\
Unfortunately, gdb does not currently know anything about volatile\n\
registers and thus data caching will produce incorrect results with\n\
volatile registers are in use.  By default, this option is off.",
		  &setlist),
     &showlist);

  add_info ("dcache", dcache_info,
	    "Print information on the dcache performance.");

}
