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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [mn10300/] [dv-mn103int.c] - Blame information for rev 309

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

Line No. Rev Author Line
1 24 jeremybenn
/*  This file is part of the program GDB, the GNU debugger.
2
 
3
    Copyright (C) 1998, 2007, 2008 Free Software Foundation, Inc.
4
    Contributed by Cygnus Solutions.
5
 
6
    This program is free software; you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation; either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
19
    */
20
 
21
 
22
#include "sim-main.h"
23
#include "hw-main.h"
24
#include "sim-hw.h"
25
 
26
/* DEVICE
27
 
28
 
29
   mn103int - mn103002 interrupt controller
30
 
31
 
32
   DESCRIPTION
33
 
34
 
35
   Implements the mn103002 interrupt controller described in the
36
   mn103002 user guide.
37
 
38
 
39
   PROPERTIES
40
 
41
 
42
   reg = <icr-adr> <icr-siz> <iagr-adr> <iadr-siz> <extmd-adr> <extmd-siz>
43
 
44
   Specify the address of the ICR (total of 30 registers), IAGR and
45
   EXTMD registers (within the parent bus).
46
 
47
   The reg property value `0x34000100 0x7C 0x34000200 0x8 0x3400280
48
   0x8' locates the interrupt controller at the addresses specified in
49
   the mn103002 interrupt controller user guide.
50
 
51
 
52
   PORTS
53
 
54
 
55
   nmi (output)
56
 
57
   Non-maskable interrupt output port.  An event on this output ports
58
   indicates a NMI request from the interrupt controller.  The value
59
   attached to the event should be ignored.
60
 
61
 
62
   level (output)
63
 
64
   Maskable interrupt level output port.  An event on this output port
65
   indicates a maskable interrupt request at the specified level.  The
66
   event value defines the level being requested.
67
 
68
   The interrupt controller will generate an event on this port
69
   whenever there is a change to the internal state of the interrupt
70
   controller.
71
 
72
 
73
   ack (input)
74
 
75
   Signal from processor indicating that a maskable interrupt has been
76
   accepted and the interrupt controller should latch the IAGR with
77
   value of the current highest priority interrupting group.
78
 
79
   The event value is the interrupt level being accepted by the
80
   processor.  It should be consistent with the most recent LEVEL sent
81
   to the processor from the interrupt controller.
82
 
83
 
84
   int[0..100] (input)
85
 
86
   Level or edge triggered interrupt input port.  Each of the 30
87
   groups (0..30) can have up to 4 (0..3) interrupt inputs.  The
88
   interpretation of a port event/value is determined by the
89
   configuration of the corresponding interrupt group.
90
 
91
   For convenience, numerous aliases to these interrupt inputs are
92
   provided.
93
 
94
 
95
   BUGS
96
 
97
 
98
   For edge triggered interrupts, the interrupt controller does not
99
   differentiate between POSITIVE (rising) and NEGATIVE (falling)
100
   edges.  Instead any input port event is considered to be an
101
   interrupt trigger.
102
 
103
   For level sensitive interrupts, the interrupt controller ignores
104
   active HIGH/LOW settings and instead always interprets a nonzero
105
   port value as an interrupt assertion and a zero port value as a
106
   negation.
107
 
108
   */
109
 
110
 
111
/* The interrupt groups - numbered according to mn103002 convention */
112
 
113
enum mn103int_trigger {
114
  ACTIVE_LOW,
115
  ACTIVE_HIGH,
116
  POSITIVE_EDGE,
117
  NEGATIVE_EDGE,
118
};
119
 
120
enum mn103int_type {
121
  NMI_GROUP,
122
  LEVEL_GROUP,
123
};
124
 
125
struct mn103int_group {
126
  int gid;
127
  int level;
128
  unsigned enable;
129
  unsigned request;
130
  unsigned input;
131
  enum mn103int_trigger trigger;
132
  enum mn103int_type type;
133
};
134
 
