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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [sim/] [m68hc11/] [interrupts.c] - Blame information for rev 1182

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

Line No. Rev Author Line
1 1181 sfurman
/* interrupts.c -- 68HC11 Interrupts Emulation
2
   Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
   Written by Stephane Carrez (stcarrez@worldnet.fr)
4
 
5
This file is part of GDB, GAS, and the GNU binutils.
6
 
7
GDB, GAS, and the GNU binutils are free software; you can redistribute
8
them and/or modify them under the terms of the GNU General Public
9
License as published by the Free Software Foundation; either version
10
1, or (at your option) any later version.
11
 
12
GDB, GAS, and the GNU binutils are distributed in the hope that they
13
will be useful, but WITHOUT ANY WARRANTY; without even the implied
14
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15
the 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 file; see the file COPYING.  If not, write to the Free
19
Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#include "sim-main.h"
22
#include "sim-options.h"
23
 
24
static const char *interrupt_names[] = {
25
  "R1",
26
  "R2",
27
  "R3",
28
  "R4",
29
  "R5",
30
  "R6",
31
  "R7",
32
  "R8",
33
  "R9",
34
  "R10",
35
  "R11",
36
 
37
  "SCI",
38
  "SPI",
39
  "AINPUT",
40
  "AOVERFLOW",
41
  "TOVERFLOW",
42
  "OUT5",
43
  "OUT4",
44
  "OUT3",
45
  "OUT2",
46
  "OUT1",
47
  "INC3",
48
  "INC2",
49
  "INC1",
50
  "RT",
51
  "IRQ",
52
  "XIRQ",
53
  "SWI",
54
  "ILL",
55
  "COPRESET",
56
  "COPFAIL",
57
  "RESET"
58
};
59
 
60
struct interrupt_def idefs[] = {
61
  /* Serial interrupts.  */
62
  { M6811_INT_SCI,      M6811_SCSR,   M6811_TDRE,  M6811_SCCR2,  M6811_TIE },
63
  { M6811_INT_SCI,      M6811_SCSR,   M6811_TC,    M6811_SCCR2,  M6811_TCIE },
64
  { M6811_INT_SCI,      M6811_SCSR,   M6811_RDRF,  M6811_SCCR2,  M6811_RIE },
65
  { M6811_INT_SCI,      M6811_SCSR,   M6811_IDLE,  M6811_SCCR2,  M6811_ILIE },
66
 
67
  /* SPI interrupts.  */
68
  { M6811_INT_SPI,      M6811_SPSR,   M6811_SPIF,  M6811_SPCR,   M6811_SPIE },
69
 
70
  /* Realtime interrupts.  */
71
  { M6811_INT_TCTN,     M6811_TFLG2,  M6811_TOF,   M6811_TMSK2,  M6811_TOI },
72
  { M6811_INT_RT,       M6811_TFLG2,  M6811_RTIF,  M6811_TMSK2,  M6811_RTII },
73
 
74
  /* Output compare interrupts.  */
75
  { M6811_INT_OUTCMP1,  M6811_TFLG1,  M6811_OC1F,  M6811_TMSK1,  M6811_OC1I },
76
  { M6811_INT_OUTCMP2,  M6811_TFLG1,  M6811_OC2F,  M6811_TMSK1,  M6811_OC2I },
77
  { M6811_INT_OUTCMP3,  M6811_TFLG1,  M6811_OC3F,  M6811_TMSK1,  M6811_OC3I },
78
  { M6811_INT_OUTCMP4,  M6811_TFLG1,  M6811_OC4F,  M6811_TMSK1,  M6811_OC4I },
79
  { M6811_INT_OUTCMP5,  M6811_TFLG1,  M6811_OC5F,  M6811_TMSK1,  M6811_OC5I },
80
 
81
  /* Input compare interrupts.  */
82
  { M6811_INT_INCMP1,   M6811_TFLG1,  M6811_IC1F,  M6811_TMSK1,  M6811_IC1I },
83
  { M6811_INT_INCMP2,   M6811_TFLG1,  M6811_IC2F,  M6811_TMSK1,  M6811_IC2I },
84
  { M6811_INT_INCMP3,   M6811_TFLG1,  M6811_IC3F,  M6811_TMSK1,  M6811_IC3I },
85
 
