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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [v850/] [interp.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
#include "sim-main.h"
2
#include "sim-options.h"
3
#include "v850_sim.h"
4
#include "sim-assert.h"
5
#include "itable.h"
6
 
7
#ifdef HAVE_STDLIB_H
8
#include <stdlib.h>
9
#endif
10
 
11
#ifdef HAVE_STRING_H
12
#include <string.h>
13
#else
14
#ifdef HAVE_STRINGS_H
15
#include <strings.h>
16
#endif
17
#endif
18
 
19
#include "bfd.h"
20
 
21
#ifndef INLINE
22
#ifdef __GNUC__
23
#define INLINE inline
24
#else
25
#define INLINE
26
#endif
27
#endif
28
 
29
static const char * get_insn_name (sim_cpu *, int);
30
 
31
/* For compatibility */
32
SIM_DESC simulator;
33
 
34
 
35
 
36
/* v850 interrupt model */
37
 
38
enum interrupt_type
39
{
40
  int_reset,
41
  int_nmi,
42
  int_intov1,
43
  int_intp10,
44
  int_intp11,
45
  int_intp12,
46
  int_intp13,
47
  int_intcm4,
48
  num_int_types
49
};
50
 
51
char *interrupt_names[] = {
52
  "reset",
53
  "nmi",
54
  "intov1",
55
  "intp10",
56
  "intp11",
57
  "intp12",
58
  "intp13",
59
  "intcm4",
60
  NULL
61
};
62
 
63
static void
64
do_interrupt (sd, data)
65
     SIM_DESC sd;
66
     void *data;
67
{
68
  char **interrupt_name = (char**)data;
69
  enum interrupt_type inttype;
70
  inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
71
 
72
  /* For a hardware reset, drop everything and jump to the start
73
     address */
74
  if (inttype == int_reset)
75
    {
76
      PC = 0;
77
      PSW = 0x20;
78
      ECR = 0;
79
      sim_engine_restart (sd, NULL, NULL, NULL_CIA);
80
    }
81
 
82
  /* Deliver an NMI when allowed */
83
  if (inttype == int_nmi)
84
    {
85
      if (PSW & PSW_NP)
86
        {
87
          /* We're already working on an NMI, so this one must wait
88
             around until the previous one is done.  The processor
89
             ignores subsequent NMIs, so we don't need to count them.
90
             Just keep re-scheduling a single NMI until it manages to
91
             be delivered */
92
          if (STATE_CPU (sd, 0)->pending_nmi != NULL)
93
            sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi);
94
          STATE_CPU (sd, 0)->pending_nmi =
95
            sim_events_schedule (sd, 1, do_interrupt, data);
96
          return;
97
        }
98
      else
99
        {
100
          /* NMI can be delivered.  Do not deschedule pending_nmi as
101
             that, if still in the event queue, is a second NMI that
102
             needs to be delivered later. */
103
          FEPC = PC;
104
          FEPSW = PSW;
105
          /* Set the FECC part of the ECR. */
106
          ECR &= 0x0000ffff;
107
          ECR |= 0x10;
108
          PSW |= PSW_NP;
109
          PSW &= ~PSW_EP;
110
          PSW |= PSW_ID;
111
          PC = 0x10;
112
          sim_engine_restart (sd, NULL, NULL, NULL_CIA);
113
        }
114
    }
115
 
116
  /* deliver maskable interrupt when allowed */
117
  if (inttype > int_nmi && inttype < num_int_types)
118
    {
119
      if ((PSW & PSW_NP) || (PSW & PSW_ID))
120
        {
121
          /* Can't deliver this interrupt, reschedule it for later */
122
          sim_events_schedule (sd, 1, do_interrupt, data);
123
          return;
124
        }
125
      else
126
        {
127
          /* save context */
128
          EIPC = PC;
129
          EIPSW = PSW;
130
          /* Disable further interrupts.  */
131
          PSW |= PSW_ID;
132
          /* Indicate that we're doing interrupt not exception processing.  */
133
          PSW &= ~PSW_EP;
134
          /* Clear the EICC part of the ECR, will set below. */
135
          ECR &= 0xffff0000;
136
          switch (inttype)
137
            {
138
            case int_intov1:
139
              PC = 0x80;
140
              ECR |= 0x80;
141
              break;
142
            case int_intp10:
143
              PC = 0x90;
144
              ECR |= 0x90;
145
              break;
146
            case int_intp11:
147
              PC = 0xa0;
148
              ECR |= 0xa0;
149
              break;
150
            case int_intp12:
151
              PC = 0xb0;
152
              ECR |= 0xb0;
153
              break;
154
            case int_intp13:
155
              PC = 0xc0;
156
              ECR |= 0xc0;
157
              break;
158
            case int_intcm4:
159
              PC = 0xd0;
160
              ECR |= 0xd0;
161
              break;
162
            default:
163
              /* Should never be possible.  */
164
              sim_engine_abort (sd, NULL, NULL_CIA,
165
                                "do_interrupt - internal error - bad switch");
166
              break;
167
            }
168
        }
169
      sim_engine_restart (sd, NULL, NULL, NULL_CIA);
170
    }
171
 
172
  /* some other interrupt? */
173
  sim_engine_abort (sd, NULL, NULL_CIA,
174
                    "do_interrupt - internal error - interrupt %d unknown",
175
                    inttype);
176
}
177
 
178
/* Return name of an insn, used by insn profiling.  */
179
 
180
static const char *
181
get_insn_name (sim_cpu *cpu, int i)
182
{
183
  return itable[i].name;
184
}
185
 
186
/* These default values correspond to expected usage for the chip.  */
187
 
188
uint32 OP[4];
189
 
190
 