135
enum {
136
  FIRST_NMI_GROUP = 0,
137
  LAST_NMI_GROUP = 1,
138
  FIRST_LEVEL_GROUP = 2,
139
  LAST_LEVEL_GROUP = 30,
140
  NR_GROUPS,
141
};
142
 
143
enum {
144
  LOWEST_LEVEL = 7,
145
};
146
 
147
/* The interrupt controller register address blocks */
148
 
149
struct mn103int_block {
150
  unsigned_word base;
151
  unsigned_word bound;
152
};
153
 
154
enum { ICR_BLOCK, IAGR_BLOCK, EXTMD_BLOCK, NR_BLOCKS };
155
 
156
 
157
struct mn103int {
158
  struct mn103int_block block[NR_BLOCKS];
159
  struct mn103int_group group[NR_GROUPS];
160
  unsigned interrupt_accepted_group;
161
};
162
 
163
 
164
 
165
/* output port ID's */
166
 
167
enum {
168
  NMI_PORT,
169
  LEVEL_PORT,
170
};
171
 
172
 
173
/* input port ID's */
174
 
175
enum {
176
  G0_PORT = 0,
177
  G1_PORT = 4,
178
  G2_PORT = 8,
179
  G3_PORT = 12,
180
  G4_PORT = 16,
181
  G5_PORT = 20,
182
  G6_PORT = 24,
183
  G7_PORT = 28,
184
  G8_PORT = 32,
185
  G9_PORT = 36,
186
  G10_PORT = 40,
187
  G11_PORT = 44,
188
  G12_PORT = 48,
189
  G13_PORT = 52,
190
  G14_PORT = 56,
191
  G15_PORT = 60,
192
  G16_PORT = 64,
193
  G17_PORT = 68,
194
  G18_PORT = 72,
195
  G19_PORT = 76,
196
  G20_PORT = 80,
197
  G21_PORT = 84,
198
  G22_PORT = 88,
199
  G23_PORT = 92,
200
  IRQ0_PORT = G23_PORT,
201
  G24_PORT = 96,
202
  G25_PORT = 100,
203
  G26_PORT = 104,
204
  G27_PORT = 108,
205
  IRQ4_PORT = G27_PORT,
206
  G28_PORT = 112,
207
  G29_PORT = 116,
208
  G30_PORT = 120,
209
  NR_G_PORTS = 124,
210
  ACK_PORT,
211
};
212
 
213
static const struct hw_port_descriptor mn103int_ports[] = {
214
 
215
  /* interrupt outputs */
216
 
217
  { "nmi", NMI_PORT, 0, output_port, },
218
  { "level", LEVEL_PORT, 0, output_port, },
219
 
220
  /* interrupt ack (latch) input from cpu */
221
 
222
  { "ack", ACK_PORT, 0, input_port, },
223
 
224
  /* interrupt inputs (as names) */
225
 
226
  { "nmirq", G0_PORT + 0, 0, input_port, },
227
  { "watchdog", G0_PORT + 1, 0, input_port, },
228
  { "syserr", G0_PORT + 2, 0, input_port, },
229
 
230
  { "timer-0-underflow", G2_PORT, 0, input_port, },
231
  { "timer-1-underflow", G3_PORT, 0, input_port, },
232
  { "timer-2-underflow", G4_PORT, 0, input_port, },
233
  { "timer-3-underflow", G5_PORT, 0, input_port, },
234
  { "timer-4-underflow", G6_PORT, 0, input_port, },
235
  { "timer-5-underflow", G7_PORT, 0, input_port, },
236
  { "timer-6-underflow", G8_PORT, 0, input_port, },
237
 
238
  { "timer-6-compare-a", G9_PORT, 0, input_port, },
239
  { "timer-6-compare-b", G10_PORT, 0, input_port, },
240
 
241
  { "dma-0-end", G12_PORT, 0, input_port, },
242
  { "dma-1-end", G13_PORT, 0, input_port, },
243
  { "dma-2-end", G14_PORT, 0, input_port, },
244
  { "dma-3-end", G15_PORT, 0, input_port, },
245
 
246
  { "serial-0-receive",  G16_PORT, 0, input_port, },
247
  { "serial-0-transmit", G17_PORT, 0, input_port, },
248
 
249
  { "serial-1-receive",  G18_PORT, 0, input_port, },
250
  { "serial-1-transmit", G19_PORT, 0, input_port, },
251
 
252
  { "serial-2-receive",  G20_PORT, 0, input_port, },
253
  { "serial-2-transmit", G21_PORT, 0, input_port, },
254
 
255
  { "irq-0", G23_PORT, 0, input_port, },
256
  { "irq-1", G24_PORT, 0, input_port, },
257
  { "irq-2", G25_PORT, 0, input_port, },
258
  { "irq-3", G26_PORT, 0, input_port, },
259
  { "irq-4", G27_PORT, 0, input_port, },
260
  { "irq-5", G28_PORT, 0, input_port, },
261
  { "irq-6", G29_PORT, 0, input_port, },
262
  { "irq-7", G30_PORT, 0, input_port, },
263
 
264
  /* interrupt inputs (as generic numbers) */
265
 
266
  { "int", 0, NR_G_PORTS, input_port, },
267
 
268
  { NULL, },
269
};
270
 