86
  /* Pulse accumulator.  */
87
  { M6811_INT_AINPUT,   M6811_TFLG2,  M6811_PAIF,  M6811_TMSK2,  M6811_PAII },
88
  { M6811_INT_AOVERFLOW,M6811_TFLG2,  M6811_PAOVF, M6811_TMSK2,  M6811_PAOVI},
89
#if 0
90
  { M6811_INT_COPRESET, M6811_CONFIG, M6811_NOCOP, 0,            0 },
91
  { M6811_INT_COPFAIL,  M6811_CONFIG, M6811_NOCOP, 0,            0 }
92
#endif
93
};
94
 
95
#define TableSize(X) (sizeof X / sizeof(X[0]))
96
#define CYCLES_MAX ((((signed64) 1) << 62) - 1)
97
 
98
enum
99
{
100
  OPTION_INTERRUPT_INFO = OPTION_START,
101
  OPTION_INTERRUPT_CATCH,
102
  OPTION_INTERRUPT_CLEAR
103
};
104
 
105
static DECLARE_OPTION_HANDLER (interrupt_option_handler);
106
 
107
static const OPTION interrupt_options[] =
108
{
109
  { {"interrupt-info", no_argument, NULL, OPTION_INTERRUPT_INFO },
110
      '\0', NULL, "Print information about interrupts",
111
      interrupt_option_handler },
112
  { {"interrupt-catch", required_argument, NULL, OPTION_INTERRUPT_CATCH },
113
      '\0', "NAME[,MODE]",
114
    "Catch interrupts when they are raised or taken\n"
115
    "NAME   Name of the interrupt\n"
116
    "MODE   Optional mode (`taken' or `raised')",
117
      interrupt_option_handler },
118
  { {"interrupt-clear", required_argument, NULL, OPTION_INTERRUPT_CLEAR },
119
      '\0', "NAME", "No longer catch the interrupt",
120
      interrupt_option_handler },
121
 
122
  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
123
};
124
 
125
/* Initialize the interrupts module.  */
126
void
127
interrupts_initialize (SIM_DESC sd, struct _sim_cpu *proc)
128
{
129
  struct interrupts *interrupts = &proc->cpu_interrupts;
130
 
131
  interrupts->cpu          = proc;
132
 
133
  sim_add_option_table (sd, 0, interrupt_options);
134
}
135
 
136
/* Initialize the interrupts of the processor.  */
137
void
138
interrupts_reset (struct interrupts *interrupts)
139
{
140
  int i;
141
 
142
  interrupts->pending_mask = 0;
143
  if (interrupts->cpu->cpu_mode & M6811_SMOD)
144
    interrupts->vectors_addr = 0xbfc0;
145
  else
146
    interrupts->vectors_addr = 0xffc0;
147
  interrupts->nb_interrupts_raised = 0;
148
  interrupts->min_mask_cycles = CYCLES_MAX;
149
  interrupts->max_mask_cycles = 0;
150
  interrupts->last_mask_cycles = 0;
151
  interrupts->start_mask_cycle = -1;
152
  interrupts->xirq_start_mask_cycle = -1;
153
  interrupts->xirq_max_mask_cycles = 0;
154
  interrupts->xirq_min_mask_cycles = CYCLES_MAX;
155
  interrupts->xirq_last_mask_cycles = 0;
156
 
157
  for (i = 0; i < M6811_INT_NUMBER; i++)
158
    {
159
      interrupts->interrupt_order[i] = i;
160
    }
161
 
162
  /* Clear the interrupt history table.  */
163
  interrupts->history_index = 0;
164
  memset (interrupts->interrupts_history, 0,
165
          sizeof (interrupts->interrupts_history));
166
 
167
  memset (interrupts->interrupts, 0,
168
          sizeof (interrupts->interrupts));
169
}
170
 
171
static int
172
find_interrupt (const char *name)
173
{
174
  int i;
175
 
176
  if (name)
177
    for (i = 0; i < M6811_INT_NUMBER; i++)
178
      if (strcasecmp (name, interrupt_names[i]) == 0)
179
        return i;
180
 
181
  return -1;
182
}
183
 
184
static SIM_RC
185
interrupt_option_handler (SIM_DESC sd, sim_cpu *cpu,
186
                          int opt, char *arg, int is_command)
