1 /* Memory attributes support, for GDB.
2 Copyright 2001 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
28 #include "gdb_string.h"
30 const struct mem_attrib default_mem_attrib
=
33 MEM_WIDTH_UNSPECIFIED
,
39 static struct mem_region
*mem_region_chain
= NULL
;
40 static int mem_number
= 0;
42 static struct mem_region
*
43 create_mem_region (CORE_ADDR lo
, CORE_ADDR hi
,
44 const struct mem_attrib
*attrib
)
46 struct mem_region
*n
, *new;
48 /* lo == hi is a useless empty region */
51 printf_unfiltered ("invalid memory region: low >= high\n");
58 /* overlapping node */
59 if ((lo
>= n
->lo
&& lo
< n
->hi
) ||
60 (hi
> n
->lo
&& hi
<= n
->hi
))
62 printf_unfiltered ("overlapping memory region\n");
68 new = xmalloc (sizeof (struct mem_region
));
71 new->number
= ++mem_number
;
73 new->attrib
= *attrib
;
75 /* link in new node */
76 new->next
= mem_region_chain
;
77 mem_region_chain
= new;
83 delete_mem_region (struct mem_region
*m
)
89 * Look up the memory region cooresponding to ADDR.
92 lookup_mem_region (CORE_ADDR addr
)
94 static struct mem_region region
;
99 /* First we initialize LO and HI so that they describe the entire
100 memory space. As we process the memory region chain, they are
101 redefined to describe the minimal region containing ADDR. LO
102 and HI are used in the case where no memory region is defined
103 that contains ADDR. If a memory region is disabled, it is
104 treated as if it does not exist. */
107 hi
= (CORE_ADDR
) ~ 0;
109 for (m
= mem_region_chain
; m
; m
= m
->next
)
111 if (m
->enabled_p
== 1)
113 if (addr
>= m
->lo
&& addr
< m
->hi
)
116 if (addr
>= m
->hi
&& lo
< m
->hi
)
119 if (addr
<= m
->lo
&& hi
> m
->lo
)
124 /* Because no region was found, we must cons up one based on what
125 was learned above. */
128 region
.attrib
= default_mem_attrib
;
134 mem_command (char *args
, int from_tty
)
138 struct mem_attrib attrib
;
141 error_no_arg ("No mem");
143 tok
= strtok (args
, " \t");
145 error ("no lo address");
146 lo
= parse_and_eval_address (tok
);
148 tok
= strtok (NULL
, " \t");
150 error ("no hi address");
151 hi
= parse_and_eval_address (tok
);
153 attrib
= default_mem_attrib
;
154 while ((tok
= strtok (NULL
, " \t")) != NULL
)
156 if (strcmp (tok
, "rw") == 0)
157 attrib
.mode
= MEM_RW
;
158 else if (strcmp (tok
, "ro") == 0)
159 attrib
.mode
= MEM_RO
;
160 else if (strcmp (tok
, "wo") == 0)
161 attrib
.mode
= MEM_WO
;
163 else if (strcmp (tok
, "8") == 0)
164 attrib
.width
= MEM_WIDTH_8
;
165 else if (strcmp (tok
, "16") == 0)
167 if ((lo
% 2 != 0) || (hi
% 2 != 0))
168 error ("region bounds not 16 bit aligned");
169 attrib
.width
= MEM_WIDTH_16
;
171 else if (strcmp (tok
, "32") == 0)
173 if ((lo
% 4 != 0) || (hi
% 4 != 0))
174 error ("region bounds not 32 bit aligned");
175 attrib
.width
= MEM_WIDTH_32
;
177 else if (strcmp (tok
, "64") == 0)
179 if ((lo
% 8 != 0) || (hi
% 8 != 0))
180 error ("region bounds not 64 bit aligned");
181 attrib
.width
= MEM_WIDTH_64
;
185 else if (strcmp (tok
, "hwbreak") == 0)
187 else if (strcmp (tok
, "swbreak") == 0)
191 else if (strcmp (tok
, "cache") == 0)
193 else if (strcmp (tok
, "nocache") == 0)
197 else if (strcmp (tok
, "verify") == 0)
199 else if (strcmp (tok
, "noverify") == 0)
204 error ("unknown attribute: %s", tok
);
207 create_mem_region (lo
, hi
, &attrib
);
212 mem_info_command (char *args
, int from_tty
)
214 struct mem_region
*m
;
215 struct mem_attrib
*attrib
;
217 if (!mem_region_chain
)
219 printf_unfiltered ("There are no memory regions defined.\n");
223 printf_filtered ("Num ");
224 printf_filtered ("Enb ");
225 printf_filtered ("Low Addr ");
226 if (TARGET_ADDR_BIT
> 32)
227 printf_filtered (" ");
228 printf_filtered ("High Addr ");
229 if (TARGET_ADDR_BIT
> 32)
230 printf_filtered (" ");
231 printf_filtered ("Attrs ");
232 printf_filtered ("\n");
234 for (m
= mem_region_chain
; m
; m
= m
->next
)
237 printf_filtered ("%-3d %-3c\t",
239 m
->enabled_p
? 'y' : 'n');
240 if (TARGET_ADDR_BIT
<= 32)
241 tmp
= longest_local_hex_string_custom ((unsigned long) m
->lo
, "08l");
243 tmp
= longest_local_hex_string_custom ((unsigned long) m
->lo
, "016l");
245 printf_filtered ("%s ", tmp
);
247 if (TARGET_ADDR_BIT
<= 32)
248 tmp
= longest_local_hex_string_custom ((unsigned long) m
->hi
, "08l");
250 tmp
= longest_local_hex_string_custom ((unsigned long) m
->hi
, "016l");
252 printf_filtered ("%s ", tmp
);
254 /* Print a token for each attribute.
256 * FIXME: Should we output a comma after each token? It may
257 * make it easier for users to read, but we'd lose the ability
258 * to cut-and-paste the list of attributes when defining a new
259 * region. Perhaps that is not important.
261 * FIXME: If more attributes are added to GDB, the output may
262 * become cluttered and difficult for users to read. At that
263 * time, we may want to consider printing tokens only if they
264 * are different from the default attribute. */
267 switch (attrib
->mode
)
270 printf_filtered ("rw ");
273 printf_filtered ("ro ");
276 printf_filtered ("wo ");
280 switch (attrib
->width
)
283 printf_filtered ("8 ");
286 printf_filtered ("16 ");
289 printf_filtered ("32 ");
292 printf_filtered ("64 ");
294 case MEM_WIDTH_UNSPECIFIED
:
300 printf_filtered ("hwbreak");
302 printf_filtered ("swbreak");
306 printf_filtered ("cache ");
308 printf_filtered ("nocache ");
312 printf_filtered ("verify ");
314 printf_filtered ("noverify ");
317 printf_filtered ("\n");
319 gdb_flush (gdb_stdout
);
324 /* Enable the memory region number NUM. */
329 struct mem_region
*m
;
331 for (m
= mem_region_chain
; m
; m
= m
->next
)
332 if (m
->number
== num
)
337 printf_unfiltered ("No memory region number %d.\n", num
);
341 mem_enable_command (char *args
, int from_tty
)
346 struct mem_region
*m
;
348 dcache_invalidate (target_dcache
);
352 for (m
= mem_region_chain
; m
; m
= m
->next
)
359 while (*p1
>= '0' && *p1
<= '9')
361 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
362 error ("Arguments must be memory region numbers.");
368 while (*p
== ' ' || *p
== '\t')
374 /* Disable the memory region number NUM. */
377 mem_disable (int num
)
379 struct mem_region
*m
;
381 for (m
= mem_region_chain
; m
; m
= m
->next
)
382 if (m
->number
== num
)
387 printf_unfiltered ("No memory region number %d.\n", num
);
391 mem_disable_command (char *args
, int from_tty
)
396 struct mem_region
*m
;
398 dcache_invalidate (target_dcache
);
402 for (m
= mem_region_chain
; m
; m
= m
->next
)
409 while (*p1
>= '0' && *p1
<= '9')
411 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
412 error ("Arguments must be memory region numbers.");
418 while (*p
== ' ' || *p
== '\t')
423 /* Clear memory region list */
428 struct mem_region
*m
;
430 while ((m
= mem_region_chain
) != 0)
432 mem_region_chain
= m
->next
;
433 delete_mem_region (m
);
437 /* Delete the memory region number NUM. */
442 struct mem_region
*m1
, *m
;
444 if (!mem_region_chain
)
446 printf_unfiltered ("No memory region number %d.\n", num
);
450 if (mem_region_chain
->number
== num
)
452 m1
= mem_region_chain
;
453 mem_region_chain
= m1
->next
;
454 delete_mem_region (m1
);
457 for (m
= mem_region_chain
; m
->next
; m
= m
->next
)
459 if (m
->next
->number
== num
)
463 delete_mem_region (m1
);
470 mem_delete_command (char *args
, int from_tty
)
476 dcache_invalidate (target_dcache
);
480 if (query ("Delete all memory regions? "))
489 while (*p1
>= '0' && *p1
<= '9')
491 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
492 error ("Arguments must be memory region numbers.");
498 while (*p
== ' ' || *p
== '\t')
508 add_com ("mem", class_vars
, mem_command
,
509 "Define attributes for memory region.\n\
510 Usage: mem <lo addr> <hi addr> [<mode> <width> <cache>], \n\
511 where <mode> may be rw (read/write), ro (read-only) or wo (write-only), \n\
512 <width> may be 8, 16, 32, or 64, and \n\
513 <cache> may be cache or nocache");
515 add_cmd ("mem", class_vars
, mem_enable_command
,
516 "Enable memory region.\n\
517 Arguments are the code numbers of the memory regions to enable.\n\
518 Usage: enable mem <code number>\n\
519 Do \"info mem\" to see current list of code numbers.", &enablelist
);
521 add_cmd ("mem", class_vars
, mem_disable_command
,
522 "Disable memory region.\n\
523 Arguments are the code numbers of the memory regions to disable.\n\
524 Usage: disable mem <code number>\n\
525 Do \"info mem\" to see current list of code numbers.", &disablelist
);
527 add_cmd ("mem", class_vars
, mem_delete_command
,
528 "Delete memory region.\n\
529 Arguments are the code numbers of the memory regions to delete.\n\
530 Usage: delete mem <code number>\n\
531 Do \"info mem\" to see current list of code numbers.", &deletelist
);
533 add_info ("mem", mem_info_command
,
534 "Memory region attributes");