* exec.c (xfer_memory): Add attrib argument.
authorJ.T. Conklin <jtc@acorntoolworks.com>
Tue, 23 Jan 2001 22:48:56 +0000 (22:48 +0000)
committerJ.T. Conklin <jtc@acorntoolworks.com>
Tue, 23 Jan 2001 22:48:56 +0000 (22:48 +0000)
* infptrace.c (child_xfer_memory): Likewise.
* monitor.c (monitor_xfer_memory): Likewise.
* remote-adapt.c (adapt_xfer_inferior_memory): Likewise.
* remote-array.c (array_xfer_memory): Likewise.
* remote-bug.c (bug_xfer_memory): Likewise.
* remote-e7000.c (e7000_xfer_inferior_memory): Likewise.
* remote-eb.c (eb_xfer_inferior_memory): Likewise.
* remote-es.c (es1800_xfer_inferior_memory): Likewise.
* remote-mips.c (mips_xfer_memory): Likewise.
* remote-mm.c (mm_xfer_inferior_memory): Likewise.
* remote-nindy.c (nindy_xfer_inferior_memory): Likewise.
* remote-os9k.c (rombug_xfer_inferior_memory): Likewise.
* remote-rdi.c (arm_rdi_xfer_memory): Likewise.
* remote-rdp.c (remote_rdp_xfer_inferior_memory): Likewise.
* remote-sds.c (sds_xfer_memory): Likewise.
* remote-sim.c (gdbsim_xfer_inferior_memory): Likewise.
* remote-st.c (st2000_xfer_inferior_memory): Likewise.
* remote-udi.c (udi_xfer_inferior_memory): Likewise.
* remote-vx.c (vx_xfer_memory): Likewise.
* remote.c (remote_xfer_memory): Likewise.
* target.c (debug_to_xfer_memory, do_xfer_memory): Likewise.
* target.h (child_xfer_memory, do_xfer_memory, xfer_memory): Likewise.