271
 
272
/* Macros for extracting/restoring the various register bits */
273
 
274
#define EXTRACT_ID(X) (LSEXTRACTED8 ((X), 3, 0))
275
#define INSERT_ID(X) (LSINSERTED8 ((X), 3, 0))
276
 
277
#define EXTRACT_IR(X) (LSEXTRACTED8 ((X), 7, 4))
278
#define INSERT_IR(X) (LSINSERTED8 ((X), 7, 4))
279
 
280
#define EXTRACT_IE(X) (LSEXTRACTED8 ((X), 3, 0))
281
#define INSERT_IE(X) (LSINSERTED8 ((X), 3, 0))
282
 
283
#define EXTRACT_LV(X) (LSEXTRACTED8 ((X), 6, 4))
284
#define INSERT_LV(X) (LSINSERTED8 ((X), 6, 4))
285
 
286
 
287
 
288
/* Finish off the partially created hw device.  Attach our local
289
   callbacks.  Wire up our port names etc */
290
 
291
static hw_io_read_buffer_method mn103int_io_read_buffer;
292
static hw_io_write_buffer_method mn103int_io_write_buffer;
293
static hw_port_event_method mn103int_port_event;
294
static hw_ioctl_method mn103int_ioctl;
295
 
296
 
297
 
298
static void
299
attach_mn103int_regs (struct hw *me,
300
                      struct mn103int *controller)
301
{
302
  int i;
303
  if (hw_find_property (me, "reg") == NULL)
304
    hw_abort (me, "Missing \"reg\" property");
305
  for (i = 0; i < NR_BLOCKS; i++)
306
    {
307
      unsigned_word attach_address;
308
      int attach_space;
309
      unsigned attach_size;
310
      reg_property_spec reg;
311
      if (!hw_find_reg_array_property (me, "reg", i, &reg))
312
        hw_abort (me, "\"reg\" property must contain three addr/size entries");
313
      hw_unit_address_to_attach_address (hw_parent (me),
314
                                         &reg.address,
315
                                         &attach_space,
316
                                         &attach_address,
317
                                         me);
318
      controller->block[i].base = attach_address;
319
      hw_unit_size_to_attach_size (hw_parent (me),
320
                                   &reg.size,
321
                                   &attach_size, me);
322
      controller->block[i].bound = attach_address + (attach_size - 1);
323
      hw_attach_address (hw_parent (me),
324
                         0,
325
                         attach_space, attach_address, attach_size,
326
                         me);
327
    }
328
}
329
 
