1130803Smarcel/* Caching code for GDB, the GNU debugger.
219370Spst
3130803Smarcel   Copyright 1992, 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2003 Free
4130803Smarcel   Software Foundation, Inc.
5130803Smarcel
619370Spst   This file is part of GDB.
719370Spst
819370Spst   This program is free software; you can redistribute it and/or modify
919370Spst   it under the terms of the GNU General Public License as published by
1019370Spst   the Free Software Foundation; either version 2 of the License, or
1119370Spst   (at your option) any later version.
1219370Spst
1319370Spst   This program is distributed in the hope that it will be useful,
1419370Spst   but WITHOUT ANY WARRANTY; without even the implied warranty of
1519370Spst   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1619370Spst   GNU General Public License for more details.
1719370Spst
1819370Spst   You should have received a copy of the GNU General Public License
1919370Spst   along with this program; if not, write to the Free Software
2098944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198944Sobrien   Boston, MA 02111-1307, USA.  */
2219370Spst
2319370Spst#include "defs.h"
2419370Spst#include "dcache.h"
2519370Spst#include "gdbcmd.h"
2619370Spst#include "gdb_string.h"
2746283Sdfr#include "gdbcore.h"
2898944Sobrien#include "target.h"
2919370Spst
3098944Sobrien/* The data cache could lead to incorrect results because it doesn't
3198944Sobrien   know about volatile variables, thus making it impossible to debug
3298944Sobrien   functions which use memory mapped I/O devices.  Set the nocache
3398944Sobrien   memory region attribute in those cases.
3419370Spst
3519370Spst   In general the dcache speeds up performance, some speed improvement
3619370Spst   comes from the actual caching mechanism, but the major gain is in
3719370Spst   the reduction of the remote protocol overhead; instead of reading
3819370Spst   or writing a large area of memory in 4 byte requests, the cache
3919370Spst   bundles up the requests into 32 byte (actually LINE_SIZE) chunks.
4019370Spst   Reducing the overhead to an eighth of what it was.  This is very
4119370Spst   obvious when displaying a large amount of data,
4219370Spst
4319370Spst   eg, x/200x 0
4419370Spst
4519370Spst   caching     |   no    yes
4619370Spst   ----------------------------
4719370Spst   first time  |   4 sec  2 sec improvement due to chunking
4819370Spst   second time |   4 sec  0 sec improvement due to caching
4919370Spst
5019370Spst   The cache structure is unusual, we keep a number of cache blocks
5119370Spst   (DCACHE_SIZE) and each one caches a LINE_SIZEed area of memory.
5219370Spst   Within each line we remember the address of the line (always a
5319370Spst   multiple of the LINE_SIZE) and a vector of bytes over the range.
5419370Spst   There's another vector which contains the state of the bytes.
5519370Spst
5619370Spst   ENTRY_BAD means that the byte is just plain wrong, and has no
5719370Spst   correspondence with anything else (as it would when the cache is
5819370Spst   turned on, but nothing has been done to it.
5919370Spst
6019370Spst   ENTRY_DIRTY means that the byte has some data in it which should be
6119370Spst   written out to the remote target one day, but contains correct
6298944Sobrien   data.
6319370Spst
6498944Sobrien   ENTRY_OK means that the data is the same in the cache as it is in
6598944Sobrien   remote memory.
6619370Spst
6798944Sobrien
6819370Spst   The ENTRY_DIRTY state is necessary because GDB likes to write large
6919370Spst   lumps of memory in small bits.  If the caching mechanism didn't
7019370Spst   maintain the DIRTY information, then something like a two byte
7119370Spst   write would mean that the entire cache line would have to be read,
7219370Spst   the two bytes modified and then written out again.  The alternative
7319370Spst   would be to not read in the cache line in the first place, and just
7419370Spst   write the two bytes directly into target memory.  The trouble with
7519370Spst   that is that it really nails performance, because of the remote
7619370Spst   protocol overhead.  This way, all those little writes are bundled
7719370Spst   up into an entire cache line write in one go, without having to
7819370Spst   read the cache line in the first place.
7998944Sobrien */
8019370Spst
8198944Sobrien/* NOTE: Interaction of dcache and memory region attributes
8219370Spst
8398944Sobrien   As there is no requirement that memory region attributes be aligned
8498944Sobrien   to or be a multiple of the dcache page size, dcache_read_line() and
8598944Sobrien   dcache_write_line() must break up the page by memory region.  If a
8698944Sobrien   chunk does not have the cache attribute set, an invalid memory type
8798944Sobrien   is set, etc., then the chunk is skipped.  Those chunks are handled
8898944Sobrien   in target_xfer_memory() (or target_xfer_memory_partial()).
8919370Spst
9098944Sobrien   This doesn't occur very often.  The most common occurance is when
9198944Sobrien   the last bit of the .text segment and the first bit of the .data
9298944Sobrien   segment fall within the same dcache page with a ro/cacheable memory
9398944Sobrien   region defined for the .text segment and a rw/non-cacheable memory
9498944Sobrien   region defined for the .data segment. */
9519370Spst
9619370Spst/* This value regulates the number of cache blocks stored.
9719370Spst   Smaller values reduce the time spent searching for a cache
9819370Spst   line, and reduce memory requirements, but increase the risk
9919370Spst   of a line not being in memory */
10019370Spst
10198944Sobrien#define DCACHE_SIZE 64
10219370Spst
10319370Spst/* This value regulates the size of a cache line.  Smaller values
10419370Spst   reduce the time taken to read a single byte, but reduce overall
10519370Spst   throughput.  */
10619370Spst
10798944Sobrien#define LINE_SIZE_POWER (5)
10819370Spst#define LINE_SIZE (1 << LINE_SIZE_POWER)
10919370Spst
11019370Spst/* Each cache block holds LINE_SIZE bytes of data
11119370Spst   starting at a multiple-of-LINE_SIZE address.  */
11219370Spst
11398944Sobrien#define LINE_SIZE_MASK  ((LINE_SIZE - 1))
11419370Spst#define XFORM(x) 	((x) & LINE_SIZE_MASK)
11519370Spst#define MASK(x)         ((x) & ~LINE_SIZE_MASK)
11619370Spst
11719370Spst
11898944Sobrien#define ENTRY_BAD   0		/* data at this byte is wrong */
11998944Sobrien#define ENTRY_DIRTY 1		/* data at this byte needs to be written back */
12098944Sobrien#define ENTRY_OK    2		/* data at this byte is same as in memory */
12119370Spst
12219370Spst
12319370Spststruct dcache_block
12498944Sobrien  {
12598944Sobrien    struct dcache_block *p;	/* next in list */
12698944Sobrien    CORE_ADDR addr;		/* Address for which data is recorded.  */
12798944Sobrien    char data[LINE_SIZE];	/* bytes at given address */
12898944Sobrien    unsigned char state[LINE_SIZE];	/* what state the data is in */
12919370Spst
13098944Sobrien    /* whether anything in state is dirty - used to speed up the
13198944Sobrien       dirty scan. */
13298944Sobrien    int anydirty;
13319370Spst
13498944Sobrien    int refs;
13598944Sobrien  };
13619370Spst
13719370Spst
13898944Sobrien/* FIXME: dcache_struct used to have a cache_has_stuff field that was
13998944Sobrien   used to record whether the cache had been accessed.  This was used
14098944Sobrien   to invalidate the cache whenever caching was (re-)enabled (if the
14198944Sobrien   cache was disabled and later re-enabled, it could contain stale
14298944Sobrien   data).  This was not needed because the cache is write through and
14398944Sobrien   the code that enables, disables, and deletes memory region all
14498944Sobrien   invalidate the cache.
14519370Spst
14698944Sobrien   This is overkill, since it also invalidates cache lines from
14798944Sobrien   unrelated regions.  One way this could be addressed by adding a
14898944Sobrien   new function that takes an address and a length and invalidates
14998944Sobrien   only those cache lines that match. */
15019370Spst
15198944Sobrienstruct dcache_struct
15298944Sobrien  {
15398944Sobrien    /* free list */
15498944Sobrien    struct dcache_block *free_head;
15598944Sobrien    struct dcache_block *free_tail;
15619370Spst
15798944Sobrien    /* in use list */
15898944Sobrien    struct dcache_block *valid_head;
15998944Sobrien    struct dcache_block *valid_tail;
16019370Spst
16198944Sobrien    /* The cache itself. */
16298944Sobrien    struct dcache_block *the_cache;
16398944Sobrien  };
16419370Spst
16598944Sobrienstatic int dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
16619370Spst
16798944Sobrienstatic int dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
16846283Sdfr
16998944Sobrienstatic struct dcache_block *dcache_hit (DCACHE *dcache, CORE_ADDR addr);
17046283Sdfr
17198944Sobrienstatic int dcache_write_line (DCACHE *dcache, struct dcache_block *db);
17246283Sdfr
17398944Sobrienstatic int dcache_read_line (DCACHE *dcache, struct dcache_block *db);
17446283Sdfr
17598944Sobrienstatic struct dcache_block *dcache_alloc (DCACHE *dcache, CORE_ADDR addr);
17646283Sdfr
17798944Sobrienstatic int dcache_writeback (DCACHE *dcache);
17846283Sdfr
17998944Sobrienstatic void dcache_info (char *exp, int tty);
18046283Sdfr
18198944Sobrienvoid _initialize_dcache (void);
18246283Sdfr
18398944Sobrienstatic int dcache_enabled_p = 0;
18419370Spst
18598944SobrienDCACHE *last_cache;		/* Used by info dcache */
18619370Spst
18719370Spst
18819370Spst/* Free all the data cache blocks, thus discarding all cached data.  */
18919370Spst
19019370Spstvoid
19198944Sobriendcache_invalidate (DCACHE *dcache)
19219370Spst{
19319370Spst  int i;
19419370Spst  dcache->valid_head = 0;
19519370Spst  dcache->valid_tail = 0;
19619370Spst
19719370Spst  dcache->free_head = 0;
19819370Spst  dcache->free_tail = 0;
19919370Spst
20019370Spst  for (i = 0; i < DCACHE_SIZE; i++)
20119370Spst    {
20219370Spst      struct dcache_block *db = dcache->the_cache + i;
20319370Spst
20419370Spst      if (!dcache->free_head)
20519370Spst	dcache->free_head = db;
20619370Spst      else
20719370Spst	dcache->free_tail->p = db;
20819370Spst      dcache->free_tail = db;
20919370Spst      db->p = 0;
21019370Spst    }
21119370Spst
21219370Spst  return;
21319370Spst}
21419370Spst
21519370Spst/* If addr is present in the dcache, return the address of the block
21619370Spst   containing it. */
21746283Sdfr
21846283Sdfrstatic struct dcache_block *
21998944Sobriendcache_hit (DCACHE *dcache, CORE_ADDR addr)
22019370Spst{
221130803Smarcel  struct dcache_block *db;
22219370Spst
22319370Spst  /* Search all cache blocks for one that is at this address.  */
22419370Spst  db = dcache->valid_head;
22519370Spst
22619370Spst  while (db)
22719370Spst    {
22898944Sobrien      if (MASK (addr) == db->addr)
22919370Spst	{
23019370Spst	  db->refs++;
23119370Spst	  return db;
23219370Spst	}
23319370Spst      db = db->p;
23419370Spst    }
23519370Spst
23619370Spst  return NULL;
23719370Spst}
23819370Spst
23919370Spst/* Make sure that anything in this line which needs to
24019370Spst   be written is. */
24119370Spst
24219370Spststatic int
243130803Smarceldcache_write_line (DCACHE *dcache, struct dcache_block *db)
24419370Spst{
24598944Sobrien  CORE_ADDR memaddr;
24698944Sobrien  char *myaddr;
24798944Sobrien  int len;
24898944Sobrien  int res;
24998944Sobrien  int reg_len;
25098944Sobrien  struct mem_region *region;
25198944Sobrien
25298944Sobrien  if (!db->anydirty)
25398944Sobrien    return 1;
25498944Sobrien
25598944Sobrien  len = LINE_SIZE;
25698944Sobrien  memaddr = db->addr;
25798944Sobrien  myaddr  = db->data;
25898944Sobrien
25998944Sobrien  while (len > 0)
26019370Spst    {
26198944Sobrien      int s;
26298944Sobrien      int e;
26398944Sobrien      int dirty_len;
26498944Sobrien
26598944Sobrien      region = lookup_mem_region(memaddr);
26698944Sobrien      if (memaddr + len < region->hi)
26798944Sobrien	reg_len = len;
26898944Sobrien      else
26998944Sobrien	reg_len = region->hi - memaddr;
27098944Sobrien
27198944Sobrien      if (!region->attrib.cache || region->attrib.mode == MEM_RO)
27219370Spst	{
27398944Sobrien	  memaddr += reg_len;
27498944Sobrien	  myaddr  += reg_len;
27598944Sobrien	  len     -= reg_len;
27698944Sobrien	  continue;
27798944Sobrien	}
27898944Sobrien
27998944Sobrien      while (reg_len > 0)
28098944Sobrien	{
28198944Sobrien	  s = XFORM(memaddr);
28298944Sobrien	  while (reg_len > 0) {
28398944Sobrien	    if (db->state[s] == ENTRY_DIRTY)
28498944Sobrien	      break;
28598944Sobrien	    s++;
28698944Sobrien	    reg_len--;
28798944Sobrien
28898944Sobrien	    memaddr++;
28998944Sobrien	    myaddr++;
29098944Sobrien	    len--;
29198944Sobrien	  }
29298944Sobrien
29398944Sobrien	  e = s;
29498944Sobrien	  while (reg_len > 0) {
29598944Sobrien	    if (db->state[e] != ENTRY_DIRTY)
29698944Sobrien	      break;
29798944Sobrien	    e++;
29898944Sobrien	    reg_len--;
29998944Sobrien	  }
30098944Sobrien
30198944Sobrien	  dirty_len = e - s;
30298944Sobrien	  while (dirty_len > 0)
30319370Spst	    {
30498944Sobrien	      res = do_xfer_memory(memaddr, myaddr, dirty_len, 1,
30598944Sobrien				   &region->attrib);
30698944Sobrien	      if (res <= 0)
30798944Sobrien		return 0;
30898944Sobrien
30998944Sobrien	      memset (&db->state[XFORM(memaddr)], ENTRY_OK, res);
31098944Sobrien	      memaddr   += res;
31198944Sobrien	      myaddr    += res;
31298944Sobrien	      len       -= res;
31398944Sobrien	      dirty_len -= res;
31419370Spst	    }
31519370Spst	}
31619370Spst    }
31798944Sobrien
31898944Sobrien  db->anydirty = 0;
31919370Spst  return 1;
32019370Spst}
32119370Spst
32298944Sobrien/* Read cache line */
32398944Sobrienstatic int
32498944Sobriendcache_read_line (DCACHE *dcache, struct dcache_block *db)
32598944Sobrien{
32698944Sobrien  CORE_ADDR memaddr;
32798944Sobrien  char *myaddr;
32898944Sobrien  int len;
32998944Sobrien  int res;
33098944Sobrien  int reg_len;
33198944Sobrien  struct mem_region *region;
33219370Spst
33398944Sobrien  /* If there are any dirty bytes in the line, it must be written
33498944Sobrien     before a new line can be read */
33598944Sobrien  if (db->anydirty)
33698944Sobrien    {
33798944Sobrien      if (!dcache_write_line (dcache, db))
33898944Sobrien	return 0;
33998944Sobrien    }
34098944Sobrien
34198944Sobrien  len = LINE_SIZE;
34298944Sobrien  memaddr = db->addr;
34398944Sobrien  myaddr  = db->data;
34498944Sobrien
34598944Sobrien  while (len > 0)
34698944Sobrien    {
34798944Sobrien      region = lookup_mem_region(memaddr);
34898944Sobrien      if (memaddr + len < region->hi)
34998944Sobrien	reg_len = len;
35098944Sobrien      else
35198944Sobrien	reg_len = region->hi - memaddr;
35298944Sobrien
35398944Sobrien      if (!region->attrib.cache || region->attrib.mode == MEM_WO)
35498944Sobrien	{
35598944Sobrien	  memaddr += reg_len;
35698944Sobrien	  myaddr  += reg_len;
35798944Sobrien	  len     -= reg_len;
35898944Sobrien	  continue;
35998944Sobrien	}
36098944Sobrien
36198944Sobrien      while (reg_len > 0)
36298944Sobrien	{
36398944Sobrien	  res = do_xfer_memory (memaddr, myaddr, reg_len, 0,
36498944Sobrien				&region->attrib);
36598944Sobrien	  if (res <= 0)
36698944Sobrien	    return 0;
36798944Sobrien
36898944Sobrien	  memaddr += res;
36998944Sobrien	  myaddr  += res;
37098944Sobrien	  len     -= res;
37198944Sobrien	  reg_len -= res;
37298944Sobrien	}
37398944Sobrien    }
37498944Sobrien
37598944Sobrien  memset (db->state, ENTRY_OK, sizeof (db->data));
37698944Sobrien  db->anydirty = 0;
37798944Sobrien
37898944Sobrien  return 1;
37998944Sobrien}
38098944Sobrien
38119370Spst/* Get a free cache block, put or keep it on the valid list,
38298944Sobrien   and return its address.  */
38346283Sdfr
38446283Sdfrstatic struct dcache_block *
38598944Sobriendcache_alloc (DCACHE *dcache, CORE_ADDR addr)
38619370Spst{
387130803Smarcel  struct dcache_block *db;
38819370Spst
38919370Spst  /* Take something from the free list */
39019370Spst  db = dcache->free_head;
39119370Spst  if (db)
39219370Spst    {
39319370Spst      dcache->free_head = db->p;
39419370Spst    }
39519370Spst  else
39619370Spst    {
39719370Spst      /* Nothing left on free list, so grab one from the valid list */
39819370Spst      db = dcache->valid_head;
39998944Sobrien
40098944Sobrien      if (!dcache_write_line (dcache, db))
40198944Sobrien	return NULL;
40298944Sobrien
40319370Spst      dcache->valid_head = db->p;
40419370Spst    }
40519370Spst
40698944Sobrien  db->addr = MASK(addr);
40798944Sobrien  db->refs = 0;
40898944Sobrien  db->anydirty = 0;
40998944Sobrien  memset (db->state, ENTRY_BAD, sizeof (db->data));
41098944Sobrien
41119370Spst  /* append this line to end of valid list */
41219370Spst  if (!dcache->valid_head)
41319370Spst    dcache->valid_head = db;
41419370Spst  else
41519370Spst    dcache->valid_tail->p = db;
41619370Spst  dcache->valid_tail = db;
41719370Spst  db->p = 0;
41819370Spst
41919370Spst  return db;
42019370Spst}
42119370Spst
42298944Sobrien/* Writeback any dirty lines. */
42346283Sdfrstatic int
42498944Sobriendcache_writeback (DCACHE *dcache)
42519370Spst{
42619370Spst  struct dcache_block *db;
42719370Spst
42819370Spst  db = dcache->valid_head;
42919370Spst
43019370Spst  while (db)
43119370Spst    {
43219370Spst      if (!dcache_write_line (dcache, db))
43319370Spst	return 0;
43419370Spst      db = db->p;
43519370Spst    }
43619370Spst  return 1;
43719370Spst}
43819370Spst
43919370Spst
44098944Sobrien/* Using the data cache DCACHE return the contents of the byte at
44198944Sobrien   address ADDR in the remote machine.
44298944Sobrien
44398944Sobrien   Returns 0 on error. */
44498944Sobrien
44598944Sobrienstatic int
44698944Sobriendcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
44719370Spst{
448130803Smarcel  struct dcache_block *db = dcache_hit (dcache, addr);
44946283Sdfr
45098944Sobrien  if (!db)
45198944Sobrien    {
45298944Sobrien      db = dcache_alloc (dcache, addr);
45398944Sobrien      if (!db)
45498944Sobrien	return 0;
45598944Sobrien    }
45698944Sobrien
45798944Sobrien  if (db->state[XFORM (addr)] == ENTRY_BAD)
45898944Sobrien    {
45998944Sobrien      if (!dcache_read_line(dcache, db))
46098944Sobrien         return 0;
46198944Sobrien    }
46246283Sdfr
46398944Sobrien  *ptr = db->data[XFORM (addr)];
46498944Sobrien  return 1;
46519370Spst}
46619370Spst
46719370Spst
46819370Spst/* Write the byte at PTR into ADDR in the data cache.
46919370Spst   Return zero on write error.
47019370Spst */
47119370Spst
47246283Sdfrstatic int
47398944Sobriendcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
47419370Spst{
475130803Smarcel  struct dcache_block *db = dcache_hit (dcache, addr);
47619370Spst
47719370Spst  if (!db)
47819370Spst    {
47998944Sobrien      db = dcache_alloc (dcache, addr);
48098944Sobrien      if (!db)
48198944Sobrien	return 0;
48219370Spst    }
48319370Spst
48419370Spst  db->data[XFORM (addr)] = *ptr;
48519370Spst  db->state[XFORM (addr)] = ENTRY_DIRTY;
48619370Spst  db->anydirty = 1;
48719370Spst  return 1;
48819370Spst}
48919370Spst
49019370Spst/* Initialize the data cache.  */
49119370SpstDCACHE *
49298944Sobriendcache_init (void)
49319370Spst{
49419370Spst  int csize = sizeof (struct dcache_block) * DCACHE_SIZE;
49519370Spst  DCACHE *dcache;
49619370Spst
49719370Spst  dcache = (DCACHE *) xmalloc (sizeof (*dcache));
49819370Spst
49919370Spst  dcache->the_cache = (struct dcache_block *) xmalloc (csize);
50019370Spst  memset (dcache->the_cache, 0, csize);
50119370Spst
50298944Sobrien  dcache_invalidate (dcache);
50319370Spst
50419370Spst  last_cache = dcache;
50519370Spst  return dcache;
50619370Spst}
50719370Spst
50898944Sobrien/* Free a data cache */
50998944Sobrienvoid
51098944Sobriendcache_free (DCACHE *dcache)
51198944Sobrien{
51298944Sobrien  if (last_cache == dcache)
51398944Sobrien    last_cache = NULL;
51498944Sobrien
51598944Sobrien  xfree (dcache->the_cache);
51698944Sobrien  xfree (dcache);
51798944Sobrien}
51898944Sobrien
51919370Spst/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
52019370Spst   to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
52119370Spst   nonzero.
52219370Spst
52319370Spst   Returns length of data written or read; 0 for error.
52419370Spst
52519370Spst   This routine is indended to be called by remote_xfer_ functions. */
52619370Spst
52719370Spstint
52898944Sobriendcache_xfer_memory (DCACHE *dcache, CORE_ADDR memaddr, char *myaddr, int len,
52998944Sobrien		    int should_write)
53019370Spst{
53119370Spst  int i;
53298944Sobrien  int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, char *ptr);
53398944Sobrien  xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
53419370Spst
53598944Sobrien  for (i = 0; i < len; i++)
53619370Spst    {
53798944Sobrien      if (!xfunc (dcache, memaddr + i, myaddr + i))
53898944Sobrien	return 0;
53919370Spst    }
54019370Spst
54198944Sobrien  /* FIXME: There may be some benefit from moving the cache writeback
54298944Sobrien     to a higher layer, as it could occur after a sequence of smaller
54398944Sobrien     writes have been completed (as when a stack frame is constructed
54498944Sobrien     for an inferior function call).  Note that only moving it up one
54598944Sobrien     level to target_xfer_memory() (also target_xfer_memory_partial())
54698944Sobrien     is not sufficent, since we want to coalesce memory transfers that
54798944Sobrien     are "logically" connected but not actually a single call to one
54898944Sobrien     of the memory transfer functions. */
54919370Spst
55098944Sobrien  if (should_write)
55198944Sobrien    dcache_writeback (dcache);
55298944Sobrien
55319370Spst  return len;
55419370Spst}
55519370Spst
55698944Sobrienstatic void
55798944Sobriendcache_info (char *exp, int tty)
55819370Spst{
55919370Spst  struct dcache_block *p;
56019370Spst
56198944Sobrien  printf_filtered ("Dcache line width %d, depth %d\n",
56219370Spst		   LINE_SIZE, DCACHE_SIZE);
56319370Spst
56498944Sobrien  if (last_cache)
56519370Spst    {
56698944Sobrien      printf_filtered ("Cache state:\n");
56719370Spst
56898944Sobrien      for (p = last_cache->valid_head; p; p = p->p)
56998944Sobrien	{
57098944Sobrien	  int j;
57198944Sobrien	  printf_filtered ("Line at %s, referenced %d times\n",
57298944Sobrien			   paddr (p->addr), p->refs);
57319370Spst
57498944Sobrien	  for (j = 0; j < LINE_SIZE; j++)
57598944Sobrien	    printf_filtered ("%02x", p->data[j] & 0xFF);
57698944Sobrien	  printf_filtered ("\n");
57798944Sobrien
57898944Sobrien	  for (j = 0; j < LINE_SIZE; j++)
57998944Sobrien	    printf_filtered ("%2x", p->state[j]);
58098944Sobrien	  printf_filtered ("\n");
58198944Sobrien	}
58219370Spst    }
58319370Spst}
58419370Spst
58519370Spstvoid
58698944Sobrien_initialize_dcache (void)
58719370Spst{
58819370Spst  add_show_from_set
58919370Spst    (add_set_cmd ("remotecache", class_support, var_boolean,
59098944Sobrien		  (char *) &dcache_enabled_p,
59119370Spst		  "\
59219370SpstSet cache use for remote targets.\n\
59319370SpstWhen on, use data caching for remote targets.  For many remote targets\n\
59419370Spstthis option can offer better throughput for reading target memory.\n\
59519370SpstUnfortunately, gdb does not currently know anything about volatile\n\
59619370Spstregisters and thus data caching will produce incorrect results with\n\
59798944Sobrienvolatile registers are in use.  By default, this option is off.",
59819370Spst		  &setlist),
59919370Spst     &showlist);
60019370Spst
60119370Spst  add_info ("dcache", dcache_info,
60219370Spst	    "Print information on the dcache performance.");
60319370Spst
60419370Spst}
605