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

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [sim/] [m68hc11/] [interp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* interp.c -- Simulator for Motorola 68HC11
2
   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
   Written by Stephane Carrez (stcarrez@worldnet.fr)
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-hw.h"
24
#include "sim-options.h"
25
#include "hw-tree.h"
26
#include "hw-device.h"
27
#include "hw-ports.h"
28
 
29
#ifndef MONITOR_BASE
30
# define MONITOR_BASE (0x0C000)
31
# define MONITOR_SIZE (0x04000)
32
#endif
33
 
34
static void sim_get_info (SIM_DESC sd, char *cmd);
35
 
36
 
37
char *interrupt_names[] = {
38
  "reset",
39
  "nmi",
40
  "int",
41
  NULL
42
};
43
 
44
#ifndef INLINE
45
#if defined(__GNUC__) && defined(__OPTIMIZE__)
46
#define INLINE __inline__
47
#else
48
#define INLINE
49
#endif
50
#endif
51
 
52
struct sim_info_list
53
{
54
  const char *name;
55
  const char *device;
56
};
57
 
58
struct sim_info_list dev_list_68hc11[] = {
59
  {"cpu", "/m68hc11"},
60
  {"timer", "/m68hc11/m68hc11tim"},
61
  {"sio", "/m68hc11/m68hc11sio"},
62
  {"spi", "/m68hc11/m68hc11spi"},
63
  {"eeprom", "/m68hc11/m68hc11eepr"},
64
  {0, 0}
65
};
66
 
67
struct sim_info_list dev_list_68hc12[] = {
68
  {"cpu", "/m68hc12"},
69
  {"timer", "/m68hc12/m68hc12tim"},
70
  {"sio", "/m68hc12/m68hc12sio"},
71
  {"spi", "/m68hc12/m68hc12spi"},
72
  {"eeprom", "/m68hc12/m68hc12eepr"},
73
  {0, 0}
74
};
75
 
76
/* Cover function of sim_state_free to free the cpu buffers as well.  */
77
 
78
static void
79
free_state (SIM_DESC sd)
80
{
81
  if (STATE_MODULES (sd) != NULL)
82
    sim_module_uninstall (sd);
83
 
84
  sim_state_free (sd);
85
}
86
 
87
/* Give some information about the simulator.  */
88
static void
89
sim_get_info (SIM_DESC sd, char *cmd)
90
{
91
  sim_cpu *cpu;
92
 
93
  cpu = STATE_CPU (sd, 0);
94
  if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
95
    {
96
      int i;
97
      struct hw *hw_dev;
98
      struct sim_info_list *dev_list;
99
      const struct bfd_arch_info *arch;
100
 
101
      arch = STATE_ARCHITECTURE (sd);
102
      cmd++;
103
 
104
      if (arch->arch == bfd_arch_m68hc11)
105
        dev_list = dev_list_68hc11;
106
      else
107
        dev_list = dev_list_68hc12;
108
 
109
      for (i = 0; dev_list[i].name; i++)
110
        if (strcmp (cmd, dev_list[i].name) == 0)
111
          break;
112
 
113
      if (dev_list[i].name == 0)
114
        {
115
          sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
116
          sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
117
          return;
118
        }
119
      hw_dev = sim_hw_parse (sd, dev_list[i].device);
120
      if (hw_dev == 0)
121
        {
122
          sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
123
          return;
124
        }
125
      hw_ioctl (hw_dev, 23, 0);
126
      return;
127
    }
128
 
129
  cpu_info (sd, cpu);
130
  interrupts_info (sd, &cpu->cpu_interrupts);
131
}
132
 
133
 
134
void
135
sim_board_reset (SIM_DESC sd)
136
{
137
  struct hw *hw_cpu;
138
  sim_cpu *cpu;
139
  const struct bfd_arch_info *arch;
140
  const char *cpu_type;
141
 
142
  cpu = STATE_CPU (sd, 0);
143
  arch = STATE_ARCHITECTURE (sd);
144
 
145
  /*  hw_cpu = sim_hw_parse (sd, "/"); */
146
  if (arch->arch == bfd_arch_m68hc11)
147
    {
148
      cpu->cpu_type = CPU_M6811;
149
      cpu_type = "/m68hc11";
150
    }
151
  else
152
    {
153
      cpu->cpu_type = CPU_M6812;
154
      cpu_type = "/m68hc12";
155
    }
156
 
157
  hw_cpu = sim_hw_parse (sd, cpu_type);
158
  if (hw_cpu == 0)
159
    {
160
      sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
161
      return;
162
    }
163
 
164
  cpu_reset (cpu);
165
  hw_port_event (hw_cpu, 3, 0);
166
  cpu_restart (cpu);
167
}
168
 
169
int
170
sim_hw_configure (SIM_DESC sd)
171
{
172
  const struct bfd_arch_info *arch;
173
  struct hw *device_tree;
174
  int m6811_mode;
175
  sim_cpu *cpu;
176
 
177
  arch = STATE_ARCHITECTURE (sd);
178
  if (arch == 0)
179
    return 0;
180
 
181
  cpu = STATE_CPU (sd, 0);
182
  cpu->cpu_configured_arch = arch;
183
  device_tree = sim_hw_parse (sd, "/");
184
  if (arch->arch == bfd_arch_m68hc11)
185
    {
186
      cpu->cpu_interpretor = cpu_interp_m6811;
187
      if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
188
        {
189
          /* Allocate core managed memory */
190
 
191
          /* the monitor  */
192
          sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
193
                           /* MONITOR_BASE, MONITOR_SIZE */
194
                           0x8000, M6811_RAM_LEVEL, 0x8000);
195
          sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
196
                           M6811_RAM_LEVEL);
197
          sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
198
        }
199
 
200
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
201
        {
202
          sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
203
          sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
204
          sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
205
        }
206
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
207
        {
208
          /* M68hc11 Timer configuration. */
209
          sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
210
          sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
211
        }
212
 
213
      /* Create the SPI device.  */
214
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
215
        {
216
          sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
217
          sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
218
        }
219
      if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
220
        {
221
          /* M68hc11 persistent ram configuration. */
222
          sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
223
          sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
224
          sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
225
          /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
226
        }
227
      if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
228
        {
229
          sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
230
          sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
231
        }
232
    }