330
static void
331
mn103int_finish (struct hw *me)
332
{
333
  int gid;
334
  struct mn103int *controller;
335
 
336
  controller = HW_ZALLOC (me, struct mn103int);
337
  set_hw_data (me, controller);
338
  set_hw_io_read_buffer (me, mn103int_io_read_buffer);
339
  set_hw_io_write_buffer (me, mn103int_io_write_buffer);
340
  set_hw_ports (me, mn103int_ports);
341
  set_hw_port_event (me, mn103int_port_event);
342
  me->to_ioctl = mn103int_ioctl;
343
 
344
  /* Attach ourself to our parent bus */
345
  attach_mn103int_regs (me, controller);
346
 
347
  /* Initialize all the groups according to their default configuration */
348
  for (gid = 0; gid < NR_GROUPS; gid++)
349
    {
350
      struct mn103int_group *group = &controller->group[gid];
351
      group->trigger = NEGATIVE_EDGE;
352
      group->gid = gid;
353
      if (FIRST_NMI_GROUP <= gid && gid <= LAST_NMI_GROUP)
354
        {
355
          group->enable = 0xf;
356
          group->type = NMI_GROUP;
357
        }
358
      else if (FIRST_LEVEL_GROUP <= gid && gid <= LAST_LEVEL_GROUP)
359
        {
360
          group->enable = 0x0;
361
          group->type = LEVEL_GROUP;
362
        }
363
      else
364
        hw_abort (me, "internal error - unknown group id");
365
    }
366
}
367
 
368
 
369
 
370
/* Perform the nasty work of figuring out which of the interrupt
371
   groups should have its interrupt delivered. */
372
 
373
static int
374
find_highest_interrupt_group (struct hw *me,
375
                              struct mn103int *controller)
376
{
377
  int gid;
378
  int selected;
379
 
380
  /* FIRST_NMI_GROUP (group zero) is used as a special default value
381
     when searching for an interrupt group.*/
382
  selected = FIRST_NMI_GROUP;
383
  controller->group[FIRST_NMI_GROUP].level = 7;
384
 
385
  for (gid = FIRST_LEVEL_GROUP; gid <= LAST_LEVEL_GROUP; gid++)
386
    {
387
      struct mn103int_group *group = &controller->group[gid];
388
      if ((group->request & group->enable) != 0)
389
        {
390
          /* Remember, lower level, higher priority.  */
391
          if (group->level < controller->group[selected].level)
392
            {
393
              selected = gid;
394
            }
395
        }
396
    }
397
  return selected;
398
}
399
 
400
 
401
/* Notify the processor of an interrupt level update */
402
 
403
static void
404
push_interrupt_level (struct hw *me,
405
                      struct mn103int *controller)
406
{
407
  int selected = find_highest_interrupt_group (me, controller);
408
  int level = controller->group[selected].level;
409
  HW_TRACE ((me, "port-out - selected=%d level=%d", selected, level));
410
  hw_port_event (me, LEVEL_PORT, level);
411
}
412
 
413
 
414
/* An event arrives on an interrupt port */
415
 
416
static void
417
mn103int_port_event (struct hw *me,
418
                     int my_port,
419
                     struct hw *source,
420
                     int source_port,
421
                     int level)