187
{
188
  char *p;
189
  int mode;
190
  int id;
191
  struct interrupts *interrupts;
192
 
193
  if (cpu == 0)
194
    cpu = STATE_CPU (sd, 0);
195
 
196
  interrupts = &cpu->cpu_interrupts;
197
  switch (opt)
198
    {
199
    case OPTION_INTERRUPT_INFO:
200
      for (id = 0; id < M6811_INT_NUMBER; id++)
201
        {
202
          sim_io_eprintf (sd, "%-10.10s ", interrupt_names[id]);
203
          switch (interrupts->interrupts[id].stop_mode)
204
            {
205
            case SIM_STOP_WHEN_RAISED:
206
              sim_io_eprintf (sd, "catch raised ");
207
              break;
208
 
209
            case SIM_STOP_WHEN_TAKEN:
210
              sim_io_eprintf (sd, "catch taken  ");
211
              break;
212
 
213
            case SIM_STOP_WHEN_RAISED | SIM_STOP_WHEN_TAKEN:
214
              sim_io_eprintf (sd, "catch all    ");
215
              break;
216
 
217
            default:
218
              sim_io_eprintf (sd, "             ");
219
              break;
220
            }
221
          sim_io_eprintf (sd, "%ld\n",
222
                          interrupts->interrupts[id].raised_count);
223
        }
224
      break;
225
 
226
    case OPTION_INTERRUPT_CATCH:
227
      p = strchr (arg, ',');
228
      if (p)
229
        *p++ = 0;
230
 
231
      mode = SIM_STOP_WHEN_RAISED;
232
      id = find_interrupt (arg);
233
      if (id < 0)
234
        sim_io_eprintf (sd, "Interrupt name not recognized: %s\n", arg);
235
 
236
      if (p && strcasecmp (p, "raised") == 0)
237
        mode = SIM_STOP_WHEN_RAISED;
238
      else if (p && strcasecmp (p, "taken") == 0)
239
        mode = SIM_STOP_WHEN_TAKEN;
240
      else if (p && strcasecmp (p, "all") == 0)
241
        mode = SIM_STOP_WHEN_RAISED | SIM_STOP_WHEN_TAKEN;
242
      else if (p)
243
        {
244
          sim_io_eprintf (sd, "Invalid argument: %s\n", p);
245
          break;
246
        }
247
      if (id >= 0)
248
        interrupts->interrupts[id].stop_mode = mode;
249
      break;
250
 
251
    case OPTION_INTERRUPT_CLEAR:
252
      mode = SIM_STOP_WHEN_RAISED;
253
      id = find_interrupt (arg);
254
      if (id < 0)
255
        sim_io_eprintf (sd, "Interrupt name not recognized: %s\n", arg);
256
      else
257
        interrupts->interrupts[id].stop_mode = 0;
258
      break;
259
    }
260
 
261
  return SIM_RC_OK;
262
}
263
 
264
/* Update the mask of pending interrupts.  This operation must be called
265
   when the state of some 68HC11 IO register changes.  It looks the
266
   different registers that indicate a pending interrupt (timer, SCI, SPI,
267
   ...) and records the interrupt if it's there and enabled.  */
