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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [v850/] [interp.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
#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
    case bfd_mach_v850e1:
281
      STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT
282
                                     | PSW_CY | PSW_OV | PSW_S | PSW_Z);
283
      break;
284
    }
285
 
286
  return sd;
287
}
288
 
289
 
290
void
291
sim_close (sd, quitting)
292
     SIM_DESC sd;
293
     int quitting;
294
{
295
  sim_module_uninstall (sd);
296
}
297
 
298
SIM_RC
299
sim_create_inferior (sd, prog_bfd, argv, env)
300
     SIM_DESC sd;
301
     struct bfd *prog_bfd;
302
     char **argv;
303
     char **env;
304
{
305
  memset (&State, 0, sizeof (State));
306
  if (prog_bfd != NULL)
307
    PC = bfd_get_start_address (prog_bfd);
308
  return SIM_RC_OK;
309
}
310
 
311
int
312
sim_fetch_register (sd, rn, memory, length)
313
     SIM_DESC sd;
314
     int rn;
315
     unsigned char *memory;
316
     int length;
317
{
318
  *(unsigned32*)memory = H2T_4 (State.regs[rn]);
319
  return -1;
320
}
321
 
322
int
323
sim_store_register (sd, rn, memory, length)
324
     SIM_DESC sd;
325
     int rn;
326
     unsigned char *memory;
327
     int length;
328
{
329
  State.regs[rn] = T2H_4 (*(unsigned32*)memory);
330
  return -1;
331
}
332
 
333
void
334
sim_do_command (sd, cmd)
335
     SIM_DESC sd;
336
     char *cmd;
337
{
338
  char *mm_cmd = "memory-map";
339
  char *int_cmd = "interrupt";
340
 
341
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
342
    {
343
      if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
344
        sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
345
      else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
346
        sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
347
      else
348
        sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
349
    }
350
}

powered by: WebSVN 2.1.0

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