This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[RFA]: memory region attributes


Since I didn't get any comments from my RFC:
        http://sources.redhat.com/ml/gdb-patches/2000-11/msg00299.html
        http://sources.redhat.com/ml/gdb-patches/2000-11/msg00301.html

I submit the enclosed patch for approval.  This patch adds the infra-
structure for memory region attributes.  

Once this is committed, there will be a follow up patch that adds
support for the memory access width attribute to the remote protocol,
the sample stubs, and possibly monitor.c (I have no personal need for
the latter, but doing it adds support to a lot of targets with just
one change.  This will depend on how much free time I have).

Many thanks to Eli for helping me with the documentation changes.

gdb ChangeLog entry:

2000-12-05  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.

gdb/doc Changelog Entry:

2000-12-05  J.T. Conklin  <jtc@redback.com>

	* gdbint.texinfo (Memory region attributes): New manual section.


Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.51
diff -c -r1.51 Makefile.in
*** Makefile.in	2000/12/04 23:27:59	1.51
--- Makefile.in	2000/12/06 01:04:28
***************
*** 504,510 ****
  	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 \
  	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 \
--- 504,510 ----
  	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 \
! 	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 \
***************
*** 646,652 ****
  	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 \
  	kod.o kod-cisco.o \
  	gdb-events.o \
  	exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
--- 646,652 ----
  	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) \
! 	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 \
***************
*** 1267,1273 ****
  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)
  
  dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
  	complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
--- 1267,1274 ----
  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) target.h
  
  dbxread.o: dbxread.c $(breakpoint_h) buildsym.h $(command_h) \
  	complaints.h $(defs_h) $(expression_h) gdb-stabs.h $(gdbcore_h) \
Index: dcache.c
===================================================================
RCS file: /cvs/src/src/gdb/dcache.c,v
retrieving revision 1.10
diff -c -r1.10 dcache.c
*** dcache.c	2000/11/03 22:00:56	1.10
--- dcache.c	2000/12/06 01:04:29
***************
*** 25,39 ****
  #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.
- 
     In general the dcache speeds up performance, some speed improvement
     comes from the actual caching mechanism, but the major gain is in
     the reduction of the remote protocol overhead; instead of reading
--- 25,35 ----
  #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 the nocache
!    memory region attribute in those cases.
  
     In general the dcache speeds up performance, some speed improvement
     comes from the actual caching mechanism, but the major gain is in
     the reduction of the remote protocol overhead; instead of reading
***************
*** 61,70 ****
  
     ENTRY_DIRTY means that the byte has some data in it which should be
     written out to the remote target one day, but contains correct
!    data.  ENTRY_OK means that the data is the same in the cache as it
!    is in remote memory.
  
  
     The ENTRY_DIRTY state is necessary because GDB likes to write large
     lumps of memory in small bits.  If the caching mechanism didn't
     maintain the DIRTY information, then something like a two byte
--- 57,68 ----
  
     ENTRY_DIRTY means that the byte has some data in it which should be
     written out to the remote target one day, but contains correct
!    data.
  
+    ENTRY_OK means that the data is the same in the cache as it is in
+    remote memory.
  
+ 
     The ENTRY_DIRTY state is necessary because GDB likes to write large
     lumps of memory in small bits.  If the caching mechanism didn't
     maintain the DIRTY information, then something like a two byte
***************
*** 76,85 ****
     protocol overhead.  This way, all those little writes are bundled
     up into an entire cache line write in one go, without having to
     read the cache line in the first place.