422
{
423
  struct mn103int *controller = hw_data (me);
424
 
425
  switch (my_port)
426
    {
427
 
428
    case ACK_PORT:
429
      {
430
        int selected = find_highest_interrupt_group (me, controller);
431
        if (controller->group[selected].level != level)
432
          hw_abort (me, "botched level synchronisation");
433
        controller->interrupt_accepted_group = selected;
434
        HW_TRACE ((me, "port-event port=ack level=%d - selected=%d",
435
                   level, selected));
436
        break;
437
      }
438
 
439
    default:
440
      {
441
        int gid;
442
        int iid;
443
        struct mn103int_group *group;
444
        unsigned interrupt;
445
        if (my_port > NR_G_PORTS)
446
          hw_abort (me, "Event on unknown port %d", my_port);
447
 
448
        /* map the port onto an interrupt group */
449
        gid = (my_port % NR_G_PORTS) / 4;
450
        group = &controller->group[gid];
451
        iid = (my_port % 4);
452
        interrupt = 1 << iid;
453
 
454
        /* update our cached input */
455
        if (level)
456
          group->input |= interrupt;
457
        else
458
          group->input &= ~interrupt;
459
 
460
        /* update the request bits */
461
        switch (group->trigger)
462
          {
463
          case ACTIVE_LOW:
464
          case ACTIVE_HIGH:
465
            if (level)
466
              group->request |= interrupt;
467
            break;
468
          case NEGATIVE_EDGE:
469
          case POSITIVE_EDGE:
470
            group->request |= interrupt;
471
          }
472
 
473
        /* force a corresponding output */
474
        switch (group->type)
475
          {
476
 
477
          case NMI_GROUP:
478
            {
479
              /* for NMI's the event is the trigger */
480
              HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - NMI",
481
                         my_port, gid, iid));
482
              if ((group->request & group->enable) != 0)
483
                {
484
                  HW_TRACE ((me, "port-out NMI"));
485
                  hw_port_event (me, NMI_PORT, 1);
486
                }
487
              break;
488
            }
489
 
490
          case LEVEL_GROUP:
491
            {
492
              /* if an interrupt is now pending */
493
              HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - INT",
494
                         my_port, gid, iid));
495
              push_interrupt_level (me, controller);
496
              break;
497
            }
498
          }
499
        break;
500
      }
501
 
502
    }
503
}
504
 
505
/* Read/write to to an ICR (group control register) */
506
 
507
static struct mn103int_group *
508
decode_group (struct hw *me,
509
              struct mn103int *controller,
510
              unsigned_word base,
511
              unsigned_word *offset)
512
{
513
  int gid = (base / 4) % NR_GROUPS;
514
  *offset = (base % 4);
515
  return &controller->group[gid];
516
}
517
 
518
static unsigned8
519
read_icr (struct hw *me,
520
          struct mn103int *controller,
521
          unsigned_word base)
522
{
523
  unsigned_word offset;
524
  struct mn103int_group *group = decode_group (me, controller, base, &offset);
525
  unsigned8 val = 0;
526
  switch (group->type)
527
    {
528
 
529
    case NMI_GROUP:
530
      switch (offset)
531
        {
532
        case 0:
533
          val = INSERT_ID (group->request);
534
          HW_TRACE ((me, "read-icr group=%d:0 nmi 0x%02x",
535
                     group->gid, val));
536
          break;
537
        default:
538
          break;
539
        }
540
      break;
541
 
542
    case LEVEL_GROUP:
543
      switch (offset)
544
        {
545
        case 0:
546
          val = (INSERT_IR (group->request)
547
                 | INSERT_ID (group->request & group->enable));
548
          HW_TRACE ((me, "read-icr group=%d:0 level 0x%02x",
549
                     group->gid, val));
550
          break;
551
        case 1:
552
          val = (INSERT_LV (group->level)
553
                 | INSERT_IE (group->enable));
554
          HW_TRACE ((me, "read-icr level-%d:1 level 0x%02x",
555
                     group->gid, val));
556
          break;
557
        }
558
      break;
559
 
560
    default:
561
      break;
562
 
563
    }
564
 
565
  return val;
566
}
567
 
568
static void
569
write_icr (struct hw *me,
570
           struct mn103int *controller,
571
           unsigned_word base,
572
           unsigned8 val)
