daily update
[external/binutils.git] / gdb / dcache.c
index d6268f7..ae5a479 100644 (file)
@@ -1,12 +1,13 @@
-/* Caching code.
-   Copyright 1992, 1993, 1995, 1996, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+/* Caching code for GDB, the GNU debugger.
+
+   Copyright (C) 1992, 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2007,
+   2008, 2009 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
+   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,
@@ -15,9 +16,7 @@
    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.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "dcache.h"
    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
+   ENTRY_INVALID 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.
+   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
+   ENTRY_VALID means that the data is the same in the cache as it is in
    remote memory.
 
 
 #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 */
+#define ENTRY_INVALID 0 /* data at this byte is wrong */
+#define ENTRY_DIRTY   1 /* data at this byte needs to be written back */
+#define ENTRY_VALID   2 /* data at this byte is same as in memory */
 
+/* For cache state display by "info dcache".
+   The letters I,D,V map to
+   I = ENTRY_INVALID
+   D = ENTRY_DIRTY
+   V = ENTRY_VALID  */
+static const char state_chars[3] = { 'I', 'D', 'V' };
 
 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 */
+    gdb_byte 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 
@@ -161,10 +166,6 @@ struct dcache_struct
     struct dcache_block *the_cache;
   };
 
-static int dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
-
-static int dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr);
-
 static struct dcache_block *dcache_hit (DCACHE *dcache, CORE_ADDR addr);
 
 static int dcache_write_line (DCACHE *dcache, struct dcache_block *db);
@@ -181,6 +182,14 @@ void _initialize_dcache (void);
 
 static int dcache_enabled_p = 0;
 
+static void
+show_dcache_enabled_p (struct ui_file *file, int from_tty,
+                      struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Cache use for remote targets is %s.\n"), value);
+}
+
+
 DCACHE *last_cache;            /* Used by info dcache */
 
 
@@ -217,7 +226,7 @@ dcache_invalidate (DCACHE *dcache)
 static struct dcache_block *
 dcache_hit (DCACHE *dcache, CORE_ADDR addr)
 {
-  register struct dcache_block *db;
+  struct dcache_block *db;
 
   /* Search all cache blocks for one that is at this address.  */
   db = dcache->valid_head;
@@ -239,10 +248,10 @@ dcache_hit (DCACHE *dcache, CORE_ADDR addr)
    be written is. */
 
 static int
-dcache_write_line (DCACHE *dcache, register struct dcache_block *db)
+dcache_write_line (DCACHE *dcache, struct dcache_block *db)
 {
   CORE_ADDR memaddr;
-  char *myaddr;
+  gdb_byte *myaddr;
   int len;
   int res;
   int reg_len;
@@ -278,34 +287,35 @@ dcache_write_line (DCACHE *dcache, register struct dcache_block *db)
       while (reg_len > 0)
        {
          s = XFORM(memaddr);
-         do {
+         while (reg_len > 0) {
            if (db->state[s] == ENTRY_DIRTY)
              break;
            s++;
            reg_len--;
-         } while (reg_len > 0);
+
+           memaddr++;
+           myaddr++;
+           len--;
+         }
 
          e = s;
-         do {
+         while (reg_len > 0) {
            if (db->state[e] != ENTRY_DIRTY)
              break;
            e++;
            reg_len--;
-         } while (reg_len > 0);
+         }
 
          dirty_len = e - s;
-         while (dirty_len > 0)
-           {
-             res = do_xfer_memory(memaddr, myaddr, dirty_len, 1,
-                                  &region->attrib);
-             if (res <= 0)
-               return 0;
-
-             memset (&db->state[XFORM(memaddr)], ENTRY_OK, res);
-             memaddr   += res;
-             myaddr    += res;
-             dirty_len -= res;
-           }
+         res = target_write (&current_target, TARGET_OBJECT_RAW_MEMORY,
+                             NULL, myaddr, memaddr, dirty_len);
+         if (res < dirty_len)
+           return 0;
+
+         memset (&db->state[XFORM(memaddr)], ENTRY_VALID, res);
+         memaddr += res;
+         myaddr += res;
+         len -= res;
        }
     }
 
@@ -318,7 +328,7 @@ static int
 dcache_read_line (DCACHE *dcache, struct dcache_block *db)
 {
   CORE_ADDR memaddr;
-  char *myaddr;
+  gdb_byte *myaddr;
   int len;
   int res;
   int reg_len;
@@ -352,21 +362,17 @@ dcache_read_line (DCACHE *dcache, struct dcache_block *db)
          continue;
        }
       
-      while (reg_len > 0)
-       {
-         res = do_xfer_memory (memaddr, myaddr, reg_len, 0,
-                               &region->attrib);
-         if (res <= 0)
-           return 0;
+      res = target_read (&current_target, TARGET_OBJECT_RAW_MEMORY,
+                        NULL, myaddr, memaddr, reg_len);
+      if (res < reg_len)
+       return 0;
 
-         memaddr += res;
-         myaddr  += res;
-         len     -= res;
-         reg_len -= res;
-       }
+      memaddr += res;
+      myaddr += res;
+      len -= res;
     }
 