- 
- 
   */
  
  
  /* This value regulates the number of cache blocks stored.
     Smaller values reduce the time spent searching for a cache
--- 74,95 ----
     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,128 ****
--- 133,151 ----
    };
  
  
+ /* 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,145 ****
  
      /* 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);
--- 158,163 ----
***************
*** 189,196 ****
        db->p = 0;
      }
  
-   dcache->cache_has_stuff = 0;
- 
    return;
  }
  
--- 207,212 ----
***************
*** 224,262 ****
  static int
  dcache_write_line (DCACHE *dcache, register struct dcache_block *db)
  {
!   int s;
!   int e;
  
!   if (db->anydirty)
      {
!       for (s = 0; s < LINE_SIZE; s++)
  	{
! 	  if (db->state[s] == ENTRY_DIRTY)
  	    {
! 	      int len = 0;
! 	      for (e = s; e < LINE_SIZE; e++, len++)
! 		if (db->state[e] != ENTRY_DIRTY)
! 		  break;
! 	      {
! 		/* all bytes from s..s+len-1 need to
! 		   be written out */
! 		int done = 0;
! 		while (done < len)
! 		  {
! 		    int t = 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;
! 	      }
  	    }
  	}
-       db->anydirty = 0;
      }
    return 1;
  }
  
--- 240,314 ----
  static int
  dcache_write_line (DCACHE *dcache, register struct dcache_block *db)
  {
!   CORE_ADDR memaddr;
!   char *myaddr;
!   int len;
!   int res;
!   int reg_len;
!   struct mem_region *region;
  
!   if (!db->anydirty)
!     return 1;
! 
!   len = LINE_SIZE;
!   memaddr = db->addr;
!   myaddr  = db->data;
! 
!   while (len > 0)
      {
!       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)
! 	{
! 	  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)
  	    {
! 	      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;
    return 1;
  }
  
***************
*** 268,273 ****
--- 320,327 ----
    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,295 ****
  
    while (len > 0)
      {
!       res = do_xfer_memory (memaddr, myaddr, len, 0);
!       if (res <= 0)
! 	return 0;
  
!       memaddr += res;
!       myaddr  += res;
!       len     -= res;
      }
  
    memset (db->state, ENTRY_OK, sizeof (db->data));
--- 337,368 ----
  
    while (len > 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;
! 	  reg_len -= res;
! 	}
      }
  
    memset (db->state, ENTRY_OK, sizeof (db->data));
***************
*** 306,314 ****
  {
    register struct dcache_block *db;
  
-   if (dcache_enabled_p == 0)
-     abort ();
- 
    /* Take something from the free list */
    db = dcache->free_head;
    if (db)
--- 379,384 ----
***************
*** 342,348 ****
    return db;
  }
  
! /* Writeback any dirty lines to the remote. */
  static int
  dcache_writeback (DCACHE *dcache)
  {
--- 412,418 ----
    return db;
  }
  
! /* Writeback any dirty lines. */
  static int
  dcache_writeback (DCACHE *dcache)
  {
***************
*** 452,481 ****
  		    int should_write)
  {
    int i;
  
!   if (dcache_enabled_p)
      {
!       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;
      }
-   else
-     {
-       if (dcache->cache_has_stuff)
- 	dcache_invalidate (dcache);
  
!       len = do_xfer_memory(memaddr, myaddr, len, should_write);
!     }
    return len;
  }
  
--- 522,548 ----
  		    int should_write)
  {
    int 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;
      }
  
!   /* 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,495 ****
  {
    struct dcache_block *p;
  
!   if (!dcache_enabled_p)
!     {
!       printf_filtered ("Dcache not enabled\n");
!       return;
!     }
!   printf_filtered ("Dcache enabled, line width %d, depth %d\n",
  		   LINE_SIZE, DCACHE_SIZE);
  
    if (last_cache)
--- 551,557 ----
  {
    struct dcache_block *p;
  
!   printf_filtered ("Dcache line width %d, depth %d\n",
  		   LINE_SIZE, DCACHE_SIZE);
  
    if (last_cache)
***************
*** 511,523 ****
  	  printf_filtered ("\n");
  	}
      }
- }
- 
- /* Turn dcache on or off. */
- void
- set_dcache_state (int what)
- {
-   dcache_enabled_p = !!what;
  }
  
  void