573
{
574
  unsigned_word offset;
575
  struct mn103int_group *group = decode_group (me, controller, base, &offset);
576
  switch (group->type)
577
    {
578
 
579
    case NMI_GROUP:
580
      switch (offset)
581
        {
582
        case 0:
583
          HW_TRACE ((me, "write-icr group=%d:0 nmi 0x%02x",
584
                     group->gid, val));
585
          group->request &= ~EXTRACT_ID (val);
586
          break;
587
          /* Special backdoor access to SYSEF flag from CPU.  See
588
             interp.c:program_interrupt(). */
589
        case 3:
590
          HW_TRACE ((me, "write-icr-special group=%d:0 nmi 0x%02x",
591
                     group->gid, val));
592
          group->request |= EXTRACT_ID (val);
593
        default:
594
          break;
595
        }
596
      break;
597
 
598
    case LEVEL_GROUP:
599
      switch (offset)
600
        {
601
        case 0: /* request/detect */
602
          /* Clear any ID bits and then set them according to IR */
603
          HW_TRACE ((me, "write-icr group=%d:0 level 0x%02x %x:%x:%x",
604
                     group->gid, val,
605
                     group->request, EXTRACT_IR (val), EXTRACT_ID (val)));
606
          group->request =
607
            ((EXTRACT_IR (val) & EXTRACT_ID (val))
608
             | (EXTRACT_IR (val) & group->request)
609
             | (~EXTRACT_IR (val) & ~EXTRACT_ID (val) & group->request));
610
          break;
611
        case 1: /* level/enable */
612
          HW_TRACE ((me, "write-icr group=%d:1 level 0x%02x",
613
                     group->gid, val));
614
          group->level = EXTRACT_LV (val);
615
          group->enable = EXTRACT_IE (val);
616
          break;
617
        default:
618
          /* ignore */
619
          break;
620
        }
621
      push_interrupt_level (me, controller);
622
      break;
623
 
624
    default:
625
      break;
626
 
627
    }
628
}
629
 
630
 
631
/* Read the IAGR (Interrupt accepted group register) */
632
 
633
static unsigned8
634
read_iagr (struct hw *me,
635
           struct mn103int *controller,
636
           unsigned_word offset)
637
{
638
  unsigned8 val;
639
  switch (offset)
640
    {
641
    case 0:
642
      {
643
        if (!(controller->group[controller->interrupt_accepted_group].request
644
              & controller->group[controller->interrupt_accepted_group].enable))
645
          {
646
            /* oops, lost the request */
647
            val = 0;
648
            HW_TRACE ((me, "read-iagr:0 lost-0"));
649
          }
650
        else
651
          {
652
            val = (controller->interrupt_accepted_group << 2);
653
            HW_TRACE ((me, "read-iagr:0 %d", (int) val));
654
          }
655
        break;
656
      }
657
    case 1:
658
      val = 0;
659
      HW_TRACE ((me, "read-iagr:1 %d", (int) val));
660
      break;
661
    default:
662
      val = 0;
663
      HW_TRACE ((me, "read-iagr 0x%08lx bad offset", (long) offset));
664
      break;
665
    }
666
  return val;
667
}
668
 
669
 
670
/* Reads/writes to the EXTMD (external interrupt trigger configuration
671
   register) */
672
 
673
static struct mn103int_group *
674
external_group (struct mn103int *controller,
675
                unsigned_word offset)
676
{
677
  switch (offset)
678
    {
679
    case 0:
680
      return &controller->group[IRQ0_PORT/4];
681
    case 1:
682
      return &controller->group[IRQ4_PORT/4];
683
    default:
684
      return NULL;
685
    }
686
}
687
 
688
static unsigned8
689
read_extmd (struct hw *me,
690
            struct mn103int *controller,
691
            unsigned_word offset)
692
{
693
  int gid;
694
  unsigned8 val = 0;
695
  struct mn103int_group *group = external_group (controller, offset);
696
  if (group != NULL)
697
    {
698
      for (gid = 0; gid < 4; gid++)
699
        {
700
          val |= (group[gid].trigger << (gid * 2));
701
        }
702
    }
703
  HW_TRACE ((me, "read-extmd 0x%02lx", (long) val));
704
  return val;
705
}
706
 
