/* Caching code for GDB, the GNU debugger.

   Copyright (C) 1992-2017 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 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/>.  */

#include "defs.h"
#include "dcache.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "target-dcache.h"
#include "inferior.h"
#include "splay-tree.h"

/* Commands with a prefix of `{set,show} dcache'.  */
static struct cmd_list_element *dcache_set_list = NULL;
static struct cmd_list_element *dcache_show_list = NULL;

/* 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 the nocache
   memory region attribute 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 LINE_SIZE chunks, reducing overhead
   significantly.  This is most useful when accessing a large amount
   of data, such as when performing a backtrace.

   The cache is a splay tree along with a linked list for replacement.
   Each block caches a LINE_SIZE area of memory.  Within each line we
   remember the address of the line (which must be a multiple of
   LINE_SIZE) and the actual data block.

   Lines are only allocated as needed, so DCACHE_SIZE really specifies the
   *maximum* number of lines in the cache.

   At present, the cache is write-through rather than writeback: as soon
   as data is written to the cache, it is also immediately written to
   the target.  Therefore, cache lines are never "dirty".  Whether a given
   line is valid or not depends on where it is stored in the dcache_struct;
   there is no per-block valid flag.  */

/* NOTE: Interaction of dcache and memory region attributes

   As there is no requirement that memory region attributes be aligned
   to or be a multiple of the dcache page size, dcache_read_line() and
   dcache_write_line() must break up the page by memory region.  If a
   chunk does not have the cache attribute set, an invalid memory type
   is set, etc., then the chunk is skipped.  Those chunks are handled
   in target_xfer_memory() (or target_xfer_memory_partial()).

   This doesn't occur very often.  The most common occurance is when
   the last bit of the .text segment and the first bit of the .data
   segment fall within the same dcache page with a ro/cacheable memory
   region defined for the .text segment and a rw/non-cacheable memory
   region defined for the .data segment.  */

/* The maximum number of lines stored.  The total size of the cache is
   equal to DCACHE_SIZE times LINE_SIZE.  */
#define DCACHE_DEFAULT_SIZE 4096
static unsigned dcache_size = DCACHE_DEFAULT_SIZE;

/* The default size of a cache line.  Smaller values reduce the time taken to
   read a single byte and make the cache more granular, but increase
   overhead and reduce the effectiveness of the cache as a prefetcher.  */
#define DCACHE_DEFAULT_LINE_SIZE 64
static unsigned dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;

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

#define LINE_SIZE_MASK(dcache)  ((dcache->line_size - 1))
#define XFORM(dcache, x) 	((x) & LINE_SIZE_MASK (dcache))
#define MASK(dcache, x)         ((x) & ~LINE_SIZE_MASK (dcache))

struct dcache_block
{
  /* For least-recently-allocated and free lists.  */
  struct dcache_block *prev;
  struct dcache_block *next;

  CORE_ADDR addr;		/* address of data */
  int refs;			/* # hits */
  gdb_byte data[1];		/* line_size bytes at given address */
};

struct dcache_struct
{
  splay_tree tree;
  struct dcache_block *oldest; /* least-recently-allocated list.  */

  /* The free list is maintained identically to OLDEST to simplify
     the code: we only need one set of accessors.  */
  struct dcache_block *freelist;

  /* The number of in-use lines in the cache.  */
  int size;
  CORE_ADDR line_size;  /* current line_size.  */

  /* The ptid of last inferior to use cache or null_ptid.  */
  ptid_t ptid;
};

typedef void (block_func) (struct dcache_block *block, void *param);

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

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

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

static void info_dcache_command (char *exp, int tty);

static int dcache_enabled_p = 0; /* OBSOLETE */

static void
show_dcache_enabled_p (struct ui_file *file, int from_tty,
		       struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file, _("Deprecated remotecache flag is %s.\n"), value);
}