268
void
269
interrupts_update_pending (struct interrupts *interrupts)
270
{
271
  int i;
272
  uint8 *ioregs;
273
  unsigned long clear_mask;
274
  unsigned long set_mask;
275
 
276
  clear_mask = 0;
277
  set_mask = 0;
278
  ioregs = &interrupts->cpu->ios[0];
279
 
280
  for (i = 0; i < TableSize(idefs); i++)
281
    {
282
      struct interrupt_def *idef = &idefs[i];
283
      uint8 data;
284
 
285
      /* Look if the interrupt is enabled.  */
286
      if (idef->enable_paddr)
287
        {
288
          data = ioregs[idef->enable_paddr];
289
          if (!(data & idef->enabled_mask))
290
            {
291
              /* Disable it.  */
292
              clear_mask |= (1 << idef->int_number);
293
              continue;
294
            }
295
        }
296
 
297
      /* Interrupt is enabled, see if it's there.  */
298
      data = ioregs[idef->int_paddr];
299
      if (!(data & idef->int_mask))
300
        {
301
          /* Disable it.  */
302
          clear_mask |= (1 << idef->int_number);
303
          continue;
304
        }
305
 
306
      /* Ok, raise it.  */
307
      set_mask |= (1 << idef->int_number);
308
    }
309
 
310
  /* Some interrupts are shared (M6811_INT_SCI) so clear
311
     the interrupts before setting the new ones.  */
312
  interrupts->pending_mask &= ~clear_mask;
313
  interrupts->pending_mask |= set_mask;
314
 
315
  /* Keep track of when the interrupt is raised by the device.
316
     Also implements the breakpoint-on-interrupt.  */
317
  if (set_mask)
318
    {
319
      signed64 cycle = cpu_current_cycle (interrupts->cpu);
320
      int must_stop = 0;
321
 
322
      for (i = 0; i < M6811_INT_NUMBER; i++)
323
        {
324
          if (!(set_mask & (1 << i)))
325
            continue;
326
 
327
          interrupts->interrupts[i].cpu_cycle = cycle;
328
          if (interrupts->interrupts[i].stop_mode & SIM_STOP_WHEN_RAISED)
329
            {
330
              must_stop = 1;
331
              sim_io_printf (CPU_STATE (interrupts->cpu),
332
                             "Interrupt %s raised\n",
333
                             interrupt_names[i]);
334
            }
335
        }
336
      if (must_stop)
337
        sim_engine_halt (CPU_STATE (interrupts->cpu),
338
                         interrupts->cpu,
339
                         0, cpu_get_pc (interrupts->cpu),
340
                         sim_stopped,
341
                         SIM_SIGTRAP);
342
    }
343
}
344
 
345
 
346
/* Finds the current active and non-masked interrupt.
347
   Returns the interrupt number (index in the vector table) or -1
348
   if no interrupt can be serviced.  */
349
int
350
interrupts_get_current (struct interrupts *interrupts)
351
{
352
  int i;
353
 
354
  if (interrupts->pending_mask == 0)
355
    return -1;
356
 
357
  /* SWI and illegal instructions are simulated by an interrupt.
358
     They are not maskable.  */
359
  if (interrupts->pending_mask & (1 << M6811_INT_SWI))
360
    {
361
      interrupts->pending_mask &= ~(1 << M6811_INT_SWI);
362
      return M6811_INT_SWI;
363
    }
364
  if (interrupts->pending_mask & (1 << M6811_INT_ILLEGAL))
365
    {
366
      interrupts->pending_mask &= ~(1 << M6811_INT_ILLEGAL);
367
      return M6811_INT_ILLEGAL;
368
    }
369
 
370
  /* If there is a non maskable interrupt, go for it (unless we are masked
371
     by the X-bit.  */
372
  if (interrupts->pending_mask & (1 << M6811_INT_XIRQ))
373
    {
374
      if (cpu_get_ccr_X (interrupts->cpu) == 0)
375
        {
376
          interrupts->pending_mask &= ~(1 << M6811_INT_XIRQ);
377
          return M6811_INT_XIRQ;
378
        }
379
      return -1;
380
    }
381
 
382
  /* Interrupts are masked, do nothing.  */
383
  if (cpu_get_ccr_I (interrupts->cpu) == 1)
384
    {
385
      return -1;
386
    }
387
 
388
  /* Returns the first interrupt number which is pending.
389
     The interrupt priority is specified by the table `interrupt_order'.
390
     For these interrupts, the pending mask is cleared when the program
391
     performs some actions on the corresponding device.  If the device
392
     is not reset, the interrupt remains and will be re-raised when
393
     we return from the interrupt (see 68HC11 pink book).  */
394
  for (i = 0; i < M6811_INT_NUMBER; i++)
395
    {
396
      enum M6811_INT int_number = interrupts->interrupt_order[i];
397
 
398
      if (interrupts->pending_mask & (1 << int_number))
399
        {
400
          return int_number;
401
        }
402
    }
403
  return -1;
404
}
405
 
406
 
407
/* Process the current interrupt if there is one.  This operation must
408
   be called after each instruction to handle the interrupts.  If interrupts
409
   are masked, it does nothing.  */