233
  else
234
    {
235
      cpu->cpu_interpretor = cpu_interp_m6812;
236
      if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
237
        {
238
          /* Allocate core external memory.  */
239
          sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
240
                           0x8000, M6811_RAM_LEVEL, 0x8000);
241
          sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
242
                           M6811_RAM_LEVEL);
243
 
244
          sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
245
        }
246
 
247
      if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
248
        {
249
          sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
250
          sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
251
          sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
252
        }
253
      if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@2/reg"))
254
        {
255
          sim_hw_parse (sd, "/m68hc12/m68hc12sio@2/reg 0xC8 0x8");
256
          sim_hw_parse (sd, "/m68hc12/m68hc12sio@2/backend tcp");
257
          sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@2");
258
        }
259
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
260
        {
261
          /* M68hc11 Timer configuration. */
262
          sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
263
          sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
264
        }
265
 
266
      /* Create the SPI device.  */
267
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
268
        {
269
          sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
270
          sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
271
        }
272
      if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
273
        {
274
          /* M68hc11 persistent ram configuration. */
275
          sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
276
          sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
277
          sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
278
        }
279
      if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
280
        {
281
          sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
282
          sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
283
        }
284
    }
285
  return 0;
286
}
287
 
288
static int
289
sim_prepare_for_program (SIM_DESC sd, struct _bfd* abfd)
290
{
291
  sim_cpu *cpu;
292
 
293
  cpu = STATE_CPU (sd, 0);
294
 
295
  sim_hw_configure (sd);
296
  if (abfd != NULL)
297
    {
298
      cpu->cpu_elf_start = bfd_get_start_address (abfd);
299
    }
300
 
301
  /* reset all state information */
302
  sim_board_reset (sd);
303
 
304
  return SIM_RC_OK;
305
}
306
 
307
SIM_DESC
308
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
309
          struct _bfd *abfd, char **argv)