191
SIM_DESC
192
sim_open (kind, cb, abfd, argv)
193
     SIM_OPEN_KIND kind;
194
     host_callback *cb;
195
     struct _bfd *abfd;
196
     char **argv;
197
{
198
  SIM_DESC sd = sim_state_alloc (kind, cb);
199
  int mach;
200
 
201
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
202
 
203
  /* for compatibility */
204
  simulator = sd;
205
 
206
  /* FIXME: should be better way of setting up interrupts */
207
  STATE_WATCHPOINTS (sd)->pc = &(PC);
208
  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
209
  STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
210
  STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;
211
 
212
  /* Initialize the mechanism for doing insn profiling.  */
213
  CPU_INSN_NAME (STATE_CPU (sd, 0)) = get_insn_name;
214
  CPU_MAX_INSNS (STATE_CPU (sd, 0)) = nr_itable_entries;
215
 
216
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
217
    return 0;
218
 
219
  /* Allocate core managed memory */
220
 
221
  /* "Mirror" the ROM addresses below 1MB. */
222
  sim_do_commandf (sd, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE);
223
  /* Chunk of ram adjacent to rom */
224
  sim_do_commandf (sd, "memory region 0x100000,0x%lx", V850_LOW_END-0x100000);
225
  /* peripheral I/O region - mirror 1K across 4k (0x1000) */
226
  sim_do_command (sd, "memory region 0xfff000,0x1000,1024");
227
  /* similarly if in the internal RAM region */
228
  sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
229
 
230
  /* getopt will print the error message so we just have to exit if this fails.
231
     FIXME: Hmmm...  in the case of gdb we need getopt to call
232
     print_filtered.  */
233
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
234
    {
235
      /* Uninstall the modules to avoid memory leaks,
236
         file descriptor leaks, etc.  */
237
      sim_module_uninstall (sd);
238
      return 0;
239
    }
240
 
241
  /* check for/establish the a reference program image */
242
  if (sim_analyze_program (sd,
243
                           (STATE_PROG_ARGV (sd) != NULL
244
                            ? *STATE_PROG_ARGV (sd)
245
                            : NULL),
246
                           abfd) != SIM_RC_OK)
247
    {
248
      sim_module_uninstall (sd);
249
      return 0;
250
    }
251
 
252
  /* establish any remaining configuration options */
253
  if (sim_config (sd) != SIM_RC_OK)
254
    {
255
      sim_module_uninstall (sd);
256
      return 0;
257
    }
258
 
259
  if (sim_post_argv_init (sd) != SIM_RC_OK)
260
    {
261
      /* Uninstall the modules to avoid memory leaks,
262
         file descriptor leaks, etc.  */
263
      sim_module_uninstall (sd);
264
      return 0;
265
    }
266
 
267
 
268
  /* determine the machine type */
269
  if (STATE_ARCHITECTURE (sd) != NULL
270
      && STATE_ARCHITECTURE (sd)->arch == bfd_arch_v850)
271
    mach = STATE_ARCHITECTURE (sd)->mach;
272
  else
273
    mach = bfd_mach_v850; /* default */
274
 
275
  /* set machine specific configuration */
276
  switch (mach)
277
    {
278
    case bfd_mach_v850:
279
    case bfd_mach_v850e:
280
      STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT
281
                                     | PSW_CY | PSW_OV | PSW_S | PSW_Z);
282
      break;
283
    case bfd_mach_v850ea:
284
      PSW |= PSW_US;
285
      STATE_CPU (sd, 0)->psw_mask = (PSW_US
286
                                     | PSW_NP | PSW_EP | PSW_ID | PSW_SAT
287
                                     | PSW_CY | PSW_OV | PSW_S | PSW_Z);
288
      break;
289
    }
290
 
291
  return sd;
292
}
293
 
294
 
295
void
296
sim_close (sd, quitting)
297
     SIM_DESC sd;
298
     int quitting;
299
{
300
  sim_module_uninstall (sd);
301
}
302
 
303
SIM_RC
304
sim_create_inferior (sd, prog_bfd, argv, env)
305
     SIM_DESC sd;
306
     struct _bfd *prog_bfd;
307
     char **argv;
308
     char **env;
309
{
310
  memset (&State, 0, sizeof (State));
311
  if (prog_bfd != NULL)
312
    PC = bfd_get_start_address (prog_bfd);
313
  /* For v850ea, set PSW[US] by default */
314
  if (STATE_ARCHITECTURE (sd) != NULL
315
      && STATE_ARCHITECTURE (sd)->arch == bfd_arch_v850
316
      && STATE_ARCHITECTURE (sd)->mach == bfd_mach_v850ea)
317
    PSW |= PSW_US;
318
  return SIM_RC_OK;
319
}
320
 
321
int
322
sim_fetch_register (sd, rn, memory, length)
323
     SIM_DESC sd;
324
     int rn;
325
     unsigned char *memory;
326
     int length;
327
{
328
  *(unsigned32*)memory = H2T_4 (State.regs[rn]);
329
  return -1;
330
}
331
 
332
int
333
sim_store_register (sd, rn, memory, length)
334
     SIM_DESC sd;
335
     int rn;
336
     unsigned char *memory;
337
     int length;
338
{
339
  State.regs[rn] = T2H_4 (*(unsigned32*)memory);
340
  return -1;
341
}
342
 
343
void
344
sim_do_command (sd, cmd)
345
     SIM_DESC sd;
346
     char *cmd;
347
{
348
  char *mm_cmd = "memory-map";
349
  char *int_cmd = "interrupt";
350
 
351
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
352
    {
353
      if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
354
        sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
355
      else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
356
        sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
357
      else
358
        sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
359
    }
360
}

powered by: WebSVN 2.1.0

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