1b725ae77Skettenis /* Memory attributes support, for GDB.
2b725ae77Skettenis
3b725ae77Skettenis Copyright 2001, 2002 Free Software Foundation, Inc.
4b725ae77Skettenis
5b725ae77Skettenis This file is part of GDB.
6b725ae77Skettenis
7b725ae77Skettenis This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis it under the terms of the GNU General Public License as published by
9b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis (at your option) any later version.
11b725ae77Skettenis
12b725ae77Skettenis This program is distributed in the hope that it will be useful,
13b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15b725ae77Skettenis GNU General Public License for more details.
16b725ae77Skettenis
17b725ae77Skettenis You should have received a copy of the GNU General Public License
18b725ae77Skettenis along with this program; if not, write to the Free Software
19b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis Boston, MA 02111-1307, USA. */
21b725ae77Skettenis
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "command.h"
24b725ae77Skettenis #include "gdbcmd.h"
25b725ae77Skettenis #include "memattr.h"
26b725ae77Skettenis #include "target.h"
27b725ae77Skettenis #include "value.h"
28b725ae77Skettenis #include "language.h"
29b725ae77Skettenis #include "gdb_string.h"
30b725ae77Skettenis
31b725ae77Skettenis const struct mem_attrib default_mem_attrib =
32b725ae77Skettenis {
33b725ae77Skettenis MEM_RW, /* mode */
34b725ae77Skettenis MEM_WIDTH_UNSPECIFIED,
35b725ae77Skettenis 0, /* hwbreak */
36b725ae77Skettenis 0, /* cache */
37b725ae77Skettenis 0 /* verify */
38b725ae77Skettenis };
39b725ae77Skettenis
40b725ae77Skettenis static struct mem_region *mem_region_chain = NULL;
41b725ae77Skettenis static int mem_number = 0;
42b725ae77Skettenis
43b725ae77Skettenis static struct mem_region *
create_mem_region(CORE_ADDR lo,CORE_ADDR hi,const struct mem_attrib * attrib)44b725ae77Skettenis create_mem_region (CORE_ADDR lo, CORE_ADDR hi,
45b725ae77Skettenis const struct mem_attrib *attrib)
46b725ae77Skettenis {
47b725ae77Skettenis struct mem_region *n, *new;
48b725ae77Skettenis
49b725ae77Skettenis /* lo == hi is a useless empty region */
50b725ae77Skettenis if (lo >= hi && hi != 0)
51b725ae77Skettenis {
52b725ae77Skettenis printf_unfiltered ("invalid memory region: low >= high\n");
53b725ae77Skettenis return NULL;
54b725ae77Skettenis }
55b725ae77Skettenis
56b725ae77Skettenis n = mem_region_chain;
57b725ae77Skettenis while (n)
58b725ae77Skettenis {
59b725ae77Skettenis /* overlapping node */
60b725ae77Skettenis if ((lo >= n->lo && (lo < n->hi || n->hi == 0))
61b725ae77Skettenis || (hi > n->lo && (hi <= n->hi || n->hi == 0))
62b725ae77Skettenis || (lo <= n->lo && (hi >= n->hi || hi == 0)))
63b725ae77Skettenis {
64b725ae77Skettenis printf_unfiltered ("overlapping memory region\n");
65b725ae77Skettenis return NULL;
66b725ae77Skettenis }
67b725ae77Skettenis n = n->next;
68b725ae77Skettenis }
69b725ae77Skettenis
70b725ae77Skettenis new = xmalloc (sizeof (struct mem_region));
71b725ae77Skettenis new->lo = lo;
72b725ae77Skettenis new->hi = hi;
73b725ae77Skettenis new->number = ++mem_number;
74b725ae77Skettenis new->enabled_p = 1;
75b725ae77Skettenis new->attrib = *attrib;
76b725ae77Skettenis
77b725ae77Skettenis /* link in new node */
78b725ae77Skettenis new->next = mem_region_chain;
79b725ae77Skettenis mem_region_chain = new;
80b725ae77Skettenis
81b725ae77Skettenis return new;
82b725ae77Skettenis }
83b725ae77Skettenis
84b725ae77Skettenis static void
delete_mem_region(struct mem_region * m)85b725ae77Skettenis delete_mem_region (struct mem_region *m)
86b725ae77Skettenis {
87b725ae77Skettenis xfree (m);
88b725ae77Skettenis }
89b725ae77Skettenis
90b725ae77Skettenis /*
91b725ae77Skettenis * Look up the memory region cooresponding to ADDR.
92b725ae77Skettenis */
93b725ae77Skettenis struct mem_region *
lookup_mem_region(CORE_ADDR addr)94b725ae77Skettenis lookup_mem_region (CORE_ADDR addr)
95b725ae77Skettenis {
96b725ae77Skettenis static struct mem_region region;
97b725ae77Skettenis struct mem_region *m;
98b725ae77Skettenis CORE_ADDR lo;
99b725ae77Skettenis CORE_ADDR hi;
100b725ae77Skettenis
101b725ae77Skettenis /* First we initialize LO and HI so that they describe the entire
102b725ae77Skettenis memory space. As we process the memory region chain, they are
103b725ae77Skettenis redefined to describe the minimal region containing ADDR. LO
104b725ae77Skettenis and HI are used in the case where no memory region is defined
105b725ae77Skettenis that contains ADDR. If a memory region is disabled, it is
106b725ae77Skettenis treated as if it does not exist. */
107b725ae77Skettenis
108b725ae77Skettenis lo = (CORE_ADDR) 0;
109b725ae77Skettenis hi = (CORE_ADDR) ~ 0;
110b725ae77Skettenis
111b725ae77Skettenis for (m = mem_region_chain; m; m = m->next)
112b725ae77Skettenis {
113b725ae77Skettenis if (m->enabled_p == 1)
114b725ae77Skettenis {
115b725ae77Skettenis if (addr >= m->lo && (addr < m->hi || m->hi == 0))
116b725ae77Skettenis return m;
117b725ae77Skettenis
118b725ae77Skettenis if (addr >= m->hi && lo < m->hi)
119b725ae77Skettenis lo = m->hi;
120b725ae77Skettenis
121b725ae77Skettenis if (addr <= m->lo && hi > m->lo)
122b725ae77Skettenis hi = m->lo;
123b725ae77Skettenis }
124b725ae77Skettenis }
125b725ae77Skettenis
126b725ae77Skettenis /* Because no region was found, we must cons up one based on what
127b725ae77Skettenis was learned above. */
128b725ae77Skettenis region.lo = lo;
129b725ae77Skettenis region.hi = hi;
130b725ae77Skettenis region.attrib = default_mem_attrib;
131b725ae77Skettenis return ®ion;
132b725ae77Skettenis }
133b725ae77Skettenis
134b725ae77Skettenis
135b725ae77Skettenis static void
mem_command(char * args,int from_tty)136b725ae77Skettenis mem_command (char *args, int from_tty)
137b725ae77Skettenis {
138b725ae77Skettenis CORE_ADDR lo, hi;
139b725ae77Skettenis char *tok;
140b725ae77Skettenis struct mem_attrib attrib;
141b725ae77Skettenis
142b725ae77Skettenis if (!args)
143b725ae77Skettenis error_no_arg ("No mem");
144b725ae77Skettenis
145b725ae77Skettenis tok = strtok (args, " \t");
146b725ae77Skettenis if (!tok)
147b725ae77Skettenis error ("no lo address");
148b725ae77Skettenis lo = parse_and_eval_address (tok);
149b725ae77Skettenis
150b725ae77Skettenis tok = strtok (NULL, " \t");
151b725ae77Skettenis if (!tok)
152b725ae77Skettenis error ("no hi address");
153b725ae77Skettenis hi = parse_and_eval_address (tok);
154b725ae77Skettenis
155b725ae77Skettenis attrib = default_mem_attrib;
156b725ae77Skettenis while ((tok = strtok (NULL, " \t")) != NULL)
157b725ae77Skettenis {
158b725ae77Skettenis if (strcmp (tok, "rw") == 0)
159b725ae77Skettenis attrib.mode = MEM_RW;
160b725ae77Skettenis else if (strcmp (tok, "ro") == 0)
161b725ae77Skettenis attrib.mode = MEM_RO;
162b725ae77Skettenis else if (strcmp (tok, "wo") == 0)
163b725ae77Skettenis attrib.mode = MEM_WO;
164b725ae77Skettenis
165b725ae77Skettenis else if (strcmp (tok, "8") == 0)
166b725ae77Skettenis attrib.width = MEM_WIDTH_8;
167b725ae77Skettenis else if (strcmp (tok, "16") == 0)
168b725ae77Skettenis {
169b725ae77Skettenis if ((lo % 2 != 0) || (hi % 2 != 0))
170b725ae77Skettenis error ("region bounds not 16 bit aligned");
171b725ae77Skettenis attrib.width = MEM_WIDTH_16;
172b725ae77Skettenis }
173b725ae77Skettenis else if (strcmp (tok, "32") == 0)
174b725ae77Skettenis {
175b725ae77Skettenis if ((lo % 4 != 0) || (hi % 4 != 0))
176b725ae77Skettenis error ("region bounds not 32 bit aligned");
177b725ae77Skettenis attrib.width = MEM_WIDTH_32;
178b725ae77Skettenis }
179b725ae77Skettenis else if (strcmp (tok, "64") == 0)
180b725ae77Skettenis {
181b725ae77Skettenis if ((lo % 8 != 0) || (hi % 8 != 0))
182b725ae77Skettenis error ("region bounds not 64 bit aligned");
183b725ae77Skettenis attrib.width = MEM_WIDTH_64;
184b725ae77Skettenis }
185b725ae77Skettenis
186b725ae77Skettenis #if 0
187b725ae77Skettenis else if (strcmp (tok, "hwbreak") == 0)
188b725ae77Skettenis attrib.hwbreak = 1;
189b725ae77Skettenis else if (strcmp (tok, "swbreak") == 0)
190b725ae77Skettenis attrib.hwbreak = 0;
191b725ae77Skettenis #endif
192b725ae77Skettenis
193b725ae77Skettenis else if (strcmp (tok, "cache") == 0)
194b725ae77Skettenis attrib.cache = 1;
195b725ae77Skettenis else if (strcmp (tok, "nocache") == 0)
196b725ae77Skettenis attrib.cache = 0;
197b725ae77Skettenis
198b725ae77Skettenis #if 0
199b725ae77Skettenis else if (strcmp (tok, "verify") == 0)
200b725ae77Skettenis attrib.verify = 1;
201b725ae77Skettenis else if (strcmp (tok, "noverify") == 0)
202b725ae77Skettenis attrib.verify = 0;
203b725ae77Skettenis #endif
204b725ae77Skettenis
205b725ae77Skettenis else
206b725ae77Skettenis error ("unknown attribute: %s", tok);
207b725ae77Skettenis }
208b725ae77Skettenis
209b725ae77Skettenis create_mem_region (lo, hi, &attrib);
210b725ae77Skettenis }
211b725ae77Skettenis
212b725ae77Skettenis
213b725ae77Skettenis static void
mem_info_command(char * args,int from_tty)214b725ae77Skettenis mem_info_command (char *args, int from_tty)
215b725ae77Skettenis {
216b725ae77Skettenis struct mem_region *m;
217b725ae77Skettenis struct mem_attrib *attrib;
218b725ae77Skettenis
219b725ae77Skettenis if (!mem_region_chain)
220b725ae77Skettenis {
221b725ae77Skettenis printf_unfiltered ("There are no memory regions defined.\n");
222b725ae77Skettenis return;
223b725ae77Skettenis }
224b725ae77Skettenis
225b725ae77Skettenis printf_filtered ("Num ");
226b725ae77Skettenis printf_filtered ("Enb ");
227b725ae77Skettenis printf_filtered ("Low Addr ");
228b725ae77Skettenis if (TARGET_ADDR_BIT > 32)
229b725ae77Skettenis printf_filtered (" ");
230b725ae77Skettenis printf_filtered ("High Addr ");
231b725ae77Skettenis if (TARGET_ADDR_BIT > 32)
232b725ae77Skettenis printf_filtered (" ");
233b725ae77Skettenis printf_filtered ("Attrs ");
234b725ae77Skettenis printf_filtered ("\n");
235b725ae77Skettenis
236b725ae77Skettenis for (m = mem_region_chain; m; m = m->next)
237b725ae77Skettenis {
238b725ae77Skettenis char *tmp;
239b725ae77Skettenis printf_filtered ("%-3d %-3c\t",
240b725ae77Skettenis m->number,
241b725ae77Skettenis m->enabled_p ? 'y' : 'n');
242b725ae77Skettenis if (TARGET_ADDR_BIT <= 32)
243*11efff7fSkettenis tmp = hex_string_custom ((unsigned long) m->lo, 8);
244b725ae77Skettenis else
245*11efff7fSkettenis tmp = hex_string_custom ((unsigned long) m->lo, 16);
246b725ae77Skettenis
247b725ae77Skettenis printf_filtered ("%s ", tmp);
248b725ae77Skettenis
249b725ae77Skettenis if (TARGET_ADDR_BIT <= 32)
250b725ae77Skettenis {
251b725ae77Skettenis if (m->hi == 0)
252b725ae77Skettenis tmp = "0x100000000";
253b725ae77Skettenis else
254*11efff7fSkettenis tmp = hex_string_custom ((unsigned long) m->hi, 8);
255b725ae77Skettenis }
256b725ae77Skettenis else
257b725ae77Skettenis {
258b725ae77Skettenis if (m->hi == 0)
259b725ae77Skettenis tmp = "0x10000000000000000";
260b725ae77Skettenis else
261*11efff7fSkettenis tmp = hex_string_custom ((unsigned long) m->hi, 16);
262b725ae77Skettenis }
263b725ae77Skettenis
264b725ae77Skettenis printf_filtered ("%s ", tmp);
265b725ae77Skettenis
266b725ae77Skettenis /* Print a token for each attribute.
267b725ae77Skettenis
268b725ae77Skettenis * FIXME: Should we output a comma after each token? It may
269b725ae77Skettenis * make it easier for users to read, but we'd lose the ability
270b725ae77Skettenis * to cut-and-paste the list of attributes when defining a new
271b725ae77Skettenis * region. Perhaps that is not important.
272b725ae77Skettenis *
273b725ae77Skettenis * FIXME: If more attributes are added to GDB, the output may
274b725ae77Skettenis * become cluttered and difficult for users to read. At that
275b725ae77Skettenis * time, we may want to consider printing tokens only if they
276b725ae77Skettenis * are different from the default attribute. */
277b725ae77Skettenis
278b725ae77Skettenis attrib = &m->attrib;
279b725ae77Skettenis switch (attrib->mode)
280b725ae77Skettenis {
281b725ae77Skettenis case MEM_RW:
282b725ae77Skettenis printf_filtered ("rw ");
283b725ae77Skettenis break;
284b725ae77Skettenis case MEM_RO:
285b725ae77Skettenis printf_filtered ("ro ");
286b725ae77Skettenis break;
287b725ae77Skettenis case MEM_WO:
288b725ae77Skettenis printf_filtered ("wo ");
289b725ae77Skettenis break;
290b725ae77Skettenis }
291b725ae77Skettenis
292b725ae77Skettenis switch (attrib->width)
293b725ae77Skettenis {
294b725ae77Skettenis case MEM_WIDTH_8:
295b725ae77Skettenis printf_filtered ("8 ");
296b725ae77Skettenis break;
297b725ae77Skettenis case MEM_WIDTH_16:
298b725ae77Skettenis printf_filtered ("16 ");
299b725ae77Skettenis break;
300b725ae77Skettenis case MEM_WIDTH_32:
301b725ae77Skettenis printf_filtered ("32 ");
302b725ae77Skettenis break;
303b725ae77Skettenis case MEM_WIDTH_64:
304b725ae77Skettenis printf_filtered ("64 ");
305b725ae77Skettenis break;
306b725ae77Skettenis case MEM_WIDTH_UNSPECIFIED:
307b725ae77Skettenis break;
308b725ae77Skettenis }
309b725ae77Skettenis
310b725ae77Skettenis #if 0
311b725ae77Skettenis if (attrib->hwbreak)
312b725ae77Skettenis printf_filtered ("hwbreak");
313b725ae77Skettenis else
314b725ae77Skettenis printf_filtered ("swbreak");
315b725ae77Skettenis #endif
316b725ae77Skettenis
317b725ae77Skettenis if (attrib->cache)
318b725ae77Skettenis printf_filtered ("cache ");
319b725ae77Skettenis else
320b725ae77Skettenis printf_filtered ("nocache ");
321b725ae77Skettenis
322b725ae77Skettenis #if 0
323b725ae77Skettenis if (attrib->verify)
324b725ae77Skettenis printf_filtered ("verify ");
325b725ae77Skettenis else
326b725ae77Skettenis printf_filtered ("noverify ");
327b725ae77Skettenis #endif
328b725ae77Skettenis
329b725ae77Skettenis printf_filtered ("\n");
330b725ae77Skettenis
331b725ae77Skettenis gdb_flush (gdb_stdout);
332b725ae77Skettenis }
333b725ae77Skettenis }
334b725ae77Skettenis
335b725ae77Skettenis
336b725ae77Skettenis /* Enable the memory region number NUM. */
337b725ae77Skettenis
338b725ae77Skettenis static void
mem_enable(int num)339b725ae77Skettenis mem_enable (int num)
340b725ae77Skettenis {
341b725ae77Skettenis struct mem_region *m;
342b725ae77Skettenis
343b725ae77Skettenis for (m = mem_region_chain; m; m = m->next)
344b725ae77Skettenis if (m->number == num)
345b725ae77Skettenis {
346b725ae77Skettenis m->enabled_p = 1;
347b725ae77Skettenis return;
348b725ae77Skettenis }
349b725ae77Skettenis printf_unfiltered ("No memory region number %d.\n", num);
350b725ae77Skettenis }
351b725ae77Skettenis
352b725ae77Skettenis static void
mem_enable_command(char * args,int from_tty)353b725ae77Skettenis mem_enable_command (char *args, int from_tty)
354b725ae77Skettenis {
355b725ae77Skettenis char *p = args;
356b725ae77Skettenis char *p1;
357b725ae77Skettenis int num;
358b725ae77Skettenis struct mem_region *m;
359b725ae77Skettenis
360b725ae77Skettenis dcache_invalidate (target_dcache);
361b725ae77Skettenis
362b725ae77Skettenis if (p == 0)
363b725ae77Skettenis {
364b725ae77Skettenis for (m = mem_region_chain; m; m = m->next)
365b725ae77Skettenis m->enabled_p = 1;
366b725ae77Skettenis }
367b725ae77Skettenis else
368b725ae77Skettenis while (*p)
369b725ae77Skettenis {
370b725ae77Skettenis p1 = p;
371b725ae77Skettenis while (*p1 >= '0' && *p1 <= '9')
372b725ae77Skettenis p1++;
373b725ae77Skettenis if (*p1 && *p1 != ' ' && *p1 != '\t')
374b725ae77Skettenis error ("Arguments must be memory region numbers.");
375b725ae77Skettenis
376b725ae77Skettenis num = atoi (p);
377b725ae77Skettenis mem_enable (num);
378b725ae77Skettenis
379b725ae77Skettenis p = p1;
380b725ae77Skettenis while (*p == ' ' || *p == '\t')
381b725ae77Skettenis p++;
382b725ae77Skettenis }
383b725ae77Skettenis }
384b725ae77Skettenis
385b725ae77Skettenis
386b725ae77Skettenis /* Disable the memory region number NUM. */
387b725ae77Skettenis
388b725ae77Skettenis static void
mem_disable(int num)389b725ae77Skettenis mem_disable (int num)
390b725ae77Skettenis {
391b725ae77Skettenis struct mem_region *m;
392b725ae77Skettenis
393b725ae77Skettenis for (m = mem_region_chain; m; m = m->next)
394b725ae77Skettenis if (m->number == num)
395b725ae77Skettenis {
396b725ae77Skettenis m->enabled_p = 0;
397b725ae77Skettenis return;
398b725ae77Skettenis }
399b725ae77Skettenis printf_unfiltered ("No memory region number %d.\n", num);
400b725ae77Skettenis }
401b725ae77Skettenis
402b725ae77Skettenis static void
mem_disable_command(char * args,int from_tty)403b725ae77Skettenis mem_disable_command (char *args, int from_tty)
404b725ae77Skettenis {
405b725ae77Skettenis char *p = args;
406b725ae77Skettenis char *p1;
407b725ae77Skettenis int num;
408b725ae77Skettenis struct mem_region *m;
409b725ae77Skettenis
410b725ae77Skettenis dcache_invalidate (target_dcache);
411b725ae77Skettenis
412b725ae77Skettenis if (p == 0)
413b725ae77Skettenis {
414b725ae77Skettenis for (m = mem_region_chain; m; m = m->next)
415b725ae77Skettenis m->enabled_p = 0;
416b725ae77Skettenis }
417b725ae77Skettenis else
418b725ae77Skettenis while (*p)
419b725ae77Skettenis {
420b725ae77Skettenis p1 = p;
421b725ae77Skettenis while (*p1 >= '0' && *p1 <= '9')
422b725ae77Skettenis p1++;
423b725ae77Skettenis if (*p1 && *p1 != ' ' && *p1 != '\t')
424b725ae77Skettenis error ("Arguments must be memory region numbers.");
425b725ae77Skettenis
426b725ae77Skettenis num = atoi (p);
427b725ae77Skettenis mem_disable (num);
428b725ae77Skettenis
429b725ae77Skettenis p = p1;
430b725ae77Skettenis while (*p == ' ' || *p == '\t')
431b725ae77Skettenis p++;
432b725ae77Skettenis }
433b725ae77Skettenis }
434b725ae77Skettenis
435b725ae77Skettenis /* Clear memory region list */
436b725ae77Skettenis
437b725ae77Skettenis static void
mem_clear(void)438b725ae77Skettenis mem_clear (void)
439b725ae77Skettenis {
440b725ae77Skettenis struct mem_region *m;
441b725ae77Skettenis
442b725ae77Skettenis while ((m = mem_region_chain) != 0)
443b725ae77Skettenis {
444b725ae77Skettenis mem_region_chain = m->next;
445b725ae77Skettenis delete_mem_region (m);
446b725ae77Skettenis }
447b725ae77Skettenis }
448b725ae77Skettenis
449b725ae77Skettenis /* Delete the memory region number NUM. */
450b725ae77Skettenis
451b725ae77Skettenis static void
mem_delete(int num)452b725ae77Skettenis mem_delete (int num)
453b725ae77Skettenis {
454b725ae77Skettenis struct mem_region *m1, *m;
455b725ae77Skettenis
456b725ae77Skettenis if (!mem_region_chain)
457b725ae77Skettenis {
458b725ae77Skettenis printf_unfiltered ("No memory region number %d.\n", num);
459b725ae77Skettenis return;
460b725ae77Skettenis }
461b725ae77Skettenis
462b725ae77Skettenis if (mem_region_chain->number == num)
463b725ae77Skettenis {
464b725ae77Skettenis m1 = mem_region_chain;
465b725ae77Skettenis mem_region_chain = m1->next;
466b725ae77Skettenis delete_mem_region (m1);
467b725ae77Skettenis }
468b725ae77Skettenis else
469b725ae77Skettenis for (m = mem_region_chain; m->next; m = m->next)
470b725ae77Skettenis {
471b725ae77Skettenis if (m->next->number == num)
472b725ae77Skettenis {
473b725ae77Skettenis m1 = m->next;
474b725ae77Skettenis m->next = m1->next;
475b725ae77Skettenis delete_mem_region (m1);
476b725ae77Skettenis break;
477b725ae77Skettenis }
478b725ae77Skettenis }
479b725ae77Skettenis }
480b725ae77Skettenis
481b725ae77Skettenis static void
mem_delete_command(char * args,int from_tty)482b725ae77Skettenis mem_delete_command (char *args, int from_tty)
483b725ae77Skettenis {
484b725ae77Skettenis char *p = args;
485b725ae77Skettenis char *p1;
486b725ae77Skettenis int num;
487b725ae77Skettenis
488b725ae77Skettenis dcache_invalidate (target_dcache);
489b725ae77Skettenis
490b725ae77Skettenis if (p == 0)
491b725ae77Skettenis {
492b725ae77Skettenis if (query ("Delete all memory regions? "))
493b725ae77Skettenis mem_clear ();
494b725ae77Skettenis dont_repeat ();
495b725ae77Skettenis return;
496b725ae77Skettenis }
497b725ae77Skettenis
498b725ae77Skettenis while (*p)
499b725ae77Skettenis {
500b725ae77Skettenis p1 = p;
501b725ae77Skettenis while (*p1 >= '0' && *p1 <= '9')
502b725ae77Skettenis p1++;
503b725ae77Skettenis if (*p1 && *p1 != ' ' && *p1 != '\t')
504b725ae77Skettenis error ("Arguments must be memory region numbers.");
505b725ae77Skettenis
506b725ae77Skettenis num = atoi (p);
507b725ae77Skettenis mem_delete (num);
508b725ae77Skettenis
509b725ae77Skettenis p = p1;
510b725ae77Skettenis while (*p == ' ' || *p == '\t')
511b725ae77Skettenis p++;
512b725ae77Skettenis }
513b725ae77Skettenis
514b725ae77Skettenis dont_repeat ();
515b725ae77Skettenis }
516b725ae77Skettenis
517b725ae77Skettenis extern initialize_file_ftype _initialize_mem; /* -Wmissing-prototype */
518b725ae77Skettenis
519b725ae77Skettenis void
_initialize_mem(void)520b725ae77Skettenis _initialize_mem (void)
521b725ae77Skettenis {
522b725ae77Skettenis add_com ("mem", class_vars, mem_command,
523b725ae77Skettenis "Define attributes for memory region.\n\
524b725ae77Skettenis Usage: mem <lo addr> <hi addr> [<mode> <width> <cache>], \n\
525b725ae77Skettenis where <mode> may be rw (read/write), ro (read-only) or wo (write-only), \n\
526b725ae77Skettenis <width> may be 8, 16, 32, or 64, and \n\
527b725ae77Skettenis <cache> may be cache or nocache");
528b725ae77Skettenis
529b725ae77Skettenis add_cmd ("mem", class_vars, mem_enable_command,
530b725ae77Skettenis "Enable memory region.\n\
531b725ae77Skettenis Arguments are the code numbers of the memory regions to enable.\n\
532b725ae77Skettenis Usage: enable mem <code number>\n\
533b725ae77Skettenis Do \"info mem\" to see current list of code numbers.", &enablelist);
534b725ae77Skettenis
535b725ae77Skettenis add_cmd ("mem", class_vars, mem_disable_command,
536b725ae77Skettenis "Disable memory region.\n\
537b725ae77Skettenis Arguments are the code numbers of the memory regions to disable.\n\
538b725ae77Skettenis Usage: disable mem <code number>\n\
539b725ae77Skettenis Do \"info mem\" to see current list of code numbers.", &disablelist);
540b725ae77Skettenis
541b725ae77Skettenis add_cmd ("mem", class_vars, mem_delete_command,
542b725ae77Skettenis "Delete memory region.\n\
543b725ae77Skettenis Arguments are the code numbers of the memory regions to delete.\n\
544b725ae77Skettenis Usage: delete mem <code number>\n\
545b725ae77Skettenis Do \"info mem\" to see current list of code numbers.", &deletelist);
546b725ae77Skettenis
547b725ae77Skettenis add_info ("mem", mem_info_command,
548b725ae77Skettenis "Memory region attributes");
549b725ae77Skettenis }
550