--- 573,578 ----
Index: dcache.h
===================================================================
RCS file: /cvs/src/src/gdb/dcache.h,v
retrieving revision 1.6
diff -c -r1.6 dcache.h
*** dcache.h	2000/11/03 22:00:56	1.6
--- dcache.h	2000/12/06 01:04:29
***************
*** 39,45 ****
  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 */
--- 39,42 ----
Index: exec.c
===================================================================
RCS file: /cvs/src/src/gdb/exec.c,v
retrieving revision 1.7
diff -c -r1.7 exec.c
*** exec.c	2000/12/01 00:41:27	1.7
--- exec.c	2000/12/06 01:04:30
***************
*** 449,454 ****
--- 449,455 ----
  
  int
  xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+ 	     struct mem_attrib *attrib,
  	     struct target_ops *target)
  {
    boolean res;
Index: infptrace.c
===================================================================
RCS file: /cvs/src/src/gdb/infptrace.c,v
retrieving revision 1.6
diff -c -r1.6 infptrace.c
*** infptrace.c	2000/09/09 01:38:49	1.6
--- infptrace.c	2000/12/06 01:04:30
***************
*** 511,516 ****
--- 511,517 ----
  
  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;
Index: monitor.c
===================================================================
RCS file: /cvs/src/src/gdb/monitor.c,v
retrieving revision 1.14
diff -c -r1.14 monitor.c
*** monitor.c	2000/11/03 22:00:56	1.14
--- monitor.c	2000/12/06 01:04:33
***************
*** 77,83 ****
  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);
  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);
--- 77,85 ----
  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 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,1994 ****
  
  static int
  monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		     struct target_ops *target)
  {
    int res;
  
--- 1990,1997 ----
  
  static int
  monitor_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int res;
  
Index: remote-adapt.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-adapt.c,v
retrieving revision 1.5
diff -c -r1.5 remote-adapt.c
*** remote-adapt.c	2000/10/02 00:49:55	1.5
--- remote-adapt.c	2000/12/06 01:04:35
***************
*** 1167,1173 ****
  
  /* FIXME!  Merge these two.  */
  int
! adapt_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
  {
  
    memaddr = translate_addr (memaddr);
--- 1167,1175 ----
  
  /* FIXME!  Merge these two.  */
  int
! 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: remote-array.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-array.c,v
retrieving revision 1.7
diff -c -r1.7 remote-array.c
*** remote-array.c	2000/10/02 00:49:55	1.7
--- remote-array.c	2000/12/06 01:04:38
***************
*** 1026,1032 ****
  
  static int
  array_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		   struct target_ops *target)
  {
    if (write)
      return array_write_inferior_memory (memaddr, myaddr, len);
--- 1026,1033 ----
  
  static int
  array_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		   struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		   struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (write)
      return array_write_inferior_memory (memaddr, myaddr, len);
Index: remote-bug.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-bug.c,v
retrieving revision 1.8
diff -c -r1.8 remote-bug.c
*** remote-bug.c	2000/11/03 22:00:56	1.8
--- remote-bug.c	2000/12/06 01:04:39
***************
*** 555,561 ****
  
  int
  bug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		 struct target_ops *target)
  {
    int res;
  
--- 555,562 ----
  
  int
  bug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		 struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int res;
  
Index: remote-e7000.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-e7000.c,v
retrieving revision 1.11
diff -c -r1.11 remote-e7000.c
*** remote-e7000.c	2000/12/02 11:37:15	1.11
--- remote-e7000.c	2000/12/06 01:04:42
***************
*** 1474,1480 ****
  
  static int
  e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr,
! 			    int len, int write, struct target_ops *target)
  {
    if (write)
      return e7000_write_inferior_memory (memaddr, myaddr, len);
--- 1474,1482 ----
  
  static int
  e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr,
! 			    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: remote-eb.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-eb.c,v
retrieving revision 1.5
diff -c -r1.5 remote-eb.c
*** remote-eb.c	2000/10/06 21:50:56	1.5
--- remote-eb.c	2000/12/06 01:04:44
***************
*** 879,885 ****
  
  int
  eb_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			 struct target_ops *target)
  {
    if (write)
      return eb_write_inferior_memory (memaddr, myaddr, len);
--- 879,886 ----
  
  int
  eb_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			 struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (write)
      return eb_write_inferior_memory (memaddr, myaddr, len);
Index: remote-es.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-es.c,v
retrieving revision 1.6
diff -c -r1.6 remote-es.c
*** remote-es.c	2000/10/30 21:50:57	1.6
--- remote-es.c	2000/12/06 01:04:46
***************
*** 134,140 ****
  
  static int
  es1800_xfer_inferior_memory (CORE_ADDR, char *, int, int,
! 			     struct target_ops *);
  
  static void es1800_prepare_to_store (void);
  
--- 134,140 ----
  
  static int
  es1800_xfer_inferior_memory (CORE_ADDR, char *, int, int,
! 			     struct mem_attrib *, struct target_ops *);
  
  static void es1800_prepare_to_store (void);
  
***************
*** 959,965 ****
  
  static int
  es1800_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *tops)
  {
    int origlen = len;
    int xfersize;
--- 959,967 ----
  
  static int
  es1800_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, 
! 			     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int origlen = len;
    int xfersize;
Index: remote-mips.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-mips.c,v
retrieving revision 1.10
diff -c -r1.10 remote-mips.c
*** remote-mips.c	2000/09/12 17:20:09	1.10
--- remote-mips.c	2000/12/06 01:04:50
***************
*** 112,118 ****
  			    char *old_contents);
  
  static int mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *ignore);
  
  static void mips_files_info (struct target_ops *ignore);
  