/* Add BLOCK to circular block list BLIST, behind the block at *BLIST.
   *BLIST is not updated (unless it was previously NULL of course).
   This is for the least-recently-allocated list's sake:
   BLIST points to the oldest block.
   ??? This makes for poor cache usage of the free list,
   but is it measurable?  */

static void
append_block (struct dcache_block **blist, struct dcache_block *block)
{
  if (*blist)
    {
      block->next = *blist;
      block->prev = (*blist)->prev;
      block->prev->next = block;
      (*blist)->prev = block;
      /* We don't update *BLIST here to maintain the invariant that for the
	 least-recently-allocated list *BLIST points to the oldest block.  */
    }
  else
    {
      block->next = block;
      block->prev = block;
      *blist = block;
    }
}

/* Remove BLOCK from circular block list BLIST.  */

static void
remove_block (struct dcache_block **blist, struct dcache_block *block)
{
  if (block->next == block)
    {
      *blist = NULL;
    }
  else
    {
      block->next->prev = block->prev;
      block->prev->next = block->next;
      /* If we removed the block *BLIST points to, shift it to the next block
	 to maintain the invariant that for the least-recently-allocated list
	 *BLIST points to the oldest block.  */
      if (*blist == block)
	*blist = block->next;
    }
}

/* Iterate over all elements in BLIST, calling FUNC.
   PARAM is passed to FUNC.
   FUNC may remove the block it's passed, but only that block.  */

static void
for_each_block (struct dcache_block **blist, block_func *func, void *param)
{
  struct dcache_block *db;

  if (*blist == NULL)
    return;

  db = *blist;
  do
    {
      struct dcache_block *next = db->next;

      func (db, param);
      db = next;
    }
  while (*blist && db != *blist);
}

/* BLOCK_FUNC routine for dcache_free.  */

static void
free_block (struct dcache_block *block, void *param)
{
  xfree (block);
}

/* Free a data cache.  */

void
dcache_free (DCACHE *dcache)
{
  splay_tree_delete (dcache->tree);
  for_each_block (&dcache->oldest, free_block, NULL);
  for_each_block (&dcache->freelist, free_block, NULL);
  xfree (dcache);
}


/* BLOCK_FUNC function for dcache_invalidate.
   This doesn't remove the block from the oldest list on purpose.
   dcache_invalidate will do it later.  */

static void
invalidate_block (struct dcache_block *block, void *param)
{
  DCACHE *dcache = (DCACHE *) param;

  splay_tree_remove (dcache->tree, (splay_tree_key) block->addr);
  append_block (&dcache->freelist, block);
}

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

void
dcache_invalidate (DCACHE *dcache)
{
  for_each_block (&dcache->oldest, invalidate_block, dcache);

  dcache->oldest = NULL;
  dcache->size = 0;
  dcache->ptid = null_ptid;

  if (dcache->line_size != dcache_line_size)
    {
      /* We've been asked to use a different line size.
	 All of our freelist blocks are now the wrong size, so free them.  */

      for_each_block (&dcache->freelist, free_block, dcache);
      dcache->freelist = NULL;
      dcache->line_size = dcache_line_size;
    }
}

/* Invalidate the line associated with ADDR.  */

static void
dcache_invalidate_line (DCACHE *dcache, CORE_ADDR addr)
{
  struct dcache_block *db = dcache_hit (dcache, addr);

  if (db)
    {
      splay_tree_remove (dcache->tree, (splay_tree_key) db->addr);
      remove_block (&dcache->oldest, db);
      append_block (&dcache->freelist, db);
      --dcache->size;
    }
}

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

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

  splay_tree_node node = splay_tree_lookup (dcache->tree,
					    (splay_tree_key) MASK (dcache, addr));

  if (!node)
    return NULL;

  db = (struct dcache_block *) node->value;
  db->refs++;
  return db;
}

/* Fill a cache line from target memory.
   The result is 1 for success, 0 if the (entire) cache line
   wasn't readable.  */

