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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [mn10300/] [dv-mn103int.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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