* target.h (#include "memattr.h"): Added.
(target_ops.to_xfer_memory): Add attrib argument.

* wince.c (_initialize_inftarg): Removed call to set_dcache_state.
* dcache.h (set_dcache_state): Removed declaration.
* dcache.c (set_dcache_state): Removed definition

* dcache.c: Update module comment, as dcache is now enabled and
disabled with memory region attributes instead of by the global
variable "remotecache".  Add comment describing the interaction
between dcache and memory region attributes.
(dcache_xfer_memory): Add comment describing benefits of moving
cache writeback to a higher level.
(dcache_struct): Removed cache_has_stuff field.  This was used to
record whether the cache had been accessed in order to invalidate
it when it was disabled.  However, this is not needed because the
cache is write through and the code that enables, disables, and
deletes memory regions invalidate the cache.  Add comment which
suggests that we could be more selective and only invalidate those
cache lines containing data from those memory regions.
(dcache_invalidate): Updated.
(dcache_xfer_memory): Updated.

(dcache_alloc): Don't abort() if dcache_enabled_p is clear.
(dcache_xfer_memory): Removed code that called do_xfer_memory() to
perform a uncached transfer if dcache_enabled_p was clear.  This
function is now only called if caching is enabled for the memory
region.
(dcache_info): Always print cache info.

* target.c (do_xfer_memory): Add attrib argument.
(target_xfer_memory, target_xfer_memory_partial): Break transfer
into chunks defined by memory regions, pass region attributes to
do_xfer_memory().
* dcache.c (dcache_read_line, dcache_write_line): Likewise.

* Makefile.in (SFILES): Add memattr.c.
(COMMON_OBS): Add memattr.o.
(dcache.o): Add target.h to dependencies.
* memattr.c: New file.
* memattr.h: Likewise.

32 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/dcache.c
gdb/dcache.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/exec.c
gdb/infptrace.c
gdb/memattr.c [new file with mode: 0644]
gdb/memattr.h [new file with mode: 0644]
gdb/monitor.c
gdb/remote-adapt.c
gdb/remote-array.c
gdb/remote-bug.c
gdb/remote-e7000.c
gdb/remote-eb.c
gdb/remote-es.c
gdb/remote-mips.c
gdb/remote-mm.c
gdb/remote-nindy.c
gdb/remote-os9k.c
gdb/remote-rdi.c
gdb/remote-rdp.c
gdb/remote-sds.c
gdb/remote-sim.c
gdb/remote-st.c
gdb/remote-udi.c
gdb/remote-vx.c
gdb/remote.c
gdb/target.c
gdb/target.h
gdb/wince.c

index dc1e3e0d3dc2d53ff76c400b16dccd1b24232e59..29f8da47d7a425bf6f39a873ab695219f0be8b75 100644 (file)
@@ -1,5 +1,71 @@
 2001-01-23  J.T. Conklin  <jtc@redback.com>
+
+       * exec.c (xfer_memory): Add attrib argument.
+       * infptrace.c (child_xfer_memory): Likewise.
+       * monitor.c (monitor_xfer_memory): Likewise.
+       * remote-adapt.c (adapt_xfer_inferior_memory): Likewise.
+       * remote-array.c (array_xfer_memory): Likewise.
+       * remote-bug.c (bug_xfer_memory): Likewise.
+       * remote-e7000.c (e7000_xfer_inferior_memory): Likewise.
+       * remote-eb.c (eb_xfer_inferior_memory): Likewise.
+       * remote-es.c (es1800_xfer_inferior_memory): Likewise.
+       * remote-mips.c (mips_xfer_memory): Likewise.
+       * remote-mm.c (mm_xfer_inferior_memory): Likewise.
+       * remote-nindy.c (nindy_xfer_inferior_memory): Likewise.
+       * remote-os9k.c (rombug_xfer_inferior_memory): Likewise.
+       * remote-rdi.c (arm_rdi_xfer_memory): Likewise.
+       * remote-rdp.c (remote_rdp_xfer_inferior_memory): Likewise.
+       * remote-sds.c (sds_xfer_memory): Likewise.
+       * remote-sim.c (gdbsim_xfer_inferior_memory): Likewise.
+       * remote-st.c (st2000_xfer_inferior_memory): Likewise.
+       * remote-udi.c (udi_xfer_inferior_memory): Likewise.
+       * remote-vx.c (vx_xfer_memory): Likewise.
+       * remote.c (remote_xfer_memory): Likewise.
+       * target.c (debug_to_xfer_memory, do_xfer_memory): Likewise.
+       * target.h (child_xfer_memory, do_xfer_memory, xfer_memory): Likewise.
+
+       * target.h (#include "memattr.h"): Added.
+       (target_ops.to_xfer_memory): Add attrib argument.
+
+       * wince.c (_initialize_inftarg): Removed call to set_dcache_state.
+       * dcache.h (set_dcache_state): Removed declaration.
+       * dcache.c (set_dcache_state): Removed definition
+       
+       * dcache.c: Update module comment, as dcache is now enabled and
+       disabled with memory region attributes instead of by the global
+       variable "remotecache".  Add comment describing the interaction
+       between dcache and memory region attributes.
+       (dcache_xfer_memory): Add comment describing benefits of moving
+       cache writeback to a higher level.
+       (dcache_struct): Removed cache_has_stuff field.  This was used to
+       record whether the cache had been accessed in order to invalidate
+       it when it was disabled.  However, this is not needed because the
+       cache is write through and the code that enables, disables, and
+       deletes memory regions invalidate the cache.  Add comment which
+       suggests that we could be more selective and only invalidate those
+       cache lines containing data from those memory regions.
+       (dcache_invalidate): Updated.
+       (dcache_xfer_memory): Updated.
        
+       (dcache_alloc): Don't abort() if dcache_enabled_p is clear.
+       (dcache_xfer_memory): Removed code that called do_xfer_memory() to
+       perform a uncached transfer if dcache_enabled_p was clear.  This
+       function is now only called if caching is enabled for the memory
+       region.
+       (dcache_info): Always print cache info.
+
+       * target.c (do_xfer_memory): Add attrib argument.
+       (target_xfer_memory, target_xfer_memory_partial): Break transfer
+       into chunks defined by memory regions, pass region attributes to
+       do_xfer_memory().
+       * dcache.c (dcache_read_line, dcache_write_line): Likewise.
+
+       * Makefile.in (SFILES): Add memattr.c.
+       (COMMON_OBS): Add memattr.o.
+       (dcache.o): Add target.h to dependencies.
+       * memattr.c: New file.
+       * memattr.h: Likewise.
+
        * config/m32r/m32r.mt (GDBSERVER_LIBS): Added ../../intl/libintl.a.
        * config/mips/vr5000.mt (GDBSERVER_LIBS): Likewise.
        * config/tic80/tic80.mt (GDBSERVER_LIBS): Likewise.
index 9bfe4241e50d6d08b496bc9a0e513f8b8d5f560a..1d987a82fea195094b033acb17dacb20d0eeda24 100644 (file)
@@ -1,5 +1,5 @@
 # Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-# 1998, 1999, 2000 Free Software Foundation, Inc.
+# 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
 # This file is part of GDB.
 
@@ -521,7 +521,7 @@ SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
        varobj.c wrapper.c \
        jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
        m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
-       mem-break.c minsyms.c mipsread.c nlmread.c objfiles.c \
+       memattr.c mem-break.c minsyms.c mipsread.c nlmread.c objfiles.c \
        p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c \
        printcmd.c remote.c remote-nrom.c scm-exp.c scm-lang.c \
        scm-valprint.c source.c stabsread.c stack.c symfile.c \
@@ -664,7 +664,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
        expprint.o environ.o stack.o thread.o \
        event-loop.o event-top.o inf-loop.o completer.o \
        gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \
-       mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
+       memattr.o mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
        kod.o kod-cisco.o \
        gdb-events.o \
        exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
@@ -1288,7 +1288,8 @@ corelow.o: corelow.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
 cp-valprint.o: cp-valprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
        $(gdbtypes_h) $(symtab_h) $(value_h) gdb_string.h
 
-dcache.o: dcache.c $(dcache_h) $(defs_h) $(gdbcmd_h) gdb_string.h $(gdbcore_h)
+dcache.o: dcache.c $(dcache_h) $(defs_h) $(gdbcmd_h) gdb_string.h \
+       $(gdbcore_h) target.h
 
 dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
        complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
index cdfe4762de4bbb4140bd0f7b4d779e629b44b4f1..7973b998ea179a7556db7278786da5bae6dbd692 100644 (file)
@@ -1,5 +1,5 @@
 /* Caching code.
-   Copyright 1992-1993, 1995, 1998-1999, 2000 Free Software Foundation, Inc.
+   Copyright 1992-1993, 1995, 1998-1999, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbcore.h"
 #include "target.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.
+/* 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
 
    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.
+   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
    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.
+ */
 
+/* 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. */
 
 /* This value regulates the number of cache blocks stored.
    Smaller values reduce the time spent searching for a cache
@@ -123,6 +133,19 @@ struct dcache_block
   };
 
 
+/* FIXME: dcache_struct used to have a cache_has_stuff field that was
+   used to record whether the cache had been accessed.  This was used
+   to invalidate the cache whenever caching was (re-)enabled (if the
+   cache was disabled and later re-enabled, it could contain stale
+   data).  This was not needed because the cache is write through and
+   the code that enables, disables, and deletes memory region all
+   invalidate the cache.
+
+   This is overkill, since it also invalidates cache lines from
+   unrelated regions.  One way this could be addressed by adding a
+   new function that takes an address and a length and invalidates
+   only those cache lines that match. */
+
 struct dcache_struct
   {
     /* free list */
@@ -135,11 +158,6 @@ struct dcache_struct
 
     /* 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 (DCACHE *dcache, CORE_ADDR addr, char *ptr);
@@ -189,8 +207,6 @@ dcache_invalidate (DCACHE *dcache)
       db->p = 0;
     }
 
-  dcache->cache_has_stuff = 0;
-
   return;
 }
 
@@ -224,39 +240,75 @@ dcache_hit (DCACHE *dcache, CORE_ADDR addr)
 static int
 dcache_write_line (DCACHE *dcache, register struct dcache_block *db)
 {
-  int s;
-  int e;
+  CORE_ADDR memaddr;
+  char *myaddr;
+  int len;
+  int res;
+  int reg_len;
+  struct mem_region *region;
 
-  if (db->anydirty)
+  if (!db->anydirty)
+    return 1;
+
+  len = LINE_SIZE;
+  memaddr = db->addr;
+  myaddr  = db->data;
+
+  while (len > 0)
     {
-      for (s = 0; s < LINE_SIZE; s++)
+      int s;
+      int e;
+      int dirty_len;
+      
+      region = lookup_mem_region(memaddr);
+      if (memaddr + len < region->hi)
+       reg_len = len;
+      else
+       reg_len = region->hi - memaddr;
+
+      if (!region->attrib.cache || region->attrib.mode == MEM_RO)
+       {
+         memaddr += reg_len;
+         myaddr  += reg_len;
+         len     -= reg_len;
+         continue;
+       }
+
+      while (reg_len > 0)
        {
-         if (db->state[s] == ENTRY_DIRTY)
+         s = XFORM(memaddr);
+         do {
+           if (db->state[s] == ENTRY_DIRTY)
+             break;
+           s++;
+           reg_len--;
+         } while (reg_len > 0);
+
+         e = s;
+         do {
+           if (db->state[e] != ENTRY_DIRTY)
+             break;
+           e++;
+           reg_len--;
+         } while (reg_len > 0);
+
+         dirty_len = e - s;
+         while (dirty_len > 0)
            {
-             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 = do_xfer_memory (db->addr + s + done,
-                                           db->data + s + done,
-                                           len - done, 1);
-                   if (t <= 0)
-                     return 0;
-                   done += t;
-                 }
-               memset (db->state + s, ENTRY_OK, len);
-               s = e;
-             }
+             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;
            }
        }
-      db->anydirty = 0;
     }
+
+  db->anydirty = 0;
   return 1;
 }
 
@@ -268,6 +320,8 @@ dcache_read_line (DCACHE *dcache, struct dcache_block *db)
   char *myaddr;
   int len;
   int res;
+  int reg_len;
+  struct mem_region *region;
 
   /* If there are any dirty bytes in the line, it must be written
      before a new line can be read */
@@ -283,13 +337,32 @@ dcache_read_line (DCACHE *dcache, struct dcache_block *db)
 
   while (len > 0)
     {
-      res = do_xfer_memory (memaddr, myaddr, len, 0);
-      if (res <= 0)
-       return 0;
+      region = lookup_mem_region(memaddr);
+      if (memaddr + len < region->hi)
+       reg_len = len;
+      else
+       reg_len = region->hi - memaddr;
+
+      if (!region->attrib.cache || region->attrib.mode == MEM_WO)
+       {
+         memaddr += reg_len;
+         myaddr  += reg_len;
+         len     -= reg_len;
+         continue;
+       }
+      
+      while (reg_len > 0)
+       {
+         res = do_xfer_memory (memaddr, myaddr, reg_len, 0,
+                               &region->attrib);
+         if (res <= 0)
+           return 0;
 
-      memaddr += res;
-      myaddr  += res;
-      len     -= res;
+         memaddr += res;
+         myaddr  += res;
+         len     -= res;
+         reg_len -= res;
+       }
     }
 
   memset (db->state, ENTRY_OK, sizeof (db->data));
@@ -306,9 +379,6 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR addr)
 {
   register struct dcache_block *db;
 
-  if (dcache_enabled_p == 0)
-    abort ();
-
   /* Take something from the free list */
   db = dcache->free_head;
   if (db)
@@ -342,7 +412,7 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR addr)
   return db;
 }
 
-/* Writeback any dirty lines to the remote. */
+/* Writeback any dirty lines. */
 static int
 dcache_writeback (DCACHE *dcache)
 {
@@ -452,30 +522,27 @@ dcache_xfer_memory (DCACHE *dcache, CORE_ADDR memaddr, char *myaddr, int len,
                    int should_write)
 {
   int i;
+  int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, char *ptr);
+  xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
 
-  if (dcache_enabled_p)
+  for (i = 0; i < len; i++)
     {
-      int (*xfunc) (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;
-       }
-
-      if (should_write)
-       dcache_writeback (dcache);
-
-      dcache->cache_has_stuff = 1;
+      if (!xfunc (dcache, memaddr + i, myaddr + i))
+       return 0;
     }
-  else
-    {
-      if (dcache->cache_has_stuff)
-       dcache_invalidate (dcache);
 
-      len = do_xfer_memory(memaddr, myaddr, len, should_write);
-    }
+  /* FIXME: There may be some benefit from moving the cache writeback
+     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() (also target_xfer_memory_partial())
+     is not sufficent, since we want to coalesce memory transfers that
+     are "logically" connected but not actually a single call to one
+     of the memory transfer functions. */
+
+  if (should_write)
+    dcache_writeback (dcache);
+    
   return len;
 }
 
@@ -484,12 +551,7 @@ dcache_info (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",
+  printf_filtered ("Dcache line width %d, depth %d\n",
                   LINE_SIZE, DCACHE_SIZE);
 
   if (last_cache)
@@ -513,13 +575,6 @@ dcache_info (char *exp, int tty)
     }
 }
 
