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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [sim/] [common/] [sim-memopt.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* Simulator memory option handling.
2
   Copyright (C) 1996-1999 Free Software Foundation, Inc.
3
   Contributed by Cygnus Support.
4
 
5
This file is part of GDB, the GNU debugger.
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, or (at your option)
10
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 along
18
with this program; if not, write to the Free Software Foundation, Inc.,
19
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "sim-main.h"
22
#include "sim-assert.h"
23
#include "sim-options.h"
24
 
25
#ifdef HAVE_STRING_H
26
#include <string.h>
27
#else
28
#ifdef HAVE_STRINGS_H
29
#include <strings.h>
30
#endif
31
#endif
32
#ifdef HAVE_STDLIB_H
33
#include <stdlib.h>
34
#endif
35
 
36
/* Memory fill byte */
37
static unsigned8 fill_byte_value;
38
static int fill_byte_flag = 0;
39
 
40
/* Memory command line options. */
41
 
42
enum {
43
  OPTION_MEMORY_DELETE = OPTION_START,
44
  OPTION_MEMORY_REGION,
45
  OPTION_MEMORY_SIZE,
46
  OPTION_MEMORY_INFO,
47
  OPTION_MEMORY_ALIAS,
48
  OPTION_MEMORY_CLEAR,
49
  OPTION_MEMORY_FILL
50
};
51
 
52
static DECLARE_OPTION_HANDLER (memory_option_handler);
53
 
54
static const OPTION memory_options[] =
55
{
56
  { {"memory-delete", required_argument, NULL, OPTION_MEMORY_DELETE },
57
      '\0', "ADDRESS|all", "Delete memory at ADDRESS (all addresses)",
58
      memory_option_handler },
59
  { {"delete-memory", required_argument, NULL, OPTION_MEMORY_DELETE },
60
      '\0', "ADDRESS", NULL,
61
      memory_option_handler },
62
 
63
  { {"memory-region", required_argument, NULL, OPTION_MEMORY_REGION },
64
      '\0', "ADDRESS,SIZE[,MODULO]", "Add a memory region",
65
      memory_option_handler },
66
 
67
  { {"memory-alias", required_argument, NULL, OPTION_MEMORY_ALIAS },
68
      '\0', "ADDRESS,SIZE{,ADDRESS}", "Add memory shadow",
69
      memory_option_handler },
70
 
71
  { {"memory-size", required_argument, NULL, OPTION_MEMORY_SIZE },
72
      '\0', "SIZE", "Add memory at address zero",
73
      memory_option_handler },
74
 
75
  { {"memory-fill", required_argument, NULL, OPTION_MEMORY_FILL },
76
      '\0', "VALUE", "Fill subsequently added memory regions",
77
      memory_option_handler },
78
 
79
  { {"memory-clear", no_argument, NULL, OPTION_MEMORY_CLEAR },
80
      '\0', NULL, "Clear subsequently added memory regions",
81
      memory_option_handler },
82
 
83
  { {"memory-info", no_argument, NULL, OPTION_MEMORY_INFO },
84
      '\0', NULL, "List configurable memory regions",
85
      memory_option_handler },
86
  { {"info-memory", no_argument, NULL, OPTION_MEMORY_INFO },
87
      '\0', NULL, NULL,
88
      memory_option_handler },
89
 
90
  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
91
};
92
 
93
 
94
static sim_memopt *
95
do_memopt_add (SIM_DESC sd,
96
               int level,
97
               int space,
98
               address_word addr,
99
               address_word nr_bytes,
100
               unsigned modulo,
101
               sim_memopt **entry,
102
               void *buffer)
103
{
104
  void *fill_buffer;
105
  unsigned fill_length;
106
  void *free_buffer;
107
 
108
  if (buffer != NULL)
109
    {
110
      /* Buffer already given.  sim_memory_uninstall will free it. */
111
      sim_core_attach (sd, NULL,
112
                       level, access_read_write_exec, space,
113
                       addr, nr_bytes, modulo, NULL, buffer);
114
 
115
      free_buffer = buffer;
116
      fill_buffer = buffer;
117
      fill_length = (modulo == 0) ? nr_bytes : modulo;
118
    }
119
  else
120
    {
121
      /* Allocate new well-aligned buffer, just as sim_core_attach(). */
122
      void *aligned_buffer;
123
      int padding = (addr % sizeof (unsigned64));
124
      unsigned long bytes = (modulo == 0 ? nr_bytes : modulo) + padding;
125
 
126
      /* If filling with non-zero value, do not use clearing allocator. */
127
 
128
      if (fill_byte_flag && fill_byte_value != 0)
129
        free_buffer = xmalloc (bytes); /* don't clear */
130
      else
131
        free_buffer = zalloc (bytes); /* clear */
132
 
133
      aligned_buffer = (char*) free_buffer + padding;
134
 
135
      sim_core_attach (sd, NULL,
136
                       level, access_read_write_exec, space,
137
                       addr, nr_bytes, modulo, NULL, aligned_buffer);
138
 
139
      fill_buffer = aligned_buffer;
140
      fill_length = (modulo == 0) ? nr_bytes : modulo;
141
 
142
      /* If we just used a clearing allocator, and are about to fill with
143
         zero, truncate the redundant fill operation. */
144
 
145
      if (fill_byte_flag && fill_byte_value == 0)
146
         fill_length = 1; /* avoid boundary length=0 case */
147
    }
148
 
149
  if (fill_byte_flag)
150
    {
151
      ASSERT (fill_buffer != 0);
152
      memset ((char*) fill_buffer, fill_byte_value, fill_length);
153
    }
154
 
155
  while ((*entry) != NULL)
156
    entry = &(*entry)->next;
157
  (*entry) = ZALLOC (sim_memopt);
158
  (*entry)->level = level;
159
  (*entry)->space = space;
160
  (*entry)->addr = addr;
161
  (*entry)->nr_bytes = nr_bytes;
162
  (*entry)->modulo = modulo;
163
  (*entry)->buffer = free_buffer;
164
 
165
  return (*entry);
166
}
167
 
168
static SIM_RC
169
do_memopt_delete (SIM_DESC sd,
170
                  int level,
171
                  int space,
172
                  address_word addr)
173
{
174
  sim_memopt **entry = &STATE_MEMOPT (sd);
175
  sim_memopt *alias;
176
  while ((*entry) != NULL
177
         && ((*entry)->level != level
178
              || (*entry)->space != space
179
              || (*entry)->addr != addr))
180
    entry = &(*entry)->next;
181
  if ((*entry) == NULL)
182
    {
183
      sim_io_eprintf (sd, "Memory at 0x%lx not found, not deleted\n",
184
                      (long) addr);
185
      return SIM_RC_FAIL;
186
    }
187
  /* delete any buffer */
188
  if ((*entry)->buffer != NULL)
189
    zfree ((*entry)->buffer);
190
  /* delete it and its aliases */
191
  alias = *entry;
192
  *entry = (*entry)->next;
193
  while (alias != NULL)
194
    {
195
      sim_memopt *dead = alias;
196
      alias = alias->alias;
197
      sim_core_detach (sd, NULL, dead->level, dead->space, dead->addr);
198
      zfree (dead);
199
    }
200
  return SIM_RC_OK;
201
}
202
 
203
 
204
static char *
205
parse_size (char *chp,
206
            address_word *nr_bytes,
207
            unsigned *modulo)
208
{
209
  /* <nr_bytes> [ "%" <modulo> ] */
210
  *nr_bytes = strtoul (chp, &chp, 0);
211
  if (*chp == '%')
212
    {
213
      *modulo = strtoul (chp + 1, &chp, 0);
214
    }
215
  return chp;
216
}
217
 
218
static char *
219
parse_ulong_value (char *chp,
220
                     unsigned long *value)
221
{
222
  *value = strtoul (chp, &chp, 0);
223
  return chp;
224
}
225
 
226
static char *
227
parse_addr (char *chp,
228
            int *level,
229
            int *space,
230
            address_word *addr)
231
{
232
  /* [ <space> ": " ] <addr> [ "@" <level> ] */
233
  *addr = (unsigned long) strtoul (chp, &chp, 0);
234
  if (*chp == ':')
235
    {
236
      *space = *addr;
237
      *addr = (unsigned long) strtoul (chp + 1, &chp, 0);
238
    }
239
  if (*chp == '@')
240
    {
241
      *level = strtoul (chp + 1, &chp, 0);
242
    }
243
  return chp;
244
}
245
 
246
 
247
static SIM_RC
248
memory_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
249
                       char *arg, int is_command)