static int
dcache_read_line (DCACHE *dcache, struct dcache_block *db)
{
  CORE_ADDR memaddr;
  gdb_byte *myaddr;
  int len;
  int res;
  int reg_len;
  struct mem_region *region;

  len = dcache->line_size;
  memaddr = db->addr;
  myaddr  = db->data;

  while (len > 0)
    {
      /* Don't overrun if this block is right at the end of the region.  */
      region = lookup_mem_region (memaddr);
      if (region->hi == 0 || memaddr + len < region->hi)
	reg_len = len;
      else
	reg_len = region->hi - memaddr;

      /* Skip non-readable regions.  The cache attribute can be ignored,
         since we may be loading this for a stack access.  */
      if (region->attrib.mode == MEM_WO)
	{
	  memaddr += reg_len;
	  myaddr  += reg_len;
	  len     -= reg_len;
	  continue;
	}

      res = target_read_raw_memory (memaddr, myaddr, reg_len);
      if (res != 0)
	return 0;

      memaddr += reg_len;
      myaddr += reg_len;
      len -= reg_len;
    }

  return 1;
}

/* Get a free cache block, put or keep it on the valid list,
   and return its address.  */

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

  if (dcache->size >= dcache_size)
    {
      /* Evict the least recently allocated line.  */
      db = dcache->oldest;
      remove_block (&dcache->oldest, db);

      splay_tree_remove (dcache->tree, (splay_tree_key) db->addr);
    }
  else
    {
      db = dcache->freelist;
      if (db)
	remove_block (&dcache->freelist, db);
      else
	db = ((struct dcache_block *)
	      xmalloc (offsetof (struct dcache_block, data)
		       + dcache->line_size));

      dcache->size++;
    }

  db->addr = MASK (dcache, addr);
  db->refs = 0;

  /* Put DB at the end of the list, it's the newest.  */
  append_block (&dcache->oldest, db);

  splay_tree_insert (dcache->tree, (splay_tree_key) db->addr,
		     (splay_tree_value) db);

  return db;
}

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

   Returns 1 for success, 0 for error.  */

static int
dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr)
{
  struct dcache_block *db = dcache_hit (dcache, addr);

  if (!db)
    {
      db = dcache_alloc (dcache, addr);

      if (!dcache_read_line (dcache, db))
         return 0;
    }

  *ptr = db->data[XFORM (dcache, addr)];
  return 1;
}

/* Write the byte at PTR into ADDR in the data cache.

   The caller should have written the data through to target memory
   already.

   If ADDR is not in cache, this function does nothing; writing to an
   area of memory which wasn't present in the cache doesn't cause it
   to be loaded in.  */

static void
dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, const gdb_byte *ptr)
{
  struct dcache_block *db = dcache_hit (dcache, addr);

  if (db)
    db->data[XFORM (dcache, addr)] = *ptr;
}

static int
dcache_splay_tree_compare (splay_tree_key a, splay_tree_key b)
{
  if (a > b)
    return 1;
  else if (a == b)
    return 0;
  else
    return -1;
}

/* Allocate and initialize a data cache.  */

DCACHE *
dcache_init (void)
{
  DCACHE *dcache = XNEW (DCACHE);

  dcache->tree = splay_tree_new (dcache_splay_tree_compare,
				 NULL,
				 NULL);

  dcache->oldest = NULL;
  dcache->freelist = NULL;
  dcache->size = 0;
  dcache->line_size = dcache_line_size;
  dcache->ptid = null_ptid;

  return dcache;
}


/* Read LEN bytes from dcache memory at MEMADDR, transferring to
   debugger address MYADDR.  If the data is presently cached, this
   fills the cache.  Arguments/return are like the target_xfer_partial
   interface.  */