-/* Turn dcache on or off. */
-void
-set_dcache_state (int what)
-{
-  dcache_enabled_p = !!what;
-}
-
 void
 _initialize_dcache (void)
 {
index 079b03790cbd168647a275dea2f68408e5bbadff..44d16ac64edea4316d26aa84c083bca16270d84a 100644 (file)
@@ -1,7 +1,7 @@
 /* Declarations for caching.  Typically used by remote back ends for
    caching remote memory.
 
-   Copyright 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1992, 1993, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -39,7 +39,4 @@ void dcache_free (DCACHE *);
 int dcache_xfer_memory (DCACHE *cache, CORE_ADDR mem, char *my, int len,
                        int should_write);
 
-/* Turn dcache state on or off */
-void set_dcache_state (int);
-
 #endif /* DCACHE_H */
index 91dd4ae199ed39b0ecff6c091175a3a7b51d3f8a..f98d81ba5cf1b5868e47419c91de5d903051e65f 100644 (file)
@@ -1,3 +1,7 @@
+2001-01-23  J.T. Conklin  <jtc@redback.com>
+
+       * gdb.texinfo (Memory region attributes): New manual section.
+
 2001-01-04  Nicholas Duffek  <nsd@redhat.com>
 
        * gdbint.texinfo (POP_FRAME): Document use by return_command.
index aa925657e1abce9e0474e4129427fbc1c8c5a81f..72f50d95897ab95e0310bd9fa990f05bc35c3cc9 100644 (file)
@@ -1,5 +1,5 @@
 \input texinfo      @c -*-texinfo-*-
-@c Copyright 1988-2000
+@c Copyright 1988-2001
 @c Free Software Foundation, Inc.
 @c
 @c %**start of header
@@ -4347,6 +4347,7 @@ Table}.
 * Convenience Vars::            Convenience variables
 * Registers::                   Registers
 * Floating Point Hardware::     Floating point hardware
+* Memory Region Attributes::    Memory region attributes
 @end menu
 
 @node Expressions
@@ -5504,6 +5505,137 @@ floating point chip.  Currently, @samp{info float} is supported on
 the ARM and x86 machines.
 @end table
 
+@node Memory Region Attributes
+@section Memory Region Attributes 
+@cindex memory region attributes
+
+@dfn{Memory region attributes} allow you to describe special handling 
+required by regions of your target's memory.  @value{GDBN} uses attributes 
+to determine whether to allow certain types of memory accesses; whether to
+use specific width accesses; and whether to cache target memory.
+
+Defined memory regions can be individually enabled and disabled.  When a
+memory region is disabled, @value{GDBN} uses the default attributes when
+accessing memory in that region.  Similarly, if no memory regions have
+been defined, @value{GDBN} uses the default attributes when accessing
+all memory.
+
+When a memory region is defined, it is given a number to identify it; 
+to enable, disable, or remove a memory region, you specify that number.
+
+@table @code
+@kindex mem
+@item mem @var{address1} @var{address1} @var{attributes}@dots{}
+Define memory region bounded by @var{address1} and @var{address2}
+with attributes @var{attributes}@dots{}.
+
+@kindex delete mem
+@item delete mem @var{nums}@dots{}
+Remove memory region numbers @var{nums}.
+
+@kindex disable mem
+@item disable mem @var{nums}@dots{}
+Disable memory region numbers @var{nums}.
+A disabled memory region is not forgotten.  
+It may be enabled again later.
+
+@kindex enable mem
+@item enable mem @var{nums}@dots{}
+Enable memory region numbers @var{nums}.
+
+@kindex info mem
+@item info mem
+Print a table of all defined memory regions, with the following columns
+for each region.
+
+@table @emph
+@item Memory Region Number
+@item Enabled or Disabled.
+Enabled memory regions are marked with @samp{y}.  
+Disabled memory regions are marked with @samp{n}.
+
+@item Lo Address
+The address defining the inclusive lower bound of the memory region.
+
+@item Hi Address
+The address defining the exclusive upper bound of the memory region.
+
+@item Attributes
+The list of attributes set for this memory region.
+@end table
+@end table
+
+
+@subsection Attributes
+
+@subsubsection Memory Access Mode 
+The access mode attributes set whether @value{GDBN} may make read or
+write accesses to a memory region.
+
+While these attributes prevent @value{GDBN} from performing invalid
+memory accesses, they do nothing to prevent the target system, I/O DMA,
+etc. from accessing memory.
+
+@table @code
+@item ro
+Memory is read only.
+@item wo
+Memory is write only.
+@item rw
+Memory is read/write (default).
+@end table
+
+@subsubsection Memory Access Size
+The acccess size attributes tells @value{GDBN} to use specific sized
+accesses in the memory region.  Often memory mapped device registers
+require specific sized accesses.  If no access size attribute is
+specified, @value{GDBN} may use accesses of any size.
+
+@table @code
+@item 8
+Use 8 bit memory accesses.
+@item 16
+Use 16 bit memory accesses.
+@item 32
+Use 32 bit memory accesses.
+@item 64
+Use 64 bit memory accesses.
+@end table
+
+@c @subsubsection Hardware/Software Breakpoints
+@c The hardware/software breakpoint attributes set whether @value{GDBN}
+@c will use hardware or software breakpoints for the internal breakpoints
+@c used by the step, next, finish, until, etc. commands.
+@c
+@c @table @code
+@c @item hwbreak
+@c Always use hardware breakpoints 
+@c @item swbreak (default)
+@c @end table
+
+@subsubsection Data Cache
+The data cache attributes set whether @value{GDBN} will cache target
+memory.  While this generally improves performance by reducing debug
+protocol overhead, it can lead to incorrect results because @value{GDBN}
+does not know about volatile variables or memory mapped device
+registers.
+
+@table @code
+@item cache
+Enable @value{GDBN} to cache target memory. 
+@item nocache (default)
+Disable @value{GDBN} from caching target memory.
+@end table
+
+@c @subsubsection Memory Write Verification
+@c The memory write verification attributes set whether @value{GDBN} 
+@c will re-reads data after each write to verify the write was successful.
+@c
+@c @table @code
+@c @item verify
+@c @item noverify (default)
+@c @end table
+
 @node Languages
 @chapter Using @value{GDBN} with Different Languages
 @cindex languages