--- 112,120 ----
  			    char *old_contents);
  
  static int mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, 
! 			     struct mem_attrib *attrib,
! 			     struct target_ops *target);
  
  static void mips_files_info (struct target_ops *ignore);
  
***************
*** 2069,2075 ****
  
  static int
  mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		  struct target_ops *ignore)
  {
    int i;
    CORE_ADDR addr;
--- 2071,2078 ----
  
  static int
  mips_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		  struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		  struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int i;
    CORE_ADDR addr;
Index: remote-mm.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-mm.c,v
retrieving revision 1.4
diff -c -r1.4 remote-mm.c
*** remote-mm.c	2000/10/06 21:50:56	1.4
--- remote-mm.c	2000/12/06 01:04:52
***************
*** 1173,1179 ****
  
  /* FIXME!  Merge these two.  */
  static int
! mm_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
  {
  
    memaddr = translate_addr (memaddr);
--- 1173,1181 ----
  
  /* FIXME!  Merge these two.  */
  static int
! 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: remote-nindy.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-nindy.c,v
retrieving revision 1.9
diff -c -r1.9 remote-nindy.c
*** remote-nindy.c	2000/11/03 22:00:56	1.9
--- remote-nindy.c	2000/12/06 01:04:54
***************
*** 476,482 ****
  
  int
  nindy_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			    int should_write, struct target_ops *target)
  {
    int res;
  
--- 476,484 ----
  
  int
  nindy_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			    int should_write, 
! 			    struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			    struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int res;
  
Index: remote-os9k.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-os9k.c,v
retrieving revision 1.7
diff -c -r1.7 remote-os9k.c
*** remote-os9k.c	2000/10/10 05:17:25	1.7
--- remote-os9k.c	2000/12/06 01:04:54
***************
*** 826,832 ****
  
  static int
  rombug_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *target)
  {
    if (write)
      return rombug_write_inferior_memory (memaddr, myaddr, len);
--- 826,834 ----
  
  static int
  rombug_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     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: remote-rdi.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-rdi.c,v
retrieving revision 1.9
diff -c -r1.9 remote-rdi.c
*** remote-rdi.c	2000/10/12 22:56:31	1.9
--- remote-rdi.c	2000/12/06 01:04:55
***************
*** 52,57 ****
--- 52,58 ----
  
  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,633 ****
  
  /* ARGSUSED */
  static int
! arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 		     int should_write, struct target_ops *target)
  {
    int rslt, i;
  
--- 627,635 ----
  
  /* ARGSUSED */
  static int
! 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: remote-rdp.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-rdp.c,v
retrieving revision 1.7
diff -c -r1.7 remote-rdp.c
*** remote-rdp.c	2000/10/30 21:50:57	1.7
--- remote-rdp.c	2000/12/06 01:04:56
***************
*** 167,176 ****
  static char *commandline = NULL;
  
  static int
! remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr,
! 				 char *myaddr,
! 				 int len,
! 				 int write, struct target_ops *target);
  
  
  /* Stuff for talking to the serial layer. */
--- 167,176 ----
  static char *commandline = NULL;
  
  static int
! 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,879 ****
  	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);
  	args->n = args[2].n - done;
  	return 1;
        }