707
static void
708
write_extmd (struct hw *me,
709
             struct mn103int *controller,
710
             unsigned_word offset,
711
             unsigned8 val)
712
{
713
  int gid;
714
  struct mn103int_group *group = external_group (controller, offset);
715
  if (group != NULL)
716
    {
717
      for (gid = 0; gid < 4; gid++)
718
        {
719
          group[gid].trigger = (val >> (gid * 2)) & 0x3;
720
          /* MAYBE: interrupts already pending? */
721
        }
722
    }
723
  HW_TRACE ((me, "write-extmd 0x%02lx", (long) val));
724
}
725
 
726
 
727
/* generic read/write */
728
 
729
static int
730
decode_addr (struct hw *me,
731
             struct mn103int *controller,
732
             unsigned_word address,
733
             unsigned_word *offset)
734
{
735
  int i;
736
  for (i = 0; i < NR_BLOCKS; i++)
737
    {
738
      if (address >= controller->block[i].base
739
          && address <= controller->block[i].bound)
740
        {
741
          *offset = address - controller->block[i].base;
742
          return i;
743
        }
744
    }
745
  hw_abort (me, "bad address");
746
  return -1;
747
}
748
 
749
static unsigned
750
mn103int_io_read_buffer (struct hw *me,
751
                         void *dest,
752
                         int space,
753
                         unsigned_word base,
754
                         unsigned nr_bytes)
755
{
756
  struct mn103int *controller = hw_data (me);
757
  unsigned8 *buf = dest;
758
  unsigned byte;
759
  /* HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); */
760
  for (byte = 0; byte < nr_bytes; byte++)
761
    {
762
      unsigned_word address = base + byte;
763
      unsigned_word offset;
764
      switch (decode_addr (me, controller, address, &offset))
765
        {
766
        case ICR_BLOCK:
767
          buf[byte] = read_icr (me, controller, offset);
768
          break;
769
        case IAGR_BLOCK:
770
          buf[byte] = read_iagr (me, controller, offset);
771
          break;
772
        case EXTMD_BLOCK:
773
          buf[byte] = read_extmd (me, controller, offset);
774
          break;
775
        default:
776
          hw_abort (me, "bad switch");
777
        }
778
    }
779
  return nr_bytes;
780
}
781
 
782
static unsigned
783
mn103int_io_write_buffer (struct hw *me,
784
                          const void *source,
785
                          int space,
786
                          unsigned_word base,
787
                          unsigned nr_bytes)
788
{
789
  struct mn103int *controller = hw_data (me);
790
  const unsigned8 *buf = source;
791
  unsigned byte;
792
  /* HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); */
793
  for (byte = 0; byte < nr_bytes; byte++)
794
    {
795
      unsigned_word address = base + byte;
796
      unsigned_word offset;
797
      switch (decode_addr (me, controller, address, &offset))
798
        {
799
        case ICR_BLOCK:
800
          write_icr (me, controller, offset, buf[byte]);
801
          break;
802
        case IAGR_BLOCK:
803
          /* not allowed */
804
          break;
805
        case EXTMD_BLOCK:
806
          write_extmd (me, controller, offset, buf[byte]);
807
          break;
808
        default:
809
          hw_abort (me, "bad switch");
810
        }
811
    }
812
  return nr_bytes;
813
}
814
 
815
static int
816
mn103int_ioctl(struct hw *me,
817
               hw_ioctl_request request,
818
               va_list ap)
819
{
820
  struct mn103int *controller = (struct mn103int *)hw_data(me);
821
  controller->group[0].request = EXTRACT_ID(4);
822
  mn103int_port_event(me, 2 /* nmi_port(syserr) */, NULL, 0, 0);
823
  return 0;
824
}
825
 
826
 
827
const struct hw_descriptor dv_mn103int_descriptor[] = {
828
  { "mn103int", mn103int_finish, },
829
  { NULL },
830
};

powered by: WebSVN 2.1.0

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