index 6c956bf43f24fbb9191e9e875fe8c3d986598d45..e39062beca5c5f8288b81aa581178a48a6fa6af9 100644 (file)
@@ -1,5 +1,5 @@
 /* Work with executable files, for GDB. 
-   Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1997, 1998
+   Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1997, 1998, 2001
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -449,6 +449,7 @@ map_vmap (bfd *abfd, bfd *arch)
 
 int
 xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+            struct mem_attrib *attrib,
             struct target_ops *target)
 {
   boolean res;
index 30ceb87c4cc94e529f868ee87e281ca3b02dd2ab..f7a1a3a7e68983da0661d9b2ee378f824ecd9ee2 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level Unix child interface to ptrace, for GDB when running under Unix.
-   Copyright 1988, 89, 90, 91, 92, 93, 94, 95, 96, 1998 
+   Copyright 1988, 89, 90, 91, 92, 93, 94, 95, 96, 1998, 2001 
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -511,6 +511,7 @@ store_inferior_registers (int regno)
 
 int
 child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+                  struct mem_attrib *attrib ATTRIBUTE_UNUSED,
                   struct target_ops *target)
 {
   register int i;
diff --git a/gdb/memattr.c b/gdb/memattr.c
new file mode 100644 (file)
index 0000000..5e9e9d5
--- /dev/null
@@ -0,0 +1,497 @@
+/* memattr.c */
+#include "defs.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "memattr.h"
+#include "target.h"
+#include "value.h"
+#include "language.h"
+#include "gdb_string.h"
+
+/* FIXME: While this conflicts with the enum defined in breakpoint.h,
+   I used them to be consistant with how breakpoints, tracepoints, and
+   displays are implemented.  It doesn't lose now because breakpoint.h
+   is not included.  */
+enum enable
+{
+  disabled,
+  enabled
+};
+
+const struct mem_attrib default_mem_attrib =
+{
+  MEM_RW,                      /* mode */
+  MEM_WIDTH_UNSPECIFIED,
+  false,                       /* hwbreak */
+  false,                       /* cache */
+  false                                /* verify */
+};
+
+static struct mem_region *mem_region_chain = NULL;
+static mem_number = 0;
+
+static struct mem_region *
+create_mem_region (CORE_ADDR lo, CORE_ADDR hi,
+                  const struct mem_attrib *attrib)
+{
+  struct mem_region *n, *p, *new;
+
+  if (lo > hi)
+    {
+      printf_unfiltered ("invalid memory region\n");
+      return NULL;
+    }
+
+  n = mem_region_chain;
+  while (n)
+    {
+      /* overlapping node */
+      if ((lo >= n->lo && lo <= n->hi) ||
+         (hi >= n->lo && hi <= n->hi))
+       {
+         printf_unfiltered ("overlapping memory region\n");
+         return NULL;
+       }
+    }
+
+  new = xmalloc (sizeof (struct mem_region));
+  new->lo = lo;
+  new->hi = hi;
+  new->number = ++mem_number;
+  new->status = enabled;
+  new->attrib = *attrib;
+
+  /* link in new node */
+  new->next = mem_region_chain;
+  mem_region_chain = new;
+
+  return new;
+}
+
+static void
+delete_mem_region (struct mem_region *m)
+{
+  free (m);
+}
+
+/*
+ * Look up the memory region cooresponding to ADDR.
+ */
+struct mem_region *
+lookup_mem_region (CORE_ADDR addr)
+{
+  static struct mem_region region;
+  struct mem_region *m;
+  CORE_ADDR lo;
+  CORE_ADDR hi;
+
+  /* First we initialize LO and HI so that they describe the entire
+     memory space.  As we process the memory region chain, they are
+     redefined to describe the minimal region containing ADDR.  LO
+     and HI are used in the case where no memory region is defined
+     that contains ADDR.  If a memory region is disabled, it is
+     treated as if it does not exist.  */
+
+  lo = (CORE_ADDR) 0;
+  hi = (CORE_ADDR) ~ 0;
+
+  for (m = mem_region_chain; m; m = m->next)
+    {
+      if (m->status == enabled)
+       {
+         if (addr >= m->lo && addr < m->hi)
+           return m;
+
+         if (addr >= m->hi && lo < m->hi)
+           lo = m->hi;
+
+         if (addr <= m->lo && hi > m->lo)
+           hi = m->lo;
+       }
+    }
+
+  /* Because no region was found, we must cons up one based on what
+     was learned above.  */
+  region.lo = lo;
+  region.hi = hi;
+  region.attrib = default_mem_attrib;
+  return &region;
+}
+\f
+
+static void
+mem_command (char *args, int from_tty)
+{
+  CORE_ADDR lo, hi;
+  char *tok;
+  struct mem_attrib attrib;
+
+  if (!args)
+    error_no_arg ("No mem");
+
+  tok = strtok (args, " \t");
+  if (!tok)
+    error ("no lo address");
+  lo = parse_and_eval_address (tok);
+
+  tok = strtok (NULL, " \t");
+  if (!tok)
+    error ("no hi address");
+  hi = parse_and_eval_address (tok);
+
+  attrib = default_mem_attrib;
+  while ((tok = strtok (NULL, " \t")) != NULL)
+    {
+      if (strcmp (tok, "rw") == 0)
+       attrib.mode = MEM_RW;
+      else if (strcmp (tok, "ro") == 0)
+       attrib.mode = MEM_RO;
+      else if (strcmp (tok, "wo") == 0)
+       attrib.mode = MEM_WO;
+
+      else if (strcmp (tok, "8") == 0)
+       attrib.width = MEM_WIDTH_8;
+      else if (strcmp (tok, "16") == 0)
+       {
+         if ((lo % 2 != 0) || (hi % 2 != 0))
+           error ("region bounds not 16 bit aligned");
+         attrib.width = MEM_WIDTH_16;
+       }
+      else if (strcmp (tok, "32") == 0)
+       {
+         if ((lo % 4 != 0) || (hi % 4 != 0))
+           error ("region bounds not 32 bit aligned");
+         attrib.width = MEM_WIDTH_32;
+       }
+      else if (strcmp (tok, "64") == 0)
+       {
+         if ((lo % 8 != 0) || (hi % 8 != 0))
+           error ("region bounds not 64 bit aligned");
+         attrib.width = MEM_WIDTH_64;
+       }
+
+#if 0
+      else if (strcmp (tok, "hwbreak") == 0)
+       attrib.hwbreak = true;
+      else if (strcmp (tok, "swbreak") == 0)
+       attrib.hwbreak = false;
+#endif
+
+      else if (strcmp (tok, "cache") == 0)
+       attrib.cache = true;
+      else if (strcmp (tok, "nocache") == 0)
+       attrib.cache = false;
+
+#if 0
+      else if (strcmp (tok, "verify") == 0)
+       attrib.verify = true;
+      else if (strcmp (tok, "noverify") == 0)
+       attrib.verify = false;
+#endif
+
+      else
+       error ("unknown attribute: %s", tok);
+    }
+
+  create_mem_region (lo, hi, &attrib);
+}
+\f
+
+static void
+mem_info_command (char *args, int from_tty)
+{
+  struct mem_region *m;
+  struct mem_attrib *attrib;
+
+  if (!mem_region_chain)
+    {
+      printf_unfiltered ("There are no memory regions defined.\n");
+      return;
+    }
+
+  printf_filtered ("Memory regions now in effect:\n");
+  for (m = mem_region_chain; m; m = m->next)
+    {
+      printf_filtered ("%d: %c\t",
+                      m->number,
+                      m->status ? 'y' : 'n');
+      printf_filtered ("%s - ",
+                   local_hex_string_custom ((unsigned long) m->lo, "08l"));
+      printf_filtered ("%s\t",
+                   local_hex_string_custom ((unsigned long) m->hi, "08l"));
+
+      /* Print a token for each attribute.
+
+       * FIXME: Should we output a comma after each token?  It may
+       * make it easier for users to read, but we'd lose the ability
+       * to cut-and-paste the list of attributes when defining a new
+       * region.  Perhaps that is not important.
+       *
+       * FIXME: If more attributes are added to GDB, the output may
+       * become cluttered and difficult for users to read.  At that
+       * time, we may want to consider printing tokens only if they
+       * are different from the default attribute.  */
+
+      attrib = &m->attrib;
+      switch (attrib->mode)
+       {
+       case MEM_RW:
+         printf_filtered ("rw ");
+         break;
+       case MEM_RO:
+         printf_filtered ("ro ");
+         break;
+       case MEM_WO:
+         printf_filtered ("wo ");
+         break;
+       }
+
+      switch (attrib->width)
+       {
+       case MEM_WIDTH_8:
+         printf_filtered ("8 ");
+         break;
+       case MEM_WIDTH_16:
+         printf_filtered ("16 ");
+         break;
+       case MEM_WIDTH_32:
+         printf_filtered ("32 ");
+         break;
+       case MEM_WIDTH_64:
+         printf_filtered ("64 ");
+         break;
+       case MEM_WIDTH_UNSPECIFIED:
+         break;
+       }
+
+#if 0
+      if (attrib->hwbreak)
+       printf_filtered ("hwbreak");
+      else
+       printf_filtered ("swbreak");
+#endif
+
+      if (attrib->cache)
+       printf_filtered ("cache ");
+      else
+       printf_filtered ("nocache ");
+
+#if 0
+      if (attrib->verify)
+       printf_filtered ("verify ");
+      else
+       printf_filtered ("noverify ");
+#endif
+
+      printf_filtered ("\n");
+
+      gdb_flush (gdb_stdout);
+    }
+}
+\f
+
+/* Enable the memory region number NUM. */
+
+static void
+mem_enable (int num)
+{
+  struct mem_region *m;
+
+  for (m = mem_region_chain; m; m = m->next)
+    if (m->number == num)
+      {
+       m->status = enabled;
+       return;
+      }
+  printf_unfiltered ("No memory region number %d.\n", num);
+}
+
+static void
+mem_enable_command (char *args, int from_tty)
+{
+  char *p = args;
+  char *p1;
+  int num;
+  struct mem_region *m;
+
+  dcache_invalidate (target_dcache);
+
+  if (p == 0)
+    {
+      for (m = mem_region_chain; m; m = m->next)
+       m->status = enabled;
+    }
+  else
+    while (*p)
+      {
+       p1 = p;
+       while (*p1 >= '0' && *p1 <= '9')
+         p1++;
+       if (*p1 && *p1 != ' ' && *p1 != '\t')
+         error ("Arguments must be memory region numbers.");
+
+       num = atoi (p);
+       mem_enable (num);
+
+       p = p1;
+       while (*p == ' ' || *p == '\t')
+         p++;
+      }
+}
+\f
+
+/* Disable the memory region number NUM. */
+
+static void
+mem_disable (int num)
+{
+  struct mem_region *m;
+
+  for (m = mem_region_chain; m; m = m->next)
+    if (m->number == num)
+      {
+       m->status = disabled;
+       return;
+      }
+  printf_unfiltered ("No memory region number %d.\n", num);
+}
+
+static void
+mem_disable_command (char *args, int from_tty)
+{
+  char *p = args;
+  char *p1;
+  int num;
+  struct mem_region *m;
+
+  dcache_invalidate (target_dcache);
+
+  if (p == 0)
+    {
+      for (m = mem_region_chain; m; m = m->next)
+       m->status = disabled;
+    }
+  else
+    while (*p)
+      {
+       p1 = p;
+       while (*p1 >= '0' && *p1 <= '9')
+         p1++;
+       if (*p1 && *p1 != ' ' && *p1 != '\t')
+         error ("Arguments must be memory region numbers.");
+
+       num = atoi (p);
+       mem_disable (num);
+
+       p = p1;
+       while (*p == ' ' || *p == '\t')
+         p++;
+      }
+}
+
+/* Clear memory region list */
+
+static void
+mem_clear (void)
+{
+  struct mem_region *m;
+
+  while ((m = mem_region_chain) != 0)
+    {
+      mem_region_chain = m->next;
+      delete_mem_region (m);
+    }
+}
+
+/* Delete the memory region number NUM. */
+
+static void
+mem_delete (int num)
+{
+  struct mem_region *m1, *m;
+
+  if (!mem_region_chain)
+    {
+      printf_unfiltered ("No memory region number %d.\n", num);
+      return;
+    }
+
+  if (mem_region_chain->number == num)
+    {
+      m1 = mem_region_chain;
+      mem_region_chain = m1->next;
+      delete_mem_region (m1);
+    }
+  else
+    for (m = mem_region_chain; m->next; m = m->next)
+      {
+       if (m->next->number == num)
+         {
+           m1 = m->next;
+           m->next = m1->next;
+           delete_mem_region (m1);
+           break;
+         }
+      }
+}
+
+static void
+mem_delete_command (char *args, int from_tty)
+{
+  char *p = args;
+  char *p1;
+  int num;
+
+  dcache_invalidate (target_dcache);
+
+  if (p == 0)
+    {
+      if (query ("Delete all memory regions? "))
+       mem_clear ();
+      dont_repeat ();
+      return;
+    }
+
+  while (*p)
+    {
+      p1 = p;
+      while (*p1 >= '0' && *p1 <= '9')
+       p1++;
+      if (*p1 && *p1 != ' ' && *p1 != '\t')
+       error ("Arguments must be memory region numbers.");
+
+      num = atoi (p);
+      mem_delete (num);
+
+      p = p1;
+      while (*p == ' ' || *p == '\t')
+       p++;
+    }
+
+  dont_repeat ();
+}
+\f
+void
+_initialize_mem ()
+{
+  add_com ("mem", class_vars, mem_command,
+          "Define attributes for memory region.");
+
+  add_cmd ("mem", class_vars, mem_enable_command,
+          "Enable memory region.\n\
+Arguments are the code numbers of the memory regions to enable.\n\
+Do \"info mem\" to see current list of code numbers.", &enablelist);
+
+  add_cmd ("mem", class_vars, mem_disable_command,
+          "Disable memory region.\n\
+Arguments are the code numbers of the memory regions to disable.\n\
+Do \"info mem\" to see current list of code numbers.", &disablelist);
+
+  add_cmd ("mem", class_vars, mem_delete_command,
+          "Delete memory region.\n\
+Arguments are the code numbers of the memory regions to delete.\n\
+Do \"info mem\" to see current list of code numbers.", &deletelist);
+
+  add_info ("mem", mem_info_command,
+           "Memory region attributes");
+}
diff --git a/gdb/memattr.h b/gdb/memattr.h
new file mode 100644 (file)
index 0000000..1af276b
--- /dev/null
@@ -0,0 +1,72 @@
+/* memattr.h */
+#ifndef MEMATTR_H
+#define MEMATTR_H
+
+enum mem_access_mode
+{
+  MEM_RW,                      /* read/write */
+  MEM_RO,                      /* read only */
+  MEM_WO,                      /* write only */
+};
+
+enum mem_access_width
+{
+  MEM_WIDTH_UNSPECIFIED,
+  MEM_WIDTH_8,                 /*  8 bit accesses */
+  MEM_WIDTH_16,                        /* 16  "      "    */
+  MEM_WIDTH_32,                        /* 32  "      "    */
+  MEM_WIDTH_64                 /* 64  "      "    */
+};
+
+/* The set of all attributes that can be set for a memory region.
+  
+   This structure was created so that memory attributes can be passed
+   to target_ functions without exposing the details of memory region
+   list, which would be necessary if these fields were simply added to
+   the mem_region structure.
+
+   FIXME: It would be useful if there was a mechanism for targets to
+   add their own attributes.  For example, the number of wait states. */
+struct mem_attrib 
+{
+  /* read/write, read-only, or write-only */
+  enum mem_access_mode mode;
+
+  enum mem_access_width width;
+
+  /* enables hardware breakpoints */
+  int hwbreak;
+  
+  /* enables host-side caching of memory region data */
+  int cache;
+  
+  /* enables memory verification.  after a write, memory is re-read
+     to verify that the write was successful. */
+  int verify; 
+};
+
+struct mem_region 
+{
+  /* FIXME: memory regions are stored in an unsorted singly-linked
+     list.  This probably won't scale to handle hundreds of memory
+     regions --- that many could be needed to describe the allowed
+     access modes for memory mapped i/o device registers. */
+  struct mem_region *next;
+  
+  CORE_ADDR lo;
+  CORE_ADDR hi;
+
+  /* Item number of this memory region. */
+  int number;
+
+  /* Status of this memory region (enabled or disabled) */
+  int status;
+
+  /* Attributes for this region */
+  struct mem_attrib attrib;
+};
+
+extern struct mem_region *lookup_mem_region(CORE_ADDR);
+
+#endif /* MEMATTR_H */
index ea7189b7d99766be49495d2fe0556aa421e4f578..90e82f3e61bbd780e05f0b3bac3f80976c911757 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for boot monitors, for GDB.
-   Copyright 1990-1993, 1995-1997, 1999-2000 Free Software Foundation, Inc.
+   Copyright 1990-1993, 1995-1997, 1999-2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.  Written by Rob Savoye for Cygnus.
    Resurrected from the ashes by Stu Grossman.
 