250
{
251
  switch (opt)
252
    {
253
 
254
    case OPTION_MEMORY_DELETE:
255
      if (strcasecmp (arg, "all") == 0)
256
        {
257
          while (STATE_MEMOPT (sd) != NULL)
258
            do_memopt_delete (sd,
259
                              STATE_MEMOPT (sd)->level,
260
                              STATE_MEMOPT (sd)->space,
261
                              STATE_MEMOPT (sd)->addr);
262
          return SIM_RC_OK;
263
        }
264
      else
265
        {
266
          int level = 0;
267
          int space = 0;
268
          address_word addr = 0;
269
          parse_addr (arg, &level, &space, &addr);
270
          return do_memopt_delete (sd, level, space, addr);
271
        }
272
 
273
    case OPTION_MEMORY_REGION:
274
      {
275
        char *chp = arg;
276
        int level = 0;
277
        int space = 0;
278
        address_word addr = 0;
279
        address_word nr_bytes = 0;
280
        unsigned modulo = 0;
281
        /* parse the arguments */
282
        chp = parse_addr (chp, &level, &space, &addr);
283
        if (*chp != ',')
284
          {
285
            sim_io_eprintf (sd, "Missing size for memory-region\n");
286
            return SIM_RC_FAIL;
287
          }
288
        chp = parse_size (chp + 1, &nr_bytes, &modulo);
289
        /* old style */
290
        if (*chp == ',')
291
          modulo = strtoul (chp + 1, &chp, 0);
292
        /* try to attach/insert it */
293
        do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
294
                       &STATE_MEMOPT (sd), NULL);
295
        return SIM_RC_OK;
296
      }
297
 
298
    case OPTION_MEMORY_ALIAS:
299
      {
300
        char *chp = arg;
301
        int level = 0;
302
        int space = 0;
303
        address_word addr = 0;
304
        address_word nr_bytes = 0;
305
        unsigned modulo = 0;
306
        sim_memopt *entry;
307
        /* parse the arguments */
308
        chp = parse_addr (chp, &level, &space, &addr);
309
        if (*chp != ',')
310
          {
311
            sim_io_eprintf (sd, "Missing size for memory-region\n");
312
            return SIM_RC_FAIL;
313
          }
314
        chp = parse_size (chp + 1, &nr_bytes, &modulo);
315
        /* try to attach/insert the main record */
316
        entry = do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
317
                               &STATE_MEMOPT (sd),
318
                               NULL);
319
        /* now attach all the aliases */
320
        while (*chp == ',')
321
          {
322
            int a_level = level;
323
            int a_space = space;
324
            address_word a_addr = addr;
325
            chp = parse_addr (chp + 1, &a_level, &a_space, &a_addr);
326
            do_memopt_add (sd, a_level, a_space, a_addr, nr_bytes, modulo,
327
                           &entry->alias, entry->buffer);
328
          }
329
        return SIM_RC_OK;
330
      }