--- 873,879 ----
  	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, 0);
  	args->n = args[2].n - done;
  	return 1;
        }
***************
*** 905,914 ****
  	      commandline[255] = '\0';
  	    }
  	  remote_rdp_xfer_inferior_memory (args[0].n,
! 					   commandline, len + 1, 1, 0);
  	}
        else
! 	remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0);
        return 1;
  
      default:
--- 905,914 ----
  	      commandline[255] = '\0';
  	    }
  	  remote_rdp_xfer_inferior_memory (args[0].n,
! 					   commandline, len + 1, 1, 0, 0);
  	}
        else
! 	remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0);
        return 1;
  
      default:
***************
*** 955,960 ****
--- 955,961 ----
  					       buf,
  					       len,
  					       0,
+ 					       0,
  					       0);
  	    }
  	  else
***************
*** 1249,1255 ****
  
  static int
  remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 				 int write, struct target_ops *target)
  {
    /* I infer from D Taylor's code that there's a limit on the amount
       we can transfer in one chunk.. */
--- 1250,1258 ----
  
  static int
  remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 				 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: remote-sds.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-sds.c,v
retrieving revision 1.9
diff -c -r1.9 remote-sds.c
*** remote-sds.c	2000/11/03 22:00:56	1.9
--- remote-sds.c	2000/12/06 01:04:57
***************
*** 55,61 ****
  
  static void sds_files_info (struct target_ops *ignore);
  
! static int sds_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
  
  static void sds_prepare_to_store (void);
  
--- 55,62 ----
  
  static void sds_files_info (struct target_ops *ignore);
  
! static int sds_xfer_memory (CORE_ADDR, char *, int, int, 
! 			    struct mem_attrib *, struct target_ops *);
  
  static void sds_prepare_to_store (void);
  
***************
*** 657,663 ****
  /* ARGSUSED */
  static int
  sds_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
! 		 struct target_ops *target)
  {
    int res;
  
--- 658,665 ----
  /* ARGSUSED */
  static int
  sds_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 res;
  
Index: remote-sim.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-sim.c,v
retrieving revision 1.8
diff -c -r1.8 remote-sim.c
*** remote-sim.c	2000/10/12 21:39:21	1.8
--- remote-sim.c	2000/12/06 01:04:58
***************
*** 91,99 ****
  
  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 void gdbsim_files_info (struct target_ops *target);
  
--- 91,100 ----
  
  static void gdbsim_prepare_to_store (void);
  
! 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,720 ****
  
  static int
  gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *target)
  {
    if (!program_loaded)
      error ("No program loaded.");
--- 715,723 ----
  
  static int
  gdbsim_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, 
! 			     struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 			     struct target_ops *target ATTRIBUTE_UNUSED)
  {
    if (!program_loaded)
      error ("No program loaded.");
Index: remote-st.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-st.c,v
retrieving revision 1.5
diff -c -r1.5 remote-st.c
*** remote-st.c	2000/10/16 06:42:28	1.5
--- remote-st.c	2000/12/06 01:04:59
***************
*** 556,562 ****
  
  static int
  st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     int write, struct target_ops *target)
  {
    if (write)
      return st2000_write_inferior_memory (memaddr, myaddr, len);
--- 556,564 ----
  
  static int
  st2000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
! 			     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: remote-udi.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-udi.c,v
retrieving revision 1.7
diff -c -r1.7 remote-udi.c
*** remote-udi.c	2000/08/02 05:17:27	1.7
--- remote-udi.c	2000/12/06 01:05:03
***************
*** 923,929 ****
  /* FIXME!  Merge these two.  */
  static int
  udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 			  struct target_ops * target)
  {
  
    memaddr = translate_addr (memaddr);
--- 923,930 ----
  /* FIXME!  Merge these two.  */
  static int
  udi_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: remote-vx.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-vx.c,v
retrieving revision 1.9
diff -c -r1.9 remote-vx.c
*** remote-vx.c	2000/10/30 21:50:57	1.9
--- remote-vx.c	2000/12/06 01:05:16
***************
*** 476,482 ****
  
  static int
  vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		struct target_ops *target)
  {
    int status;
    Rptrace ptrace_in;
--- 476,483 ----
  
  static int
  vx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		struct target_ops *target ATTRIBUTE_UNUSED)
  {
    int status;
    Rptrace ptrace_in;
Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.30
diff -c -r1.30 remote.c
*** remote.c	2000/11/27 02:18:44	1.30
--- remote.c	2000/12/06 01:05:35
***************
*** 70,75 ****
--- 70,76 ----
  
  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);