@@ -77,7 +77,9 @@ static void monitor_fetch_registers (int regno);
 static void monitor_store_registers (int regno);
 static void monitor_prepare_to_store (void);
 static int monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                               int write, struct target_ops *target);
+                               int write, 
+                               struct mem_attrib *attrib,
+                               struct target_ops *target);
 static void monitor_files_info (struct target_ops *ops);
 static int monitor_insert_breakpoint (CORE_ADDR addr, char *shadow);
 static int monitor_remove_breakpoint (CORE_ADDR addr, char *shadow);
@@ -1988,7 +1990,8 @@ monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
 
 static int
 monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                    struct target_ops *target)
+                    struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                    struct target_ops *target ATTRIBUTE_UNUSED)
 {
   int res;
 
index f370d3850eaac49b13ad4eab530310c63760592d..44342cbfee4b80d924ec2d3c301b6aa3c94110ae 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for AMD 290*0 Adapt Monitor Version 2.1d18. 
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
    Contributed by David Wood at New York University (wood@lab.ultra.nyu.edu).
    Adapted from work done at Cygnus Support in remote-eb.c.
 
@@ -1167,7 +1167,9 @@ translate_addr (CORE_ADDR addr)
 
 /* FIXME!  Merge these two.  */
 int
-adapt_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
+adapt_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+                           struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                           struct target_ops *target ATTRIBUTE_UNUSED)
 {
 
   memaddr = translate_addr (memaddr);
index cd3cff3e11eaa3ccb57e2eb1296e67178fbae68c..7f0a6d6d9135794f3afac076ee913abfb944177e 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for Array Tech RAID controller..
-   Copyright 90, 91, 92, 93, 94, 1995, 1998  Free Software Foundation, Inc.
+   Copyright 90, 91, 92, 93, 94, 1995, 1998, 2001  Free Software Foundation, Inc.
    Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
 
    This module talks to a debug monitor called 'MONITOR', which
@@ -1026,7 +1026,8 @@ array_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
 
 static int
 array_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                  struct target_ops *target)