310
{
311
  char **p;
312
  SIM_DESC sd;
313
  sim_cpu *cpu;
314
  struct hw *device_tree;
315
 
316
  sd = sim_state_alloc (kind, callback);
317
  cpu = STATE_CPU (sd, 0);
318
 
319
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
320
 
321
  /* for compatibility */
322
  current_alignment = NONSTRICT_ALIGNMENT;
323
  current_target_byte_order = BIG_ENDIAN;
324
 
325
  cpu_initialize (sd, cpu);
326
 
327
  cpu->cpu_use_elf_start = 1;
328
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
329
    {
330
      free_state (sd);
331
      return 0;
332
    }
333
 
334
  /* getopt will print the error message so we just have to exit if this fails.
335
     FIXME: Hmmm...  in the case of gdb we need getopt to call
336
     print_filtered.  */
337
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
338
    {
339
      /* Uninstall the modules to avoid memory leaks,
340
         file descriptor leaks, etc.  */
341
      free_state (sd);
342
      return 0;
343
    }
344
 
345
  /* Check for/establish the a reference program image.  */
346
  if (sim_analyze_program (sd,
347
                           (STATE_PROG_ARGV (sd) != NULL
348
                            ? *STATE_PROG_ARGV (sd)
349
                            : NULL), abfd) != SIM_RC_OK)
350
    {
351
      free_state (sd);
352
      return 0;
353
    }
354
 
355
  /* Establish any remaining configuration options.  */
356
  if (sim_config (sd) != SIM_RC_OK)
357
    {
358
      free_state (sd);
359
      return 0;
360
    }
361
 
362
  if (sim_post_argv_init (sd) != SIM_RC_OK)
363
    {
364
      /* Uninstall the modules to avoid memory leaks,
365
         file descriptor leaks, etc.  */
366
      free_state (sd);
367
      return 0;
368
    }
369
 
370
  sim_hw_configure (sd);
371
 
372
  /* Fudge our descriptor.  */
373
  return sd;
374
}
375
 
376
 
377
void
378
sim_close (SIM_DESC sd, int quitting)
379
{
380
  /* shut down modules */
381
  sim_module_uninstall (sd);
382
 
383
  /* Ensure that any resources allocated through the callback
384
     mechanism are released: */
385
  sim_io_shutdown (sd);
386
 
387
  /* FIXME - free SD */
388
  sim_state_free (sd);
389
  return;
390
}
391
 
392
void
393
sim_set_profile (int n)
394
{
395
}
396
 
397
void
398
sim_set_profile_size (int n)
399
{
400
}
401
 
402
/* Generic implementation of sim_engine_run that works within the
403
   sim_engine setjmp/longjmp framework. */
404
 
405
void
406
sim_engine_run (SIM_DESC sd,
407
                int next_cpu_nr,        /* ignore */
408
                int nr_cpus,    /* ignore */
409
                int siggnal)    /* ignore */
410
{
411
  sim_cpu *cpu;
412
 
413
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
414
  cpu = STATE_CPU (sd, 0);
415
  while (1)
416
    {
417
      cpu_single_step (cpu);
418
 
419
      /* process any events */
420
      if (sim_events_tickn (sd, cpu->cpu_current_cycle))
421
        {
422
          sim_events_process (sd);
423
        }
424
    }
425
}
426
 
427
int
428
sim_trace (SIM_DESC sd)
429
{
430
  sim_resume (sd, 0, 0);
431
  return 1;
432
}
433
 
434
void
435
sim_info (SIM_DESC sd, int verbose)
436
{
437
  const char *cpu_type;
438
  const struct bfd_arch_info *arch;
439
 
440
  arch = STATE_ARCHITECTURE (sd);
441
  if (arch->arch == bfd_arch_m68hc11)
442
    cpu_type = "68HC11";
443
  else
444
    cpu_type = "68HC12";
445
 
446
  sim_io_eprintf (sd, "Simulator info:\n");
447
  sim_io_eprintf (sd, "  CPU Motorola %s\n", cpu_type);
448
  sim_get_info (sd, 0);
449
  sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
450
}
451
 