-  memset (db->state, ENTRY_OK, sizeof (db->data));
+  memset (db->state, ENTRY_VALID, sizeof (db->data));
   db->anydirty = 0;
   
   return 1;
@@ -378,7 +384,7 @@ dcache_read_line (DCACHE *dcache, struct dcache_block *db)
 static struct dcache_block *
 dcache_alloc (DCACHE *dcache, CORE_ADDR addr)
 {
-  register struct dcache_block *db;
+  struct dcache_block *db;
 
   /* Take something from the free list */
   db = dcache->free_head;
@@ -400,7 +406,7 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR addr)
   db->addr = MASK(addr);
   db->refs = 0;
   db->anydirty = 0;
-  memset (db->state, ENTRY_BAD, sizeof (db->data));
+  memset (db->state, ENTRY_INVALID, sizeof (db->data));
 
   /* append this line to end of valid list */
   if (!dcache->valid_head)
@@ -437,9 +443,9 @@ dcache_writeback (DCACHE *dcache)
    Returns 0 on error. */
 
 static int
-dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
+dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr)
 {
-  register struct dcache_block *db = dcache_hit (dcache, addr);
+  struct dcache_block *db = dcache_hit (dcache, addr);
 
   if (!db)
     {
@@ -448,7 +454,7 @@ dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
        return 0;
     }
   
-  if (db->state[XFORM (addr)] == ENTRY_BAD)
+  if (db->state[XFORM (addr)] == ENTRY_INVALID)
     {
       if (!dcache_read_line(dcache, db))
          return 0;
@@ -464,9 +470,9 @@ dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
  */
 
 static int
-dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, char *ptr)
+dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr)
 {
-  register struct dcache_block *db = dcache_hit (dcache, addr);
+  struct dcache_block *db = dcache_hit (dcache, addr);
 
   if (!db)
     {
@@ -519,11 +525,11 @@ dcache_free (DCACHE *dcache)
    This routine is indended to be called by remote_xfer_ functions. */
 
 int
-dcache_xfer_memory (DCACHE *dcache, CORE_ADDR memaddr, char *myaddr, int len,
-                   int should_write)
+dcache_xfer_memory (DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr,
+                   int len, int should_write)
 {
   int i;
-  int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, char *ptr);
+  int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr);
   xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
 
   for (i = 0; i < len; i++)
@@ -552,25 +558,25 @@ dcache_info (char *exp, int tty)
 {
   struct dcache_block *p;
 
-  printf_filtered ("Dcache line width %d, depth %d\n",
+  printf_filtered (_("Dcache line width %d, depth %d\n"),
                   LINE_SIZE, DCACHE_SIZE);
 
   if (last_cache)
     {
-      printf_filtered ("Cache state:\n");
+      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",
+         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");
+         printf_filtered (("\n"));
 
          for (j = 0; j < LINE_SIZE; j++)
-           printf_filtered ("%2x", p->state[j]);
+           printf_filtered (" %c", state_chars[p->state[j]]);
          printf_filtered ("\n");
        }
     }
@@ -579,20 +585,24 @@ dcache_info (char *exp, int tty)
 void
 _initialize_dcache (void)
 {
-  add_show_from_set
-    (add_set_cmd ("remotecache", class_support, var_boolean,
-                 (char *) &dcache_enabled_p,
-                 "\
-Set cache use for remote targets.\n\
+  add_setshow_boolean_cmd ("remotecache", class_support,
+                          &dcache_enabled_p, _("\
+Set cache use for remote targets."), _("\
+Show cache use for remote targets."), _("\
 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);
+volatile registers are in use.  By default, this option is off."),
+                          NULL,
+                          show_dcache_enabled_p,
+                          &setlist, &showlist);
 
   add_info ("dcache", dcache_info,
-           "Print information on the dcache performance.");
-
+           _("\
+Print information on the dcache performance.\n\
+The state of each cached byte is represented by a letter:\n\
+  I = invalid\n\
+  D = dirty\n\
+  V = valid"));
 }