+                  struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                  struct target_ops *target ATTRIBUTE_UNUSED)
 {
   if (write)
     return array_write_inferior_memory (memaddr, myaddr, len);
index 73d37b7255b10d323117850f3bbb997ee2dfd7ea..df05975bd06a8f18ca9e338d39ebafd4f9092e9a 100644 (file)
@@ -1,7 +1,7 @@
 /* Remote debugging interface for Motorola's MVME187BUG monitor, an embedded
    monitor for the m88k.
 
-   Copyright 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1992, 1993, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.  Written by K. Richard Pixley.
 
    This file is part of GDB.
@@ -555,7 +555,8 @@ bug_store_register (int regno)
 
 int
 bug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                struct target_ops *target)
+                struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                struct target_ops *target ATTRIBUTE_UNUSED)
 {
   int res;
 
index fbe36025e54b83772e222f22c3803043d16fb8bd..b81df8a6c59180b835012fa360f7f70df791550b 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for Hitachi E7000 ICE, for GDB
-   Copyright 1993, 1994, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support. 
 
    Written by Steve Chamberlain for Cygnus Support.
@@ -1474,7 +1474,9 @@ fast_but_for_the_pause_e7000_read_inferior_memory (CORE_ADDR memaddr,
 
 static int
 e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr,
-                           int len, int write, struct target_ops *target)
+                           int len, int write, 
+                           struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                           struct target_ops *target ATTRIBUTE_UNUSED)
 {
   if (write)
     return e7000_write_inferior_memory (memaddr, myaddr, len);
index 9ccac6f3d8b1b12084fbe412d87a2130a7a693fd..4db90712086894a2d702ab260b445cda55b16585 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for AMD 29000 EBMON on IBM PC, for GDB.
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.  Written by Jim Kingdon for Cygnus.
 
    This file is part of GDB.
@@ -879,7 +879,8 @@ eb_prepare_to_store (void)
 
 int
 eb_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                        struct target_ops *target)
+                        struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                        struct target_ops *target ATTRIBUTE_UNUSED)
 {
   if (write)
     return eb_write_inferior_memory (memaddr, myaddr, len);
index 92541a789f764e6c4179f31c67825794c9c3c9df..2d879c1ccc83acced0b4ea0847e53d5d3d14828c 100644 (file)
@@ -1,5 +1,5 @@
 /* Memory-access and commands for remote es1800 processes, for GDB.
-   Copyright (C) 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1992, 2001 Free Software Foundation, Inc.
 
    This file is added to GDB to make it possible to do debugging via an
    ES-1800 emulator. The code was originally written by Johan Holmberg
@@ -134,7 +134,7 @@ static void es1800_files_info (struct target_ops *);
 
 static int
 es1800_xfer_inferior_memory (CORE_ADDR, char *, int, int,
-                            struct target_ops *);
+                            struct mem_attrib *, struct target_ops *);
 
 static void es1800_prepare_to_store (void);
 
@@ -959,7 +959,9 @@ tohex (int nib)
 
 static int
 es1800_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                            int write, struct target_ops *tops)
+                            int write, 
+                            struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                            struct target_ops *target ATTRIBUTE_UNUSED)
 {
   int origlen = len;
   int xfersize;
index 1905c613b8d5f40ae71da79e46e83ce0f56c26bb..2dff690870cde1fe00cd8723d310a6899d40e5cf 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for MIPS remote debugging protocol.
-   Copyright 1993, 1994, 1995, 2000 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.  Written by Ian Lance Taylor
    <ian@cygnus.com>.
 
@@ -112,7 +112,9 @@ static int mips_store_word (CORE_ADDR addr, unsigned int value,
                            char *old_contents);
 
 static int mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                            int write, struct target_ops *ignore);
+                            int write, 
+                            struct mem_attrib *attrib,
+                            struct target_ops *target);
 
 static void mips_files_info (struct target_ops *ignore);
 
@@ -2069,7 +2071,8 @@ static int mask_address_p = 1;
 
 static int
 mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                 struct target_ops *ignore)
+                 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                 struct target_ops *target ATTRIBUTE_UNUSED)
 {
   int i;
   CORE_ADDR addr;
index f6b5408733bfa4a56e4296ffeae0f37bf995369e..ae4df944b43e43b09e9a6c3d75d29b83b70d9279 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for Am290*0 running MiniMON monitor, for GDB.
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
    Originally written by Daniel Mann at AMD.
 
    This file is part of GDB.
@@ -1173,7 +1173,9 @@ mm_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
 
 /* FIXME!  Merge these two.  */
 static int
-mm_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
+mm_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+                        struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                        struct target_ops *target ATTRIBUTE_UNUSED)
 {
 
   memaddr = translate_addr (memaddr);
index 691aa726b83ed4d8cc32c8c9f66183cb93157828..be6a6e96ea3e74ec452a4e657c45b7c0ce1f5881 100644 (file)
@@ -1,5 +1,5 @@
 /* Memory-access and commands for remote NINDY process, for GDB.
-   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc.
    Contributed by Intel Corporation.  Modified from remote.c by Chris Benenati.
 
    GDB is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -476,7 +476,9 @@ nindy_store_registers (int regno)
 
 int
 nindy_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                           int should_write, struct target_ops *target)
+                           int should_write, 
+                           struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                           struct target_ops *target ATTRIBUTE_UNUSED)
 {
   int res;
 
index 08e1d85f5242549c628a0e6374d6327710a2fed0..57baf84dae9fb695bf0f88d12b3547f9edeb9a5e 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for boot monitors, for GDB.
-   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -826,7 +826,9 @@ rombug_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
 
 static int
 rombug_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                            int write, struct target_ops *target)
+                            int write, 
+                            struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                            struct target_ops *target ATTRIBUTE_UNUSED)
 {
   if (write)
     return rombug_write_inferior_memory (memaddr, myaddr, len);
index 0115e4d4ebecf23bf00516904b1a5c73ee87499b..386a0df96a58d081d20ff81b19a2ea36a839fbce 100644 (file)
@@ -1,5 +1,5 @@
 /* GDB interface to ARM RDI library.
-   Copyright 1997, 1998 Free Software Foundation, Inc.
+   Copyright 1997, 1998, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -52,6 +52,7 @@ static void arm_rdi_files_info (struct target_ops *ignore);
 
 static int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr,
                                int len, int should_write,
+                               struct mem_attrib *attrib,
                                struct target_ops *target);
 
 static void arm_rdi_prepare_to_store (void);
@@ -626,8 +627,9 @@ arm_rdi_store_registers (int regno)
 
 /* ARGSUSED */
 static int
-arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                    int should_write, struct target_ops *target)
+arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
+                    struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                    struct target_ops *target ATTRIBUTE_UNUSED)
 {
   int rslt, i;
 
index 223e2ef5f2fd182591c64a5e5bd45c69df3280a6..ccce506537eb203a653a9ae5d1e4d1662c4dcb28 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging for the ARM RDP interface.
-   Copyright 1994, 1995 Free Software Foundation, Inc.
+   Copyright 1994, 1995, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -167,10 +167,10 @@ static int timeout = 2;
 static char *commandline = NULL;
 
 static int
-remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr,
-                                char *myaddr,
-                                int len,
-                                int write, struct target_ops *target);
+remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
+                                int write, 
+                                struct mem_attrib *attrib,
+                                struct target_ops *target);
 
 
 /* Stuff for talking to the serial layer. */