452
SIM_RC
453
sim_create_inferior (SIM_DESC sd, struct _bfd *abfd,
454
                     char **argv, char **env)
455
{
456
  return sim_prepare_for_program (sd, abfd);
457
}
458
 
459
 
460
void
461
sim_set_callbacks (host_callback *p)
462
{
463
  /*  m6811_callback = p; */
464
}
465
 
466
 
467
int
468
sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
469
{
470
  sim_cpu *cpu;
471
  uint16 val;
472
 
473
  cpu = STATE_CPU (sd, 0);
474
  switch (rn)
475
    {
476
    case A_REGNUM:
477
      val = cpu_get_a (cpu);
478
      break;
479
 
480
    case B_REGNUM:
481
      val = cpu_get_b (cpu);
482
      break;
483
 
484
    case D_REGNUM:
485
      val = cpu_get_d (cpu);
486
      break;
487
 
488
    case X_REGNUM:
489
      val = cpu_get_x (cpu);
490
      break;
491
 
492
    case Y_REGNUM:
493
      val = cpu_get_y (cpu);
494
      break;
495
 
496
    case SP_REGNUM:
497
      val = cpu_get_sp (cpu);
498
      break;
499
 
500
    case PC_REGNUM:
501
      val = cpu_get_pc (cpu);
502
      break;
503
 
504
    case PSW_REGNUM:
505
      val = cpu_get_ccr (cpu);
506
      break;
507
 
508
    default:
509
      val = 0;
510
      break;
511
    }
512
  memory[0] = val >> 8;
513
  memory[1] = val & 0x0FF;
514
  return 2;
515
}
516
 
517
int
518
sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
519
{
520
  uint16 val;
521
  sim_cpu *cpu;
522
 
523
  cpu = STATE_CPU (sd, 0);
524
 
525
  val = *memory++;
526
  if (length == 2)
527
    val = (val << 8) | *memory;
528
 
529
  switch (rn)
530
    {
531
    case D_REGNUM:
532
      cpu_set_d (cpu, val);
533
      break;
534
 
535
    case A_REGNUM:
536
      cpu_set_a (cpu, val);
537
      break;
538
 
539
    case B_REGNUM:
540
      cpu_set_b (cpu, val);
541
      break;
542
 
543
    case X_REGNUM:
544
      cpu_set_x (cpu, val);
545
      break;
546
 
547
    case Y_REGNUM:
548
      cpu_set_y (cpu, val);
549
      break;
550
 
551
    case SP_REGNUM:
552
      cpu_set_sp (cpu, val);
553
      break;
554
 
555
    case PC_REGNUM:
556
      cpu_set_pc (cpu, val);
557
      break;
558
 
559
    case PSW_REGNUM:
560
      cpu_set_ccr (cpu, val);
561
      break;
562
 
563
    default:
564
      break;
565
    }
566
 
567
  return 2;
568
}
569
 
570
void
571
sim_size (int s)
572
{
573
  ;
574
}
575
 
576
void
577
sim_do_command (SIM_DESC sd, char *cmd)
578
{
579
  char *mm_cmd = "memory-map";
580
  char *int_cmd = "interrupt";
581
  sim_cpu *cpu;
582
 
583
  cpu = STATE_CPU (sd, 0);
584
  /* Commands available from GDB:   */
585
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
586
    {
587
      if (strncmp (cmd, "info", sizeof ("info") - 1) == 0)
588
        sim_get_info (sd, &cmd[4]);
589
      else if (strncmp (cmd, "frame", sizeof ("frame") - 1) == 0)
590
        cpu_print_frame (sd, STATE_CPU (sd, 0));
591
      else if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
592
        sim_io_eprintf (sd,
593
                        "`memory-map' command replaced by `sim memory'\n");
594
      else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
595
        sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
596
      else
597
        sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
598
    }
599
 
600
  /* If the architecture changed, re-configure.  */
601
  if (STATE_ARCHITECTURE (sd) != cpu->cpu_configured_arch)
602
    sim_hw_configure (sd);
603
}

powered by: WebSVN 2.1.0

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