1 /* Memory attributes support, for GDB.
3 Copyright 2001, 2002 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
29 #include "gdb_string.h"
31 const struct mem_attrib default_mem_attrib
=
34 MEM_WIDTH_UNSPECIFIED
,
40 static struct mem_region
*mem_region_chain
= NULL
;
41 static int mem_number
= 0;
43 static struct mem_region
*
44 create_mem_region (CORE_ADDR lo
, CORE_ADDR hi
,
45 const struct mem_attrib
*attrib
)
47 struct mem_region
*n
, *new;
49 /* lo == hi is a useless empty region */
52 printf_unfiltered ("invalid memory region: low >= high\n");
59 /* overlapping node */
60 if ((lo
>= n
->lo
&& lo
< n
->hi
) ||
61 (hi
> n
->lo
&& hi
<= n
->hi
))
63 printf_unfiltered ("overlapping memory region\n");
69 new = xmalloc (sizeof (struct mem_region
));
72 new->number
= ++mem_number
;
74 new->attrib
= *attrib
;
76 /* link in new node */
77 new->next
= mem_region_chain
;
78 mem_region_chain
= new;
84 delete_mem_region (struct mem_region
*m
)
90 * Look up the memory region cooresponding to ADDR.
93 lookup_mem_region (CORE_ADDR addr
)
95 static struct mem_region region
;
100 /* First we initialize LO and HI so that they describe the entire
101 memory space. As we process the memory region chain, they are
102 redefined to describe the minimal region containing ADDR. LO
103 and HI are used in the case where no memory region is defined
104 that contains ADDR. If a memory region is disabled, it is
105 treated as if it does not exist. */
108 hi
= (CORE_ADDR
) ~ 0;
110 for (m
= mem_region_chain
; m
; m
= m
->next
)
112 if (m
->enabled_p
== 1)
114 if (addr
>= m
->lo
&& addr
< m
->hi
)
117 if (addr
>= m
->hi
&& lo
< m
->hi
)
120 if (addr
<= m
->lo
&& hi
> m
->lo
)
125 /* Because no region was found, we must cons up one based on what
126 was learned above. */
129 region
.attrib
= default_mem_attrib
;
135 mem_command (char *args
, int from_tty
)
139 struct mem_attrib attrib
;
142 error_no_arg ("No mem");
144 tok
= strtok (args
, " \t");
146 error ("no lo address");
147 lo
= parse_and_eval_address (tok
);
149 tok
= strtok (NULL
, " \t");
151 error ("no hi address");
152 hi
= parse_and_eval_address (tok
);
154 attrib
= default_mem_attrib
;
155 while ((tok
= strtok (NULL
, " \t")) != NULL
)
157 if (strcmp (tok
, "rw") == 0)
158 attrib
.mode
= MEM_RW
;
159 else if (strcmp (tok
, "ro") == 0)
160 attrib
.mode
= MEM_RO
;
161 else if (strcmp (tok
, "wo") == 0)
162 attrib
.mode
= MEM_WO
;
164 else if (strcmp (tok
, "8") == 0)
165 attrib
.width
= MEM_WIDTH_8
;
166 else if (strcmp (tok
, "16") == 0)
168 if ((lo
% 2 != 0) || (hi
% 2 != 0))
169 error ("region bounds not 16 bit aligned");
170 attrib
.width
= MEM_WIDTH_16
;
172 else if (strcmp (tok
, "32") == 0)
174 if ((lo
% 4 != 0) || (hi
% 4 != 0))
175 error ("region bounds not 32 bit aligned");
176 attrib
.width
= MEM_WIDTH_32
;
178 else if (strcmp (tok
, "64") == 0)
180 if ((lo
% 8 != 0) || (hi
% 8 != 0))
181 error ("region bounds not 64 bit aligned");
182 attrib
.width
= MEM_WIDTH_64
;
186 else if (strcmp (tok
, "hwbreak") == 0)
188 else if (strcmp (tok
, "swbreak") == 0)
192 else if (strcmp (tok
, "cache") == 0)
194 else if (strcmp (tok
, "nocache") == 0)
198 else if (strcmp (tok
, "verify") == 0)
200 else if (strcmp (tok
, "noverify") == 0)
205 error ("unknown attribute: %s", tok
);
208 create_mem_region (lo
, hi
, &attrib
);
213 mem_info_command (char *args
, int from_tty
)
215 struct mem_region
*m
;
216 struct mem_attrib
*attrib
;
218 if (!mem_region_chain
)
220 printf_unfiltered ("There are no memory regions defined.\n");
224 printf_filtered ("Num ");
225 printf_filtered ("Enb ");
226 printf_filtered ("Low Addr ");
227 if (TARGET_ADDR_BIT
> 32)
228 printf_filtered (" ");
229 printf_filtered ("High Addr ");
230 if (TARGET_ADDR_BIT
> 32)
231 printf_filtered (" ");
232 printf_filtered ("Attrs ");
233 printf_filtered ("\n");
235 for (m
= mem_region_chain
; m
; m
= m
->next
)
238 printf_filtered ("%-3d %-3c\t",
240 m
->enabled_p
? 'y' : 'n');
241 if (TARGET_ADDR_BIT
<= 32)
242 tmp
= local_hex_string_custom ((unsigned long) m
->lo
, "08l");
244 tmp
= local_hex_string_custom ((unsigned long) m
->lo
, "016l");
246 printf_filtered ("%s ", tmp
);
248 if (TARGET_ADDR_BIT
<= 32)
249 tmp
= local_hex_string_custom ((unsigned long) m
->hi
, "08l");
251 tmp
= local_hex_string_custom ((unsigned long) m
->hi
, "016l");
253 printf_filtered ("%s ", tmp
);
255 /* Print a token for each attribute.
257 * FIXME: Should we output a comma after each token? It may
258 * make it easier for users to read, but we'd lose the ability
259 * to cut-and-paste the list of attributes when defining a new
260 * region. Perhaps that is not important.
262 * FIXME: If more attributes are added to GDB, the output may
263 * become cluttered and difficult for users to read. At that
264 * time, we may want to consider printing tokens only if they
265 * are different from the default attribute. */
268 switch (attrib
->mode
)
271 printf_filtered ("rw ");
274 printf_filtered ("ro ");
277 printf_filtered ("wo ");
281 switch (attrib
->width
)
284 printf_filtered ("8 ");
287 printf_filtered ("16 ");
290 printf_filtered ("32 ");
293 printf_filtered ("64 ");
295 case MEM_WIDTH_UNSPECIFIED
:
301 printf_filtered ("hwbreak");
303 printf_filtered ("swbreak");
307 printf_filtered ("cache ");
309 printf_filtered ("nocache ");
313 printf_filtered ("verify ");
315 printf_filtered ("noverify ");
318 printf_filtered ("\n");
320 gdb_flush (gdb_stdout
);
325 /* Enable the memory region number NUM. */
330 struct mem_region
*m
;
332 for (m
= mem_region_chain
; m
; m
= m
->next
)
333 if (m
->number
== num
)
338 printf_unfiltered ("No memory region number %d.\n", num
);
342 mem_enable_command (char *args
, int from_tty
)
347 struct mem_region
*m
;
349 dcache_invalidate (target_dcache
);
353 for (m
= mem_region_chain
; m
; m
= m
->next
)
360 while (*p1
>= '0' && *p1
<= '9')
362 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
363 error ("Arguments must be memory region numbers.");
369 while (*p
== ' ' || *p
== '\t')
375 /* Disable the memory region number NUM. */
378 mem_disable (int num
)
380 struct mem_region
*m
;
382 for (m
= mem_region_chain
; m
; m
= m
->next
)
383 if (m
->number
== num
)
388 printf_unfiltered ("No memory region number %d.\n", num
);
392 mem_disable_command (char *args
, int from_tty
)
397 struct mem_region
*m
;
399 dcache_invalidate (target_dcache
);
403 for (m
= mem_region_chain
; m
; m
= m
->next
)
410 while (*p1
>= '0' && *p1
<= '9')
412 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
413 error ("Arguments must be memory region numbers.");
419 while (*p
== ' ' || *p
== '\t')
424 /* Clear memory region list */
429 struct mem_region
*m
;
431 while ((m
= mem_region_chain
) != 0)
433 mem_region_chain
= m
->next
;
434 delete_mem_region (m
);
438 /* Delete the memory region number NUM. */
443 struct mem_region
*m1
, *m
;
445 if (!mem_region_chain
)
447 printf_unfiltered ("No memory region number %d.\n", num
);
451 if (mem_region_chain
->number
== num
)
453 m1
= mem_region_chain
;
454 mem_region_chain
= m1
->next
;
455 delete_mem_region (m1
);
458 for (m
= mem_region_chain
; m
->next
; m
= m
->next
)
460 if (m
->next
->number
== num
)
464 delete_mem_region (m1
);
471 mem_delete_command (char *args
, int from_tty
)
477 dcache_invalidate (target_dcache
);
481 if (query ("Delete all memory regions? "))
490 while (*p1
>= '0' && *p1
<= '9')
492 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
493 error ("Arguments must be memory region numbers.");
499 while (*p
== ' ' || *p
== '\t')
509 add_com ("mem", class_vars
, mem_command
,
510 "Define attributes for memory region.\n\
511 Usage: mem <lo addr> <hi addr> [<mode> <width> <cache>], \n\
512 where <mode> may be rw (read/write), ro (read-only) or wo (write-only), \n\
513 <width> may be 8, 16, 32, or 64, and \n\
514 <cache> may be cache or nocache");
516 add_cmd ("mem", class_vars
, mem_enable_command
,
517 "Enable memory region.\n\
518 Arguments are the code numbers of the memory regions to enable.\n\
519 Usage: enable mem <code number>\n\
520 Do \"info mem\" to see current list of code numbers.", &enablelist
);
522 add_cmd ("mem", class_vars
, mem_disable_command
,
523 "Disable memory region.\n\
524 Arguments are the code numbers of the memory regions to disable.\n\
525 Usage: disable mem <code number>\n\
526 Do \"info mem\" to see current list of code numbers.", &disablelist
);
528 add_cmd ("mem", class_vars
, mem_delete_command
,
529 "Delete memory region.\n\
530 Arguments are the code numbers of the memory regions to delete.\n\
531 Usage: delete mem <code number>\n\
532 Do \"info mem\" to see current list of code numbers.", &deletelist
);
534 add_info ("mem", mem_info_command
,
535 "Memory region attributes");