@@ -873,7 +873,7 @@ exec_swi (int swi, argsin *args)
        char *copy = alloca (args[2].n);
        int done = callback->read (callback, args[0].n, copy, args[2].n);
        if (done > 0)
-         remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0);
+         remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0);
        args->n = args[2].n - done;
        return 1;
       }
@@ -905,10 +905,10 @@ exec_swi (int swi, argsin *args)
              commandline[255] = '\0';
            }
          remote_rdp_xfer_inferior_memory (args[0].n,
-                                          commandline, len + 1, 1, 0);
+                                          commandline, len + 1, 1, 0, 0);
        }
       else
-       remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0);
+       remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0);
       return 1;
 
     default:
@@ -955,6 +955,7 @@ handle_swi (void)
                                               buf,
                                               len,
                                               0,
+                                              0,
                                               0);
            }
          else
@@ -1249,7 +1250,9 @@ remote_rdp_prepare_to_store (void)
 
 static int
 remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                                int write, struct target_ops *target)
+                                int write, 
+                                struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                                struct target_ops *target ATTRIBUTE_UNUSED)
 {
   /* I infer from D Taylor's code that there's a limit on the amount
      we can transfer in one chunk.. */
index 96fa4a881eae7cf9fe976bbd1c12883889f0f8ce..56e61b658190650d9743bb6209eec2019070a9cf 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote target communications for serial-line targets using SDS' protocol.
-   Copyright 1997 Free Software Foundation, Inc.
+   Copyright 1997, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -55,7 +55,8 @@ static int sds_read_bytes (CORE_ADDR, char *, int);
 
 static void sds_files_info (struct target_ops *ignore);
 
-static int sds_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
+static int sds_xfer_memory (CORE_ADDR, char *, int, int, 
+                           struct mem_attrib *, struct target_ops *);
 
 static void sds_prepare_to_store (void);
 
@@ -657,7 +658,8 @@ sds_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
 /* ARGSUSED */
 static int
 sds_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
-                struct target_ops *target)
+                struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                struct target_ops *target ATTRIBUTE_UNUSED)
 {
   int res;
 
index 8b03b889cefd8b2a37f534a6fc495be4a8017148..8c2e75309e6e8caccad74f5d6ed570aebde18a55 100644 (file)
@@ -1,5 +1,5 @@
 /* Generic remote debugging interface for simulators.
-   Copyright 1993, 1994, 1996, 1997, 2000 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
    Steve Chamberlain (sac@cygnus.com).
 
@@ -91,9 +91,10 @@ static int gdbsim_wait (int pid, struct target_waitstatus *status);
 
 static void gdbsim_prepare_to_store (void);
 
-static int gdbsim_xfer_inferior_memory (CORE_ADDR memaddr,
-                                       char *myaddr, int len,
-                                       int write, struct target_ops *target);
+static int gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, 
+                                       int len, int write,
+                                       struct mem_attrib *attrib,
+                                       struct target_ops *target);
 
 static void gdbsim_files_info (struct target_ops *target);
 
@@ -714,7 +715,9 @@ gdbsim_prepare_to_store (void)
 
 static int
 gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                            int write, struct target_ops *target)
+                            int write, 
+                            struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                            struct target_ops *target ATTRIBUTE_UNUSED)
 {
   if (!program_loaded)
     error ("No program loaded.");
index 85077bb175d052df7ef127645c49859485964fee..51e96b70d553e5d48ead679a1ca88dfd2816ca1a 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
-   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.  Written by Jim Kingdon for Cygnus.
 
    This file is part of GDB.
@@ -556,7 +556,9 @@ st2000_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
 
 static int
 st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
-                            int write, struct target_ops *target)
+                            int write, 
+                            struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                            struct target_ops *target ATTRIBUTE_UNUSED)
 {
   if (write)
     return st2000_write_inferior_memory (memaddr, myaddr, len);
index a09c70e384da44165a108153d845d397653fec7d..3987d87a5bac9ff6b64ef401b6fe73837262e37a 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
-   Copyright 1990, 1992, 1995, 2000 Free Software Foundation, Inc.
+   Copyright 1990, 1992, 1995, 2000, 2001 Free Software Foundation, Inc.
    Written by Daniel Mann.  Contributed by AMD.
 
    This file is part of GDB.
@@ -923,7 +923,8 @@ translate_addr (CORE_ADDR addr)
 /* FIXME!  Merge these two.  */
 static int
 udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                         struct target_ops * target)
