9 #include "gdb_string.h"
11 /* FIXME: While this conflicts with the enum defined in breakpoint.h,
12 I used them to be consistant with how breakpoints, tracepoints, and
13 displays are implemented. It doesn't lose now because breakpoint.h
21 const struct mem_attrib default_mem_attrib
=
24 MEM_WIDTH_UNSPECIFIED
,
30 static struct mem_region
*mem_region_chain
= NULL
;
31 static int mem_number
= 0;
33 static struct mem_region
*
34 create_mem_region (CORE_ADDR lo
, CORE_ADDR hi
,
35 const struct mem_attrib
*attrib
)
37 struct mem_region
*n
, *p
, *new;
41 printf_unfiltered ("invalid memory region\n");
48 /* overlapping node */
49 if ((lo
>= n
->lo
&& lo
<= n
->hi
) ||
50 (hi
>= n
->lo
&& hi
<= n
->hi
))
52 printf_unfiltered ("overlapping memory region\n");
57 new = xmalloc (sizeof (struct mem_region
));
60 new->number
= ++mem_number
;
61 new->status
= enabled
;
62 new->attrib
= *attrib
;
64 /* link in new node */
65 new->next
= mem_region_chain
;
66 mem_region_chain
= new;
72 delete_mem_region (struct mem_region
*m
)
78 * Look up the memory region cooresponding to ADDR.
81 lookup_mem_region (CORE_ADDR addr
)
83 static struct mem_region region
;
88 /* First we initialize LO and HI so that they describe the entire
89 memory space. As we process the memory region chain, they are
90 redefined to describe the minimal region containing ADDR. LO
91 and HI are used in the case where no memory region is defined
92 that contains ADDR. If a memory region is disabled, it is
93 treated as if it does not exist. */
98 for (m
= mem_region_chain
; m
; m
= m
->next
)
100 if (m
->status
== enabled
)
102 if (addr
>= m
->lo
&& addr
< m
->hi
)
105 if (addr
>= m
->hi
&& lo
< m
->hi
)
108 if (addr
<= m
->lo
&& hi
> m
->lo
)
113 /* Because no region was found, we must cons up one based on what
114 was learned above. */
117 region
.attrib
= default_mem_attrib
;
123 mem_command (char *args
, int from_tty
)
127 struct mem_attrib attrib
;
130 error_no_arg ("No mem");
132 tok
= strtok (args
, " \t");
134 error ("no lo address");
135 lo
= parse_and_eval_address (tok
);
137 tok
= strtok (NULL
, " \t");
139 error ("no hi address");
140 hi
= parse_and_eval_address (tok
);
142 attrib
= default_mem_attrib
;
143 while ((tok
= strtok (NULL
, " \t")) != NULL
)
145 if (strcmp (tok
, "rw") == 0)
146 attrib
.mode
= MEM_RW
;
147 else if (strcmp (tok
, "ro") == 0)
148 attrib
.mode
= MEM_RO
;
149 else if (strcmp (tok
, "wo") == 0)
150 attrib
.mode
= MEM_WO
;
152 else if (strcmp (tok
, "8") == 0)
153 attrib
.width
= MEM_WIDTH_8
;
154 else if (strcmp (tok
, "16") == 0)
156 if ((lo
% 2 != 0) || (hi
% 2 != 0))
157 error ("region bounds not 16 bit aligned");
158 attrib
.width
= MEM_WIDTH_16
;
160 else if (strcmp (tok
, "32") == 0)
162 if ((lo
% 4 != 0) || (hi
% 4 != 0))
163 error ("region bounds not 32 bit aligned");
164 attrib
.width
= MEM_WIDTH_32
;
166 else if (strcmp (tok
, "64") == 0)
168 if ((lo
% 8 != 0) || (hi
% 8 != 0))
169 error ("region bounds not 64 bit aligned");
170 attrib
.width
= MEM_WIDTH_64
;
174 else if (strcmp (tok
, "hwbreak") == 0)
175 attrib
.hwbreak
= true;
176 else if (strcmp (tok
, "swbreak") == 0)
177 attrib
.hwbreak
= false;
180 else if (strcmp (tok
, "cache") == 0)
182 else if (strcmp (tok
, "nocache") == 0)
183 attrib
.cache
= false;
186 else if (strcmp (tok
, "verify") == 0)
187 attrib
.verify
= true;
188 else if (strcmp (tok
, "noverify") == 0)
189 attrib
.verify
= false;
193 error ("unknown attribute: %s", tok
);
196 create_mem_region (lo
, hi
, &attrib
);
201 mem_info_command (char *args
, int from_tty
)
203 struct mem_region
*m
;
204 struct mem_attrib
*attrib
;
206 if (!mem_region_chain
)
208 printf_unfiltered ("There are no memory regions defined.\n");
212 printf_filtered ("Memory regions now in effect:\n");
213 for (m
= mem_region_chain
; m
; m
= m
->next
)
215 printf_filtered ("%d: %c\t",
217 m
->status
? 'y' : 'n');
218 printf_filtered ("%s - ",
219 local_hex_string_custom ((unsigned long) m
->lo
, "08l"));
220 printf_filtered ("%s\t",
221 local_hex_string_custom ((unsigned long) m
->hi
, "08l"));
223 /* Print a token for each attribute.
225 * FIXME: Should we output a comma after each token? It may
226 * make it easier for users to read, but we'd lose the ability
227 * to cut-and-paste the list of attributes when defining a new
228 * region. Perhaps that is not important.
230 * FIXME: If more attributes are added to GDB, the output may
231 * become cluttered and difficult for users to read. At that
232 * time, we may want to consider printing tokens only if they
233 * are different from the default attribute. */
236 switch (attrib
->mode
)
239 printf_filtered ("rw ");
242 printf_filtered ("ro ");
245 printf_filtered ("wo ");
249 switch (attrib
->width
)
252 printf_filtered ("8 ");
255 printf_filtered ("16 ");
258 printf_filtered ("32 ");
261 printf_filtered ("64 ");
263 case MEM_WIDTH_UNSPECIFIED
:
269 printf_filtered ("hwbreak");
271 printf_filtered ("swbreak");
275 printf_filtered ("cache ");
277 printf_filtered ("nocache ");
281 printf_filtered ("verify ");
283 printf_filtered ("noverify ");
286 printf_filtered ("\n");
288 gdb_flush (gdb_stdout
);
293 /* Enable the memory region number NUM. */
298 struct mem_region
*m
;
300 for (m
= mem_region_chain
; m
; m
= m
->next
)
301 if (m
->number
== num
)
306 printf_unfiltered ("No memory region number %d.\n", num
);
310 mem_enable_command (char *args
, int from_tty
)
315 struct mem_region
*m
;
317 dcache_invalidate (target_dcache
);
321 for (m
= mem_region_chain
; m
; m
= m
->next
)
328 while (*p1
>= '0' && *p1
<= '9')
330 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
331 error ("Arguments must be memory region numbers.");
337 while (*p
== ' ' || *p
== '\t')
343 /* Disable the memory region number NUM. */
346 mem_disable (int num
)
348 struct mem_region
*m
;
350 for (m
= mem_region_chain
; m
; m
= m
->next
)
351 if (m
->number
== num
)
353 m
->status
= disabled
;
356 printf_unfiltered ("No memory region number %d.\n", num
);
360 mem_disable_command (char *args
, int from_tty
)
365 struct mem_region
*m
;
367 dcache_invalidate (target_dcache
);
371 for (m
= mem_region_chain
; m
; m
= m
->next
)
372 m
->status
= disabled
;
378 while (*p1
>= '0' && *p1
<= '9')
380 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
381 error ("Arguments must be memory region numbers.");
387 while (*p
== ' ' || *p
== '\t')
392 /* Clear memory region list */
397 struct mem_region
*m
;
399 while ((m
= mem_region_chain
) != 0)
401 mem_region_chain
= m
->next
;
402 delete_mem_region (m
);
406 /* Delete the memory region number NUM. */
411 struct mem_region
*m1
, *m
;
413 if (!mem_region_chain
)
415 printf_unfiltered ("No memory region number %d.\n", num
);
419 if (mem_region_chain
->number
== num
)
421 m1
= mem_region_chain
;
422 mem_region_chain
= m1
->next
;
423 delete_mem_region (m1
);
426 for (m
= mem_region_chain
; m
->next
; m
= m
->next
)
428 if (m
->next
->number
== num
)
432 delete_mem_region (m1
);
439 mem_delete_command (char *args
, int from_tty
)
445 dcache_invalidate (target_dcache
);
449 if (query ("Delete all memory regions? "))
458 while (*p1
>= '0' && *p1
<= '9')
460 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
461 error ("Arguments must be memory region numbers.");
467 while (*p
== ' ' || *p
== '\t')
477 add_com ("mem", class_vars
, mem_command
,
478 "Define attributes for memory region.");
480 add_cmd ("mem", class_vars
, mem_enable_command
,
481 "Enable memory region.\n\
482 Arguments are the code numbers of the memory regions to enable.\n\
483 Do \"info mem\" to see current list of code numbers.", &enablelist
);
485 add_cmd ("mem", class_vars
, mem_disable_command
,
486 "Disable memory region.\n\
487 Arguments are the code numbers of the memory regions to disable.\n\
488 Do \"info mem\" to see current list of code numbers.", &disablelist
);
490 add_cmd ("mem", class_vars
, mem_delete_command
,
491 "Delete memory region.\n\
492 Arguments are the code numbers of the memory regions to delete.\n\
493 Do \"info mem\" to see current list of code numbers.", &deletelist
);
495 add_info ("mem", mem_info_command
,
496 "Memory region attributes");