enum target_xfer_status
dcache_read_memory_partial (struct target_ops *ops, DCACHE *dcache,
			    CORE_ADDR memaddr, gdb_byte *myaddr,
			    ULONGEST len, ULONGEST *xfered_len)
{
  ULONGEST i;

  /* If this is a different inferior from what we've recorded,
     flush the cache.  */

  if (! ptid_equal (inferior_ptid, dcache->ptid))
    {
      dcache_invalidate (dcache);
      dcache->ptid = inferior_ptid;
    }

  for (i = 0; i < len; i++)
    {
      if (!dcache_peek_byte (dcache, memaddr + i, myaddr + i))
	{
	  /* That failed.  Discard its cache line so we don't have a
	     partially read line.  */
	  dcache_invalidate_line (dcache, memaddr + i);
	  break;
	}
    }

  if (i == 0)
    {
      /* Even though reading the whole line failed, we may be able to
	 read a piece starting where the caller wanted.  */
      return raw_memory_xfer_partial (ops, myaddr, NULL, memaddr, len,
				      xfered_len);
    }
  else
    {
      *xfered_len = i;
      return TARGET_XFER_OK;
    }
}

/* FIXME: There would be some benefit to making the cache write-back and
   moving the writeback operation to a higher layer, as it could occur
   after a sequence of smaller writes have been completed (as when a stack
   frame is constructed for an inferior function call).  Note that only
   moving it up one level to target_xfer_memory[_partial]() is not
   sufficient since we want to coalesce memory transfers that are
   "logically" connected but not actually a single call to one of the
   memory transfer functions.  */

/* Just update any cache lines which are already present.  This is
   called by the target_xfer_partial machinery when writing raw
   memory.  */

void
dcache_update (DCACHE *dcache, enum target_xfer_status status,
	       CORE_ADDR memaddr, const gdb_byte *myaddr,
	       ULONGEST len)
{
  ULONGEST i;

  for (i = 0; i < len; i++)
    if (status == TARGET_XFER_OK)
      dcache_poke_byte (dcache, memaddr + i, myaddr + i);
    else
      {
	/* Discard the whole cache line so we don't have a partially
	   valid line.  */
	dcache_invalidate_line (dcache, memaddr + i);
      }
}

/* Print DCACHE line INDEX.  */

static void
dcache_print_line (DCACHE *dcache, int index)
{
  splay_tree_node n;
  struct dcache_block *db;
  int i, j;

  if (dcache == NULL)
    {
      printf_filtered (_("No data cache available.\n"));
      return;
    }

  n = splay_tree_min (dcache->tree);

  for (i = index; i > 0; --i)
    {
      if (!n)
	break;
      n = splay_tree_successor (dcache->tree, n->key);
    }

  if (!n)
    {
      printf_filtered (_("No such cache line exists.\n"));
      return;
    }
    
  db = (struct dcache_block *) n->value;

  printf_filtered (_("Line %d: address %s [%d hits]\n"),
		   index, paddress (target_gdbarch (), db->addr), db->refs);

  for (j = 0; j < dcache->line_size; j++)
    {
      printf_filtered ("%02x ", db->data[j]);

      /* Print a newline every 16 bytes (48 characters).  */
      if ((j % 16 == 15) && (j != dcache->line_size - 1))
	printf_filtered ("\n");
    }
  printf_filtered ("\n");
}

/* Parse EXP and show the info about DCACHE.  */

