OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [memattr.c] - Blame information for rev 1775

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.