+                         struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                         struct target_ops *target ATTRIBUTE_UNUSED)
 {
 
   memaddr = translate_addr (memaddr);
index 011e1eaa737c11df66eb6ad952f1b140b4ae9e7b..4503e773244a4b8fd75bb4e9392482c08e1b7fe0 100644 (file)
@@ -1,5 +1,5 @@
 /* Memory-access and commands for remote VxWorks processes, for GDB.
-   Copyright (C) 1990-95, 1997-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1990-95, 1997-98, 1999, 2001 Free Software Foundation, Inc.
    Contributed by Wind River Systems and Cygnus Support.
 
    This file is part of GDB.
@@ -476,7 +476,8 @@ vx_prepare_to_store (void)
 
 static int
 vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-               struct target_ops *target)
+               struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+               struct target_ops *target ATTRIBUTE_UNUSED)
 {
   int status;
   Rptrace ptrace_in;
index c990b1e37f53798ef3476b4b587888227a1c6005..0140b12b9a970232fc8a6a2352e6a3a8cde0c0ab 100644 (file)
@@ -1,5 +1,5 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
-   Copyright 1988, 1991-2000 Free Software Foundation, Inc.
+   Copyright 1988, 1991-2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -70,6 +70,7 @@ static void remote_files_info (struct target_ops *ignore);
 
 static int remote_xfer_memory (CORE_ADDR memaddr, char *myaddr,
                               int len, int should_write,
+                              struct mem_attrib *attrib,
                               struct target_ops *target);
 
 static void remote_prepare_to_store (void);
@@ -3543,7 +3544,9 @@ remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
 /* ARGSUSED */
 static int
 remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
-                   int should_write, struct target_ops *target)
+                   int should_write,
+                   struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                   struct target_ops *target)
 {
   CORE_ADDR targ_addr;
   int targ_len;
index ec4d01eff0ba13c7a1da777312c8463cd2009484..8c76f076868f0e20ef16baf9b78cb3c9a441002d 100644 (file)
@@ -1,5 +1,5 @@
 /* Select target systems and architectures at runtime for GDB.
-   Copyright 1990, 1992-1995, 1998-2000 Free Software Foundation, Inc.
+   Copyright 1990, 1992-1995, 1998-2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
    This file is part of GDB.
@@ -102,7 +102,8 @@ static void debug_to_store_registers (int);
 static void debug_to_prepare_to_store (void);
 
 static int
-debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
+debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *, 
+                     struct target_ops *);
 
 static void debug_to_files_info (struct target_ops *);
 
@@ -379,7 +380,7 @@ cleanup_target (struct target_ops *t)
            (void (*) (void)) 
            noprocess);
   de_fault (to_xfer_memory, 
-           (int (*) (CORE_ADDR, char *, int, int, struct target_ops *)) 
+           (int (*) (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *)) 
            nomemory);
   de_fault (to_files_info, 
            (void (*) (struct target_ops *)) 
@@ -843,7 +844,8 @@ target_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
    Result is -1 on error, or the number of bytes transfered.  */
 
 int
-do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
+do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+               struct mem_attrib *attrib)
 {
   int res;
   int done = 0;
@@ -860,7 +862,7 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
 
   /* The quick case is that the top target can handle the transfer.  */
   res = current_target.to_xfer_memory
-    (memaddr, myaddr, len, write, &current_target);
+    (memaddr, myaddr, len, write, attrib, &current_target);
 
   /* If res <= 0 then we call it again in the loop.  Ah well. */
   if (res <= 0)
@@ -871,7 +873,7 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
          if (!t->to_has_memory)
            continue;
 
-         res = t->to_xfer_memory (memaddr, myaddr, len, write, t);
+         res = t->to_xfer_memory (memaddr, myaddr, len, write, attrib, t);
          if (res > 0)
            break;              /* Handled all or part of xfer */
          if (t->to_has_all_memory)
@@ -895,6 +897,8 @@ static int
 target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
 {
   int res;
+  int reg_len;
+  struct mem_region *region;
 
   /* Zero length requests are ok and require no work.  */
   if (len == 0)
@@ -904,22 +908,52 @@ target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
 
   while (len > 0)
     {
-      res = dcache_xfer_memory(target_dcache, memaddr, myaddr, len, write);
-      if (res <= 0)
+      region = lookup_mem_region(memaddr);
+      if (memaddr + len < region->hi)
+       reg_len = len;
+      else
+       reg_len = region->hi - memaddr;
+
+      switch (region->attrib.mode)
        {
-         /* If this address is for nonexistent memory,
-            read zeros if reading, or do nothing if writing.  Return error. */
+       case MEM_RO:
+         if (write)
+           return EIO;
+         break;
+         
+       case MEM_WO:
          if (!write)
-           memset (myaddr, 0, len);
-         if (errno == 0)
            return EIO;
-         else
-           return errno;
+         break;
        }
 
-      memaddr += res;
-      myaddr  += res;
-      len     -= res;
+      while (reg_len > 0)
+       {
+         if (region->attrib.cache)
+           res = dcache_xfer_memory(target_dcache, memaddr, myaddr,
+                                    reg_len, write);
+         else
+           res = do_xfer_memory(memaddr, myaddr, reg_len, write,
+                                &region->attrib);
+             
+         if (res <= 0)
+           {
+             /* If this address is for nonexistent memory, read zeros
+                if reading, or do nothing if writing.  Return
+                error. */
+             if (!write)
+               memset (myaddr, 0, len);
+             if (errno == 0)
+               return EIO;
+             else
+               return errno;
+           }
+
+         memaddr += res;
+         myaddr  += res;
+         len     -= res;
+         reg_len -= res;
+       }
     }
   
   return 0;                    /* We managed to cover it all somehow. */
@@ -935,6 +969,8 @@ target_xfer_memory_partial (CORE_ADDR memaddr, char *myaddr, int len,
                            int write_p, int *err)
 {
   int res;
+  int reg_len;
+  struct mem_region *region;
 
   /* Zero length requests are ok and require no work.  */
   if (len == 0)
@@ -943,7 +979,38 @@ target_xfer_memory_partial (CORE_ADDR memaddr, char *myaddr, int len,
       return 0;
     }
 
-  res = dcache_xfer_memory (target_dcache, memaddr, myaddr, len, write_p);
+  region = lookup_mem_region(memaddr);
+  if (memaddr + len < region->hi)
+    reg_len = len;
+  else
+    reg_len = region->hi - memaddr;
+
+  switch (region->attrib.mode)
+    {
+    case MEM_RO:
+      if (write_p)
+       {
+         *err = EIO;
+         return 0;
+       }
+      break;
+
+    case MEM_WO:
+      if (write_p)
+       {
+         *err = EIO;
+         return 0;
+       }
+      break;
+    }
+
+  if (region->attrib.cache)
+    res = dcache_xfer_memory (target_dcache, memaddr, myaddr,
+                             reg_len, write_p);
+  else
+    res = do_xfer_memory (memaddr, myaddr, reg_len, write_p,
+                         &region->attrib);
+      
   if (res <= 0)
     {
       if (errno != 0)
@@ -2313,11 +2380,13 @@ debug_to_prepare_to_store (void)
 
 static int
 debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+                     struct mem_attrib *attrib,
                      struct target_ops *target)
 {
   int retval;
 
-  retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target);
+  retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write,
+                                       attrib, target);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
index e1e71d95d34aec2c5af2b15939d495fccfe2c674..d007bbab4786dfe3eaf4a1a4d5785de2d98f0107 100644 (file)
@@ -1,5 +1,5 @@
 /* Interface between GDB and target environments, including files and processes
-   Copyright 1990-1994, 1999, 2000 Free Software Foundation, Inc.
+   Copyright 1990-1994, 1999, 2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.  Written by John Gilmore.
 
    This file is part of GDB.
@@ -44,6 +44,7 @@
 #include "bfd.h"
 #include "symtab.h"
 #include "dcache.h"
+#include "memattr.h"
 
 enum strata
   {
@@ -363,7 +364,9 @@ struct target_ops
        something at MEMADDR + N.  */
 
     int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr,
-                          int len, int write, struct target_ops * target);
+                          int len, int write, 
+                          struct mem_attrib *attrib,
+                          struct target_ops *target);
 
 #if 0
     /* Enable this after 4.12.  */
@@ -619,7 +622,8 @@ extern void target_detach (char *, int);
 
 extern DCACHE *target_dcache;
 
-extern int do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write);
+extern int do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+                          struct mem_attrib *attrib);
 
 extern int target_read_string (CORE_ADDR, char **, int, int *);
 
@@ -627,10 +631,11 @@ extern int target_read_memory (CORE_ADDR memaddr, char *myaddr, int len);
 
 extern int target_write_memory (CORE_ADDR memaddr, char *myaddr, int len);
 
-extern int xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
+extern int xfer_memory (CORE_ADDR, char *, int, int, 
+                       struct mem_attrib *, struct target_ops *);
 
-extern int
-child_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
+extern int child_xfer_memory (CORE_ADDR, char *, int, int, 
+                             struct mem_attrib *, struct target_ops *);
 
 /* Make a single attempt at transfering LEN bytes.  On a successful
    transfer, the number of bytes actually transfered is returned and
index 7ee0b60f6c020d85398394053af45b36c8658cda..bcbe212dab76a9b6dee9b42bea78cfe365b152a2 100644 (file)
@@ -1,5 +1,5 @@
 /* Target-vector operations for controlling Windows CE child processes, for GDB.
-   Copyright 1999, 2000 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Solutions, A Red Hat Company.
 
    This file is part of GDB.
@@ -1975,7 +1975,6 @@ _initialize_inftarg (void)
   add_show_from_set (set, &showlist);
   set->function.cfunc = set_upload_type;
   set_upload_type (NULL, 0);
-  set_dcache_state (1);
 
   add_show_from_set
     (add_set_cmd ((char *) "debugexec", class_support, var_boolean,