static void
dcache_info_1 (DCACHE *dcache, char *exp)
{
  splay_tree_node n;
  int i, refcount;

  if (exp)
    {
      char *linestart;

      i = strtol (exp, &linestart, 10);
      if (linestart == exp || i < 0)
	{
	  printf_filtered (_("Usage: info dcache [linenumber]\n"));
          return;
	}

      dcache_print_line (dcache, i);
      return;
    }

  printf_filtered (_("Dcache %u lines of %u bytes each.\n"),
		   dcache_size,
		   dcache ? (unsigned) dcache->line_size
		   : dcache_line_size);

  if (dcache == NULL || ptid_equal (dcache->ptid, null_ptid))
    {
      printf_filtered (_("No data cache available.\n"));
      return;
    }

  printf_filtered (_("Contains data for %s\n"),
		   target_pid_to_str (dcache->ptid));

  refcount = 0;

  n = splay_tree_min (dcache->tree);
  i = 0;

  while (n)
    {
      struct dcache_block *db = (struct dcache_block *) n->value;

      printf_filtered (_("Line %d: address %s [%d hits]\n"),
		       i, paddress (target_gdbarch (), db->addr), db->refs);
      i++;
      refcount += db->refs;

      n = splay_tree_successor (dcache->tree, n->key);
    }

  printf_filtered (_("Cache state: %d active lines, %d hits\n"), i, refcount);
}

static void
info_dcache_command (char *exp, int tty)
{
  dcache_info_1 (target_dcache_get (), exp);
}

static void
set_dcache_size (char *args, int from_tty,
		 struct cmd_list_element *c)
{
  if (dcache_size == 0)
    {
      dcache_size = DCACHE_DEFAULT_SIZE;
      error (_("Dcache size must be greater than 0."));
    }
  target_dcache_invalidate ();
}

static void
set_dcache_line_size (char *args, int from_tty,
		      struct cmd_list_element *c)
{
  if (dcache_line_size < 2
      || (dcache_line_size & (dcache_line_size - 1)) != 0)
    {
      unsigned d = dcache_line_size;
      dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
      error (_("Invalid dcache line size: %u (must be power of 2)."), d);
    }
  target_dcache_invalidate ();
}

static void
set_dcache_command (char *arg, int from_tty)
{
  printf_unfiltered (
     "\"set dcache\" must be followed by the name of a subcommand.\n");
  help_list (dcache_set_list, "set dcache ", all_commands, gdb_stdout);
}

static void
show_dcache_command (char *args, int from_tty)
{
  cmd_show_list (dcache_show_list, from_tty, "");
}

void
_initialize_dcache (void)
{
  add_setshow_boolean_cmd ("remotecache", class_support,
			   &dcache_enabled_p, _("\
Set cache use for remote targets."), _("\
Show cache use for remote targets."), _("\
This used to enable the data cache for remote targets.  The cache\n\
functionality is now controlled by the memory region system and the\n\
\"stack-cache\" flag; \"remotecache\" now does nothing and\n\
exists only for compatibility reasons."),
			   NULL,
			   show_dcache_enabled_p,
			   &setlist, &showlist);

  add_info ("dcache", info_dcache_command,
	    _("\
Print information on the dcache performance.\n\
With no arguments, this command prints the cache configuration and a\n\
summary of each line in the cache.  Use \"info dcache <lineno> to dump\"\n\
the contents of a given line."));

  add_prefix_cmd ("dcache", class_obscure, set_dcache_command, _("\
Use this command to set number of lines in dcache and line-size."),
		  &dcache_set_list, "set dcache ", /*allow_unknown*/0, &setlist);
  add_prefix_cmd ("dcache", class_obscure, show_dcache_command, _("\
Show dcachesettings."),
		  &dcache_show_list, "show dcache ", /*allow_unknown*/0, &showlist);

  add_setshow_zuinteger_cmd ("line-size", class_obscure,
			     &dcache_line_size, _("\
Set dcache line size in bytes (must be power of 2)."), _("\
Show dcache line size."),
			     NULL,
			     set_dcache_line_size,
			     NULL,
			     &dcache_set_list, &dcache_show_list);
  add_setshow_zuinteger_cmd ("size", class_obscure,
			     &dcache_size, _("\
Set number of dcache lines."), _("\
Show number of dcache lines."),
			     NULL,
			     set_dcache_size,
			     NULL,
			     &dcache_set_list, &dcache_show_list);
}