***************
*** 3542,3548 ****
  /* ARGSUSED */
  static int
  remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
! 		    int should_write, struct target_ops *target)
  {
    CORE_ADDR targ_addr;
    int targ_len;
--- 3543,3551 ----
  /* ARGSUSED */
  static int
  remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
! 		    int should_write,
! 		    struct mem_attrib *attrib ATTRIBUTE_UNUSED,
! 		    struct target_ops *target)
  {
    CORE_ADDR targ_addr;
    int targ_len;
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.16
diff -c -r1.16 target.c
*** target.c	2000/11/21 10:26:07	1.16
--- target.c	2000/12/06 01:05:47
***************
*** 102,108 ****
  static void debug_to_prepare_to_store (void);
  
  static int
! debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
  
  static void debug_to_files_info (struct target_ops *);
  
--- 102,109 ----
  static void debug_to_prepare_to_store (void);
  
  static int
! 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,385 ****
  	    (void (*) (void)) 
  	    noprocess);
    de_fault (to_xfer_memory, 
! 	    (int (*) (CORE_ADDR, char *, int, int, struct target_ops *)) 
  	    nomemory);
    de_fault (to_files_info, 
  	    (void (*) (struct target_ops *)) 
--- 380,386 ----
  	    (void (*) (void)) 
  	    noprocess);
    de_fault (to_xfer_memory, 
! 	    (int (*) (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *)) 
  	    nomemory);
    de_fault (to_files_info, 
  	    (void (*) (struct target_ops *)) 
***************
*** 843,849 ****
     Result is -1 on error, or the number of bytes transfered.  */
  
  int
! do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
  {
    int res;
    int done = 0;
--- 844,851 ----
     Result is -1 on error, or the number of bytes transfered.  */
  
  int
! do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
! 		struct mem_attrib *attrib)
  {
    int res;
    int done = 0;
***************
*** 860,866 ****
  
    /* The quick case is that the top target can handle the transfer.  */
    res = current_target.to_xfer_memory
!     (memaddr, myaddr, len, write, &current_target);
  
    /* If res <= 0 then we call it again in the loop.  Ah well. */
    if (res <= 0)
--- 862,868 ----
  
    /* The quick case is that the top target can handle the transfer.  */
    res = current_target.to_xfer_memory
!     (memaddr, myaddr, len, write, attrib, &current_target);
  
    /* If res <= 0 then we call it again in the loop.  Ah well. */
    if (res <= 0)
***************
*** 871,877 ****
  	  if (!t->to_has_memory)
  	    continue;
  
! 	  res = t->to_xfer_memory (memaddr, myaddr, len, write, t);
  	  if (res > 0)
  	    break;		/* Handled all or part of xfer */
  	  if (t->to_has_all_memory)
--- 873,879 ----
  	  if (!t->to_has_memory)
  	    continue;
  
! 	  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,900 ****
--- 897,904 ----
  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,925 ****
  
    while (len > 0)
      {
!       res = dcache_xfer_memory(target_dcache, memaddr, myaddr, len, write);
!       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;
      }
    
    return 0;			/* We managed to cover it all somehow. */
--- 908,959 ----
  
    while (len > 0)
      {
!       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)
! 	    return EIO;
! 	  break;
! 	  
! 	case MEM_WO:
  	  if (!write)
  	    return EIO;
! 	  break;
  	}
+ 
+       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,940 ****
--- 969,976 ----
  			    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)