331
 
332
    case OPTION_MEMORY_SIZE:
333
      {
334
        int level = 0;
335
        int space = 0;
336
        address_word addr = 0;
337
        address_word nr_bytes = 0;
338
        unsigned modulo = 0;
339
        /* parse the arguments */
340
        parse_size (arg, &nr_bytes, &modulo);
341
        /* try to attach/insert it */
342
        do_memopt_add (sd, level, space, addr, nr_bytes, modulo,
343
                       &STATE_MEMOPT (sd), NULL);
344
        return SIM_RC_OK;
345
      }
346
 
347
    case OPTION_MEMORY_CLEAR:
348
      {
349
        fill_byte_value = (unsigned8) 0;
350
        fill_byte_flag = 1;
351
        return SIM_RC_OK;
352
        break;
353
      }
354
 
355
    case OPTION_MEMORY_FILL:
356
      {
357
        unsigned long fill_value;
358
        parse_ulong_value (arg, &fill_value);
359
        if (fill_value > 255)
360
          {
361
            sim_io_eprintf (sd, "Missing fill value between 0 and 255\n");
362
            return SIM_RC_FAIL;
363
          }
364
        fill_byte_value = (unsigned8) fill_value;
365
        fill_byte_flag = 1;
366
        return SIM_RC_OK;
367
        break;
368
      }