410
int
411
interrupts_process (struct interrupts *interrupts)
412
{
413
  int id;
414
  uint8 ccr;
415
 
416
  /* See if interrupts are enabled/disabled and keep track of the
417
     number of cycles the interrupts are masked.  Such information is
418
     then reported by the info command.  */
419
  ccr = cpu_get_ccr (interrupts->cpu);
420
  if (ccr & M6811_I_BIT)
421
    {
422
      if (interrupts->start_mask_cycle < 0)
423
        interrupts->start_mask_cycle = cpu_current_cycle (interrupts->cpu);
424
    }
425
  else if (interrupts->start_mask_cycle >= 0
426
           && (ccr & M6811_I_BIT) == 0)
427
    {
428
      signed64 t = cpu_current_cycle (interrupts->cpu);
429
 
430
      t -= interrupts->start_mask_cycle;
431
      if (t < interrupts->min_mask_cycles)
432
        interrupts->min_mask_cycles = t;
433
      if (t > interrupts->max_mask_cycles)
434
        interrupts->max_mask_cycles = t;
435
      interrupts->start_mask_cycle = -1;
436
      interrupts->last_mask_cycles = t;
437
    }
438
  if (ccr & M6811_X_BIT)
439
    {
440
      if (interrupts->xirq_start_mask_cycle < 0)
441
        interrupts->xirq_start_mask_cycle
442
          = cpu_current_cycle (interrupts->cpu);
443
    }
444
  else if (interrupts->xirq_start_mask_cycle >= 0
445
           && (ccr & M6811_X_BIT) == 0)
446
    {
447
      signed64 t = cpu_current_cycle (interrupts->cpu);
448
 
449
      t -= interrupts->xirq_start_mask_cycle;
450
      if (t < interrupts->xirq_min_mask_cycles)
451
        interrupts->xirq_min_mask_cycles = t;
452
      if (t > interrupts->xirq_max_mask_cycles)
453
        interrupts->xirq_max_mask_cycles = t;
454
      interrupts->xirq_start_mask_cycle = -1;
455
      interrupts->xirq_last_mask_cycles = t;
456
    }
457
 
458
  id = interrupts_get_current (interrupts);
459
  if (id >= 0)
460
    {
461
      uint16 addr;
462
      struct interrupt_history *h;
463
 
464
      /* Implement the breakpoint-on-interrupt.  */
465
      if (interrupts->interrupts[id].stop_mode & SIM_STOP_WHEN_TAKEN)
466
        {
467
          sim_io_printf (CPU_STATE (interrupts->cpu),
468
                         "Interrupt %s will be handled\n",
469
                         interrupt_names[id]);
470
          sim_engine_halt (CPU_STATE (interrupts->cpu),
471
                           interrupts->cpu,
472
                           0, cpu_get_pc (interrupts->cpu),
473
                           sim_stopped,
474
                           SIM_SIGTRAP);
475
        }
476
 
477
      cpu_push_all (interrupts->cpu);
478
      addr = memory_read16 (interrupts->cpu,
479
                            interrupts->vectors_addr + id * 2);
480
      cpu_call (interrupts->cpu, addr);
481
 
482
      /* Now, protect from nested interrupts.  */
483
      if (id == M6811_INT_XIRQ)
484
        {
485
          cpu_set_ccr_X (interrupts->cpu, 1);
486
        }
487
      else
488
        {
489
          cpu_set_ccr_I (interrupts->cpu, 1);
490
        }
491
 
492
      /* Update the interrupt history table.  */
493
      h = &interrupts->interrupts_history[interrupts->history_index];
494
      h->type = id;
495
      h->taken_cycle = cpu_current_cycle (interrupts->cpu);
496
      h->raised_cycle = interrupts->interrupts[id].cpu_cycle;
497
 
498
      if (interrupts->history_index >= MAX_INT_HISTORY-1)
499
        interrupts->history_index = 0;
500
      else
501
        interrupts->history_index++;
502
 
503
      interrupts->nb_interrupts_raised++;
504
      cpu_add_cycles (interrupts->cpu, 14);
505
      return 1;
506
    }
507
  return 0;
508
}
509
 
510
void
511
interrupts_raise (struct interrupts *interrupts, enum M6811_INT number)
512
{
513
  interrupts->pending_mask |= (1 << number);
514
  interrupts->nb_interrupts_raised ++;
515
}
516
 