***************
*** 942,949 ****
        *err = 0;
        return 0;
      }
  
!   res = dcache_xfer_memory (target_dcache, memaddr, myaddr, len, write_p);
    if (res <= 0)
      {
        if (errno != 0)
--- 978,1016 ----
        *err = 0;
        return 0;
      }
+ 
+   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,2323 ****
  
  static int
  debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
  		      struct target_ops *target)
  {
    int retval;
  
!   retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target);
  
    fprintf_unfiltered (gdb_stdlog,
  		      "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
--- 2380,2392 ----
  
  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,
! 					attrib, target);
  
    fprintf_unfiltered (gdb_stdlog,
  		      "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.9
diff -c -r1.9 target.h
*** target.h	2000/11/21 10:26:07	1.9
--- target.h	2000/12/06 01:06:04
***************
*** 44,49 ****
--- 44,50 ----
  #include "bfd.h"
  #include "symtab.h"
  #include "dcache.h"
+ #include "memattr.h"
  
  enum strata
    {
***************
*** 363,369 ****
         something at MEMADDR + N.  */
  
      int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr,
! 			   int len, int write, struct target_ops * target);
  
  #if 0
      /* Enable this after 4.12.  */
--- 364,372 ----
         something at MEMADDR + N.  */
  
      int (*to_xfer_memory) (CORE_ADDR memaddr, char *myaddr,
! 			   int len, int write, 
! 			   struct mem_attrib *attrib,
! 			   struct target_ops *target);
  
  #if 0
      /* Enable this after 4.12.  */
***************
*** 619,625 ****
  
  extern DCACHE *target_dcache;
  
! extern int do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write);
  
  extern int target_read_string (CORE_ADDR, char **, int, int *);
  
--- 622,629 ----
  
  extern DCACHE *target_dcache;
  
! 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,636 ****
  
  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
! child_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
  
  /* Make a single attempt at transfering LEN bytes.  On a successful
     transfer, the number of bytes actually transfered is returned and
--- 631,641 ----
  
  extern int target_write_memory (CORE_ADDR memaddr, char *myaddr, int len);
  
! 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 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: wince.c
===================================================================
RCS file: /cvs/src/src/gdb/wince.c,v
retrieving revision 1.10
diff -c -r1.10 wince.c
*** wince.c	2000/11/03 22:00:56	1.10
--- wince.c	2000/12/06 01:06:08
***************
*** 1975,1981 ****
    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,
--- 1975,1980 ----
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.30
diff -c -r1.30 gdb.texinfo
*** gdb.texinfo	2000/11/19 06:31:39	1.30
--- gdb.texinfo	2000/12/06 01:06:41
***************
*** 4347,4352 ****
--- 4347,4353 ----
  * Convenience Vars::            Convenience variables
  * Registers::                   Registers
  * Floating Point Hardware::     Floating point hardware
+ * Memory Region Attributes::    Memory region attributes
  @end menu
  
  @node Expressions
***************
*** 5503,5508 ****
--- 5504,5640 ----
  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 any size accesses.
+ 
+ @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} may can 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





-- 
J.T. Conklin
RedBack Networks

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]