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;
50 printf_unfiltered ("invalid memory region\n");
57 /* overlapping node */
58 if ((lo >= n->lo && lo <= n->hi) ||
59 (hi >= n->lo && hi <= n->hi))
61 printf_unfiltered ("overlapping memory region\n");
67 new = xmalloc (sizeof (struct mem_region));
70 new->number = ++mem_number;
72 new->attrib = *attrib;
74 /* link in new node */
75 new->next = mem_region_chain;
76 mem_region_chain = new;
82 delete_mem_region (struct mem_region *m)
88 * Look up the memory region cooresponding to ADDR.
91 lookup_mem_region (CORE_ADDR addr)
93 static struct mem_region region;
98 /* First we initialize LO and HI so that they describe the entire
99 memory space. As we process the memory region chain, they are
100 redefined to describe the minimal region containing ADDR. LO
101 and HI are used in the case where no memory region is defined
102 that contains ADDR. If a memory region is disabled, it is
103 treated as if it does not exist. */
106 hi = (CORE_ADDR) ~ 0;
108 for (m = mem_region_chain; m; m = m->next)
110 if (m->enabled_p == 1)
112 if (addr >= m->lo && addr < m->hi)
115 if (addr >= m->hi && lo < m->hi)
118 if (addr <= m->lo && hi > m->lo)
123 /* Because no region was found, we must cons up one based on what
124 was learned above. */
127 region.attrib = default_mem_attrib;
133 mem_command (char *args, int from_tty)
137 struct mem_attrib attrib;
140 error_no_arg ("No mem");
142 tok = strtok (args, " \t");
144 error ("no lo address");
145 lo = parse_and_eval_address (tok);
147 tok = strtok (NULL, " \t");
149 error ("no hi address");
150 hi = parse_and_eval_address (tok);
152 attrib = default_mem_attrib;
153 while ((tok = strtok (NULL, " \t")) != NULL)
155 if (strcmp (tok, "rw") == 0)
156 attrib.mode = MEM_RW;
157 else if (strcmp (tok, "ro") == 0)
158 attrib.mode = MEM_RO;
159 else if (strcmp (tok, "wo") == 0)
160 attrib.mode = MEM_WO;
162 else if (strcmp (tok, "8") == 0)
163 attrib.width = MEM_WIDTH_8;
164 else if (strcmp (tok, "16") == 0)
166 if ((lo % 2 != 0) || (hi % 2 != 0))
167 error ("region bounds not 16 bit aligned");
168 attrib.width = MEM_WIDTH_16;
170 else if (strcmp (tok, "32") == 0)
172 if ((lo % 4 != 0) || (hi % 4 != 0))
173 error ("region bounds not 32 bit aligned");
174 attrib.width = MEM_WIDTH_32;
176 else if (strcmp (tok, "64") == 0)
178 if ((lo % 8 != 0) || (hi % 8 != 0))
179 error ("region bounds not 64 bit aligned");
180 attrib.width = MEM_WIDTH_64;
184 else if (strcmp (tok, "hwbreak") == 0)
185 attrib.hwbreak = true;
186 else if (strcmp (tok, "swbreak") == 0)
187 attrib.hwbreak = false;
190 else if (strcmp (tok, "cache") == 0)
192 else if (strcmp (tok, "nocache") == 0)
193 attrib.cache = false;
196 else if (strcmp (tok, "verify") == 0)
197 attrib.verify = true;
198 else if (strcmp (tok, "noverify") == 0)
199 attrib.verify = false;
203 error ("unknown attribute: %s", tok);
206 create_mem_region (lo, hi, &attrib);
211 mem_info_command (char *args, int from_tty)
213 struct mem_region *m;
214 struct mem_attrib *attrib;
216 if (!mem_region_chain)
218 printf_unfiltered ("There are no memory regions defined.\n");
222 printf_filtered ("Num ");
223 printf_filtered ("Enb ");
224 printf_filtered ("Low Addr ");
225 if (TARGET_ADDR_BIT > 32)
226 printf_filtered (" ");
227 printf_filtered ("High Addr ");
228 if (TARGET_ADDR_BIT > 32)
229 printf_filtered (" ");
230 printf_filtered ("Attrs ");
231 printf_filtered ("\n");
233 for (m = mem_region_chain; m; m = m->next)
236 printf_filtered ("%-3d %-3c\t",
238 m->enabled_p ? 'y' : 'n');
239 if (TARGET_ADDR_BIT <= 32)
240 tmp = longest_local_hex_string_custom ((unsigned long) m->lo, "08l");
242 tmp = longest_local_hex_string_custom ((unsigned long) m->lo, "016l");
244 printf_filtered ("%s ", tmp);
246 if (TARGET_ADDR_BIT <= 32)
247 tmp = longest_local_hex_string_custom ((unsigned long) m->hi, "08l");
249 tmp = longest_local_hex_string_custom ((unsigned long) m->hi, "016l");
251 printf_filtered ("%s ", tmp);
253 /* Print a token for each attribute.
255 * FIXME: Should we output a comma after each token? It may
256 * make it easier for users to read, but we'd lose the ability
257 * to cut-and-paste the list of attributes when defining a new
258 * region. Perhaps that is not important.
260 * FIXME: If more attributes are added to GDB, the output may
261 * become cluttered and difficult for users to read. At that
262 * time, we may want to consider printing tokens only if they
263 * are different from the default attribute. */
266 switch (attrib->mode)
269 printf_filtered ("rw ");
272 printf_filtered ("ro ");
275 printf_filtered ("wo ");
279 switch (attrib->width)
282 printf_filtered ("8 ");
285 printf_filtered ("16 ");
288 printf_filtered ("32 ");
291 printf_filtered ("64 ");
293 case MEM_WIDTH_UNSPECIFIED:
299 printf_filtered ("hwbreak");
301 printf_filtered ("swbreak");
305 printf_filtered ("cache ");
307 printf_filtered ("nocache ");
311 printf_filtered ("verify ");
313 printf_filtered ("noverify ");
316 printf_filtered ("\n");
318 gdb_flush (gdb_stdout);
323 /* Enable the memory region number NUM. */
328 struct mem_region *m;
330 for (m = mem_region_chain; m; m = m->next)
331 if (m->number == num)
336 printf_unfiltered ("No memory region number %d.\n", num);
340 mem_enable_command (char *args, int from_tty)
345 struct mem_region *m;
347 dcache_invalidate (target_dcache);
351 for (m = mem_region_chain; m; m = m->next)
358 while (*p1 >= '0' && *p1 <= '9')
360 if (*p1 && *p1 != ' ' && *p1 != '\t')
361 error ("Arguments must be memory region numbers.");
367 while (*p == ' ' || *p == '\t')
373 /* Disable the memory region number NUM. */
376 mem_disable (int num)
378 struct mem_region *m;
380 for (m = mem_region_chain; m; m = m->next)
381 if (m->number == num)
386 printf_unfiltered ("No memory region number %d.\n", num);
390 mem_disable_command (char *args, int from_tty)
395 struct mem_region *m;
397 dcache_invalidate (target_dcache);
401 for (m = mem_region_chain; m; m = m->next)
408 while (*p1 >= '0' && *p1 <= '9')
410 if (*p1 && *p1 != ' ' && *p1 != '\t')
411 error ("Arguments must be memory region numbers.");
417 while (*p == ' ' || *p == '\t')
422 /* Clear memory region list */
427 struct mem_region *m;
429 while ((m = mem_region_chain) != 0)
431 mem_region_chain = m->next;
432 delete_mem_region (m);
436 /* Delete the memory region number NUM. */
441 struct mem_region *m1, *m;
443 if (!mem_region_chain)
445 printf_unfiltered ("No memory region number %d.\n", num);
449 if (mem_region_chain->number == num)
451 m1 = mem_region_chain;
452 mem_region_chain = m1->next;
453 delete_mem_region (m1);
456 for (m = mem_region_chain; m->next; m = m->next)
458 if (m->next->number == num)
462 delete_mem_region (m1);
469 mem_delete_command (char *args, int from_tty)
475 dcache_invalidate (target_dcache);
479 if (query ("Delete all memory regions? "))
488 while (*p1 >= '0' && *p1 <= '9')
490 if (*p1 && *p1 != ' ' && *p1 != '\t')
491 error ("Arguments must be memory region numbers.");
497 while (*p == ' ' || *p == '\t')
507 add_com ("mem", class_vars, mem_command,
508 "Define attributes for memory region.\n\
509 Usage: mem <lo addr> <hi addr> [<mode> <width> <cache>]");
511 add_cmd ("mem", class_vars, mem_enable_command,
512 "Enable memory region.\n\
513 Arguments are the code numbers of the memory regions to enable.\n\
514 Usage: enable mem <code number>\n\
515 Do \"info mem\" to see current list of code numbers.", &enablelist);
517 add_cmd ("mem", class_vars, mem_disable_command,
518 "Disable memory region.\n\
519 Arguments are the code numbers of the memory regions to disable.\n\
520 Usage: disable mem <code number>\n\
521 Do \"info mem\" to see current list of code numbers.", &disablelist);
523 add_cmd ("mem", class_vars, mem_delete_command,
524 "Delete memory region.\n\
525 Arguments are the code numbers of the memory regions to delete.\n\
526 Usage: delete mem <code number>\n\
527 Do \"info mem\" to see current list of code numbers.", &deletelist);
529 add_info ("mem", mem_info_command,
530 "Memory region attributes");