369
 
370
    case OPTION_MEMORY_INFO:
371
      {
372
        sim_memopt *entry;
373
        sim_io_printf (sd, "Memory maps:\n");
374
        for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
375
          {
376
            sim_memopt *alias;
377
            sim_io_printf (sd, " memory");
378
            if (entry->alias == NULL)
379
              sim_io_printf (sd, " region ");
380
            else
381
              sim_io_printf (sd, " alias ");
382
            if (entry->space != 0)
383
              sim_io_printf (sd, "0x%lx:", (long) entry->space);
384
            sim_io_printf (sd, "0x%08lx", (long) entry->addr);
385
            if (entry->level != 0)
386
              sim_io_printf (sd, "@0x%lx", (long) entry->level);
387
            sim_io_printf (sd, ",0x%lx",
388
                           (long) entry->nr_bytes);
389
            if (entry->modulo != 0)
390
              sim_io_printf (sd, "%%0x%lx", (long) entry->modulo);
391
            for (alias = entry->alias;
392
                 alias != NULL;
393
                 alias = alias->next)
394
              {
395
                if (alias->space != 0)
396
                  sim_io_printf (sd, "0x%lx:", (long) alias->space);
397
                sim_io_printf (sd, ",0x%08lx", (long) alias->addr);
398
                if (alias->level != 0)
399
                  sim_io_printf (sd, "@0x%lx", (long) alias->level);
400
              }
401
            sim_io_printf (sd, "\n");
402
          }
403
        return SIM_RC_OK;
404
        break;
405
      }
406
 
407
    default:
408
      sim_io_eprintf (sd, "Unknown memory option %d\n", opt);
409
      return SIM_RC_FAIL;
410
 
411
    }
412
 
413
  return SIM_RC_FAIL;
414
}
415
 
416
 
417
/* "memory" module install handler.
418
 
419
   This is called via sim_module_install to install the "memory" subsystem
420
   into the simulator.  */
421
 
422
static MODULE_INIT_FN sim_memory_init;
423
static MODULE_UNINSTALL_FN sim_memory_uninstall;
424
 
425
SIM_RC
426
sim_memopt_install (SIM_DESC sd)
427
{
428
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
429
  sim_add_option_table (sd, NULL, memory_options);
430
  sim_module_add_uninstall_fn (sd, sim_memory_uninstall);
431
  sim_module_add_init_fn (sd, sim_memory_init);
432
  return SIM_RC_OK;
433
}
434
 
435
 
436
/* Uninstall the "memory" subsystem from the simulator.  */
437
 
438
static void
439
sim_memory_uninstall (SIM_DESC sd)
440
{
441
  sim_memopt **entry = &STATE_MEMOPT (sd);
442
  sim_memopt *alias;
443
 
444
  while ((*entry) != NULL)
445
    {
446
      /* delete any buffer */
447
      if ((*entry)->buffer != NULL)
448
        zfree ((*entry)->buffer);
449
 
450
      /* delete it and its aliases */
451
      alias = *entry;
452
 
453
      /* next victim */
454
      *entry = (*entry)->next;
455
 
456
      while (alias != NULL)
457
        {
458
          sim_memopt *dead = alias;
459
          alias = alias->alias;
460
          sim_core_detach (sd, NULL, dead->level, dead->space, dead->addr);
461
          zfree (dead);
462
        }
463
    }
464
}
465
 
466
 
467
static SIM_RC
468
sim_memory_init (SIM_DESC sd)
469
{
470
  /* FIXME: anything needed? */
471
  return SIM_RC_OK;
472
}

powered by: WebSVN 2.1.0

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