517
void
518
interrupts_info (SIM_DESC sd, struct interrupts *interrupts)
519
{
520
  signed64 t;
521
  int i;
522
 
523
  sim_io_printf (sd, "Interrupts Info:\n");
524
  sim_io_printf (sd, "  Interrupts raised: %lu\n",
525
                 interrupts->nb_interrupts_raised);
526
 
527
  if (interrupts->start_mask_cycle >= 0)
528
    {
529
      t = cpu_current_cycle (interrupts->cpu);
530
 
531
      t -= interrupts->start_mask_cycle;
532
      if (t > interrupts->max_mask_cycles)
533
        interrupts->max_mask_cycles = t;
534
 
535
      sim_io_printf (sd, "  Current interrupts masked sequence:   %s\n",
536
                     cycle_to_string (interrupts->cpu, t));
537
    }
538
  t = interrupts->min_mask_cycles == CYCLES_MAX ?
539
    interrupts->max_mask_cycles :
540
    interrupts->min_mask_cycles;
541
  sim_io_printf (sd, "  Shortest interrupts masked sequence:  %s\n",
542
                 cycle_to_string (interrupts->cpu, t));
543
 
544
  t = interrupts->max_mask_cycles;
545
  sim_io_printf (sd, "  Longest interrupts masked sequence:   %s\n",
546
                 cycle_to_string (interrupts->cpu, t));
547
 
548
  t = interrupts->last_mask_cycles;
549
  sim_io_printf (sd, "  Last interrupts masked sequence:      %s\n",
550
                 cycle_to_string (interrupts->cpu, t));
551
 
552
  if (interrupts->xirq_start_mask_cycle >= 0)
553
    {
554
      t = cpu_current_cycle (interrupts->cpu);
555
 
556
      t -= interrupts->xirq_start_mask_cycle;
557
      if (t > interrupts->xirq_max_mask_cycles)
558
        interrupts->xirq_max_mask_cycles = t;
559
 
560
      sim_io_printf (sd, "  XIRQ Current interrupts masked sequence: %s\n",
561
                     cycle_to_string (interrupts->cpu, t));
562
    }
563
 
564
  t = interrupts->xirq_min_mask_cycles == CYCLES_MAX ?
565
    interrupts->xirq_max_mask_cycles :
566
    interrupts->xirq_min_mask_cycles;
567
  sim_io_printf (sd, "  XIRQ Min interrupts masked sequence:  %s\n",
568
                 cycle_to_string (interrupts->cpu, t));
569
 
570
  t = interrupts->xirq_max_mask_cycles;
571
  sim_io_printf (sd, "  XIRQ Max interrupts masked sequence:  %s\n",
572
                 cycle_to_string (interrupts->cpu, t));
573
 
574
  t = interrupts->xirq_last_mask_cycles;
575
  sim_io_printf (sd, "  XIRQ Last interrupts masked sequence: %s\n",
576
                 cycle_to_string (interrupts->cpu, t));
577
 
578
  if (interrupts->pending_mask)
579
    {
580
      sim_io_printf (sd, "  Pending interrupts : ");
581
      for (i = 0; i < M6811_INT_NUMBER; i++)
582
        {
583
          enum M6811_INT int_number = interrupts->interrupt_order[i];
584
 
585
          if (interrupts->pending_mask & (1 << int_number))
586
            {
587
              sim_io_printf (sd, "%s ", interrupt_names[int_number]);
588
            }
589
        }
590
      sim_io_printf (sd, "\n");
591
    }
592
 
593
  for (i = 0; i < MAX_INT_HISTORY; i++)
594
    {
595
      int which;
596
      struct interrupt_history *h;
597
      signed64 dt;
598
 
599
      which = interrupts->history_index - i - 1;
600
      if (which < 0)
601
        which += MAX_INT_HISTORY;
602
      h = &interrupts->interrupts_history[which];
603
      if (h->taken_cycle == 0)
604
        break;
605
 
606
      dt = h->taken_cycle - h->raised_cycle;
607
      sim_io_printf (sd, "%2d %-10.10s %30.30s ", i,
608
                     interrupt_names[h->type],
609
                     cycle_to_string (interrupts->cpu, h->taken_cycle));
610
      sim_io_printf (sd, "%s\n",
611
                     cycle_to_string (interrupts->cpu, dt));
612
    }
613
}

powered by: WebSVN 2.1.0

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