Fix interrupt settings for mn103002, not mn10300 implementation.
[external/binutils.git] / sim / mn10300 / dv-mn103int.c
1 /*  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
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 25 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   G24_PORT = 96,
201   G25_PORT = 100,
202   G26_PORT = 104,
203   G27_PORT = 108,
204   G28_PORT = 112,
205   G29_PORT = 116,
206   G30_PORT = 120,
207   NR_G_PORTS = 124,
208   ACK_PORT,
209 };
210
211 static const struct hw_port_descriptor mn103int_ports[] = {
212
213   /* interrupt outputs */
214
215   { "nmi", NMI_PORT, 0, output_port, },
216   { "level", LEVEL_PORT, 0, output_port, },
217
218   /* interrupt ack (latch) input from cpu */
219
220   { "ack", ACK_PORT, 0, input_port, },
221
222   /* interrupt inputs (as names) */
223
224   { "nmirq", G0_PORT + 0, 0, input_port, },
225   { "watchdog", G0_PORT + 1, 0, input_port, },
226   { "syserr", G0_PORT + 2, 0, input_port, },
227
228   { "timer-0-underflow", G2_PORT, 0, input_port, },
229   { "timer-1-underflow", G3_PORT, 0, input_port, },
230   { "timer-2-underflow", G4_PORT, 0, input_port, },
231   { "timer-3-underflow", G5_PORT, 0, input_port, },
232   { "timer-4-underflow", G6_PORT, 0, input_port, },
233   { "timer-5-underflow", G7_PORT, 0, input_port, },
234   { "timer-6-underflow", G8_PORT, 0, input_port, },
235
236   { "timer-6-compare-a", G9_PORT, 0, input_port, },
237   { "timer-6-compare-b", G10_PORT, 0, input_port, },
238
239   { "dma-0-end", G12_PORT, 0, input_port, },
240   { "dma-1-end", G13_PORT, 0, input_port, },
241   { "dma-2-end", G14_PORT, 0, input_port, },
242   { "dma-3-end", G15_PORT, 0, input_port, },
243
244   { "serial-0-receive",  G16_PORT, 0, input_port, },
245   { "serial-0-transmit", G17_PORT, 0, input_port, },
246
247   { "serial-1-receive",  G18_PORT, 0, input_port, },
248   { "serial-1-transmit", G19_PORT, 0, input_port, },
249
250   { "serial-2-receive",  G20_PORT, 0, input_port, },
251   { "serial-2-transmit", G21_PORT, 0, input_port, },
252
253   { "irq-0", G23_PORT, 0, input_port, },
254   { "irq-1", G24_PORT, 0, input_port, },
255   { "irq-2", G25_PORT, 0, input_port, },
256   { "irq-3", G26_PORT, 0, input_port, },
257   { "irq-4", G27_PORT, 0, input_port, },
258   { "irq-5", G28_PORT, 0, input_port, },
259   { "irq-6", G29_PORT, 0, input_port, },
260   { "irq-7", G30_PORT, 0, input_port, },
261
262   /*   { "ad-end", G24_PORT, 0, input_port, },  a/d conversion end, not in 103002? */ 
263
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
296 static void
297 attach_mn103int_regs (struct hw *me,
298                       struct mn103int *controller)
299 {
300   int i;
301   if (hw_find_property (me, "reg") == NULL)
302     hw_abort (me, "Missing \"reg\" property");
303   for (i = 0; i < NR_BLOCKS; i++)
304     {
305       unsigned_word attach_address;
306       int attach_space;
307       unsigned attach_size;
308       reg_property_spec reg;
309       if (!hw_find_reg_array_property (me, "reg", i, &reg))
310         hw_abort (me, "\"reg\" property must contain three addr/size entries");
311       hw_unit_address_to_attach_address (hw_parent (me),
312                                          &reg.address,
313                                          &attach_space,
314                                          &attach_address,
315                                          me);
316       controller->block[i].base = attach_address;
317       hw_unit_size_to_attach_size (hw_parent (me),
318                                    &reg.size,
319                                    &attach_size, me);
320       controller->block[i].bound = attach_address + (attach_size - 1);
321       hw_attach_address (hw_parent (me),
322                          0,
323                          attach_space, attach_address, attach_size,
324                          me);
325     }
326 }
327
328 static void
329 mn103int_finish (struct hw *me)
330 {
331   int gid;
332   struct mn103int *controller;
333
334   controller = HW_ZALLOC (me, struct mn103int);
335   set_hw_data (me, controller);
336   set_hw_io_read_buffer (me, mn103int_io_read_buffer);
337   set_hw_io_write_buffer (me, mn103int_io_write_buffer);
338   set_hw_ports (me, mn103int_ports);
339   set_hw_port_event (me, mn103int_port_event);
340
341   /* Attach ourself to our parent bus */
342   attach_mn103int_regs (me, controller);
343
344   /* Initialize all the groups according to their default configuration */
345   for (gid = 0; gid < NR_GROUPS; gid++)
346     {
347       struct mn103int_group *group = &controller->group[gid];
348       group->enable = 0xf;
349       group->trigger = NEGATIVE_EDGE;
350       group->gid = gid;
351       if (FIRST_NMI_GROUP <= gid && gid <= LAST_NMI_GROUP)
352         {
353           group->type = NMI_GROUP;
354         }
355       else if (FIRST_LEVEL_GROUP <= gid && gid <= LAST_LEVEL_GROUP)
356         {
357           group->type = LEVEL_GROUP;
358         }
359       else
360         hw_abort (me, "internal error - unknown group id");
361     }
362 }
363
364
365
366 /* Perform the nasty work of figuring out which of the interrupt
367    groups should have its interrupt delivered. */
368
369 static int
370 find_highest_interrupt_group (struct hw *me,
371                               struct mn103int *controller)
372 {
373   int gid;
374   int selected;
375
376   /* FIRST_NMI_GROUP (group zero) is used as a special default value
377      when searching for an interrupt group.*/
378   selected = FIRST_NMI_GROUP; 
379   controller->group[FIRST_NMI_GROUP].level = 7;
380   
381   for (gid = FIRST_LEVEL_GROUP; gid <= LAST_LEVEL_GROUP; gid++)
382     {
383       struct mn103int_group *group = &controller->group[gid];
384       if ((group->request & group->enable) != 0)
385         {
386           /* Remember, lower level, higher priority.  */
387           if (group->level < controller->group[selected].level)
388             {
389               selected = gid;
390             }
391         }
392     }
393   return selected;
394 }
395
396
397 /* Notify the processor of an interrupt level update */
398
399 static void
400 push_interrupt_level (struct hw *me,
401                       struct mn103int *controller)
402 {
403   int selected = find_highest_interrupt_group (me, controller);
404   int level = controller->group[selected].level;
405   HW_TRACE ((me, "port-out - selected=%d level=%d", selected, level));
406   hw_port_event (me, LEVEL_PORT, level);
407 }
408
409
410 /* An event arrives on an interrupt port */
411
412 static void
413 mn103int_port_event (struct hw *me,
414                      int my_port,
415                      struct hw *source,
416                      int source_port,
417                      int level)
418 {
419   struct mn103int *controller = hw_data (me);
420
421   switch (my_port)
422     {
423
424     case ACK_PORT:
425       {
426         int selected = find_highest_interrupt_group (me, controller);
427         if (controller->group[selected].level != level)
428           hw_abort (me, "botched level synchronisation");
429         controller->interrupt_accepted_group = selected;        
430         HW_TRACE ((me, "port-event port=ack level=%d - selected=%d",
431                    level, selected));
432         break;
433       }
434
435     default:
436       {
437         int gid;
438         int iid;
439         struct mn103int_group *group;
440         unsigned interrupt;
441         if (my_port > NR_G_PORTS)
442           hw_abort (me, "Event on unknown port %d", my_port);
443
444         /* map the port onto an interrupt group */
445         gid = (my_port % NR_G_PORTS) / 4;
446         group = &controller->group[gid];
447         iid = (my_port % 4);
448         interrupt = 1 << iid;
449
450         /* update our cached input */
451         if (level)
452           group->input |= interrupt;
453         else
454           group->input &= ~interrupt;
455
456         /* update the request bits */
457         switch (group->trigger)
458           {
459           case ACTIVE_LOW:
460           case ACTIVE_HIGH:
461             if (level)
462               group->request |= interrupt;
463             break;
464           case NEGATIVE_EDGE:
465           case POSITIVE_EDGE:
466             group->request |= interrupt;
467           }
468
469         /* force a corresponding output */
470         switch (group->type)
471           {
472
473           case NMI_GROUP:
474             {
475               /* for NMI's the event is the trigger */
476               HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - NMI",
477                          my_port, gid, iid));
478               if ((group->request & group->enable) != 0)
479                 {
480                   HW_TRACE ((me, "port-out NMI"));
481                   hw_port_event (me, NMI_PORT, 1);
482                 }
483               break;
484             }
485               
486           case LEVEL_GROUP:
487             {
488               /* if an interrupt is now pending */
489               HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - INT",
490                          my_port, gid, iid));
491               push_interrupt_level (me, controller);
492               break;
493             }
494           }
495         break;
496       }
497
498     }
499 }
500
501 /* Read/write to to an ICR (group control register) */
502
503 static struct mn103int_group *
504 decode_group (struct hw *me,
505               struct mn103int *controller,
506               unsigned_word base,
507               unsigned_word *offset)
508 {
509   int gid = (base / 4) % NR_GROUPS;
510   *offset = (base % 4);
511   return &controller->group[gid];
512 }
513
514 static unsigned8
515 read_icr (struct hw *me,
516           struct mn103int *controller,
517           unsigned_word base)
518 {
519   unsigned_word offset;
520   struct mn103int_group *group = decode_group (me, controller, base, &offset);
521   unsigned8 val = 0;
522   switch (group->type)
523     {
524
525     case NMI_GROUP:
526       switch (offset)
527         {
528         case 0:
529           val = INSERT_ID (group->request);
530           HW_TRACE ((me, "read-icr group=%d:0 nmi 0x%02x",
531                      group->gid, val));
532           break;
533         default:
534           break;
535         }
536       break;
537
538     case LEVEL_GROUP:
539       switch (offset)
540         {
541         case 0:
542           val = (INSERT_IR (group->request)
543                  | INSERT_ID (group->request & group->enable));
544           HW_TRACE ((me, "read-icr group=%d:0 level 0x%02x",
545                      group->gid, val));
546           break;
547         case 1:
548           val = (INSERT_LV (group->level)
549                  | INSERT_IE (group->enable));
550           HW_TRACE ((me, "read-icr level-%d:1 level 0x%02x",
551                      group->gid, val));
552           break;
553         }
554       break;
555
556     default:
557       break;
558
559     }
560
561   return val;
562 }
563
564 static void
565 write_icr (struct hw *me,
566            struct mn103int *controller,
567            unsigned_word base,
568            unsigned8 val)
569 {
570   unsigned_word offset;
571   struct mn103int_group *group = decode_group (me, controller, base, &offset);
572   switch (group->type)
573     {
574
575     case NMI_GROUP:
576       switch (offset)
577         {
578         case 0:
579           HW_TRACE ((me, "write-icr group=%d:0 nmi 0x%02x",
580                      group->gid, val));
581           group->request &= ~EXTRACT_ID (val);
582           break;
583         default:
584           break;
585         }
586       break;
587
588     case LEVEL_GROUP:
589       switch (offset)
590         {
591         case 0: /* request/detect */
592           /* Clear any ID bits and then set them according to IR */
593           HW_TRACE ((me, "write-icr group=%d:0 level 0x%02x %x:%x:%x",
594                      group->gid, val,
595                      group->request, EXTRACT_IR (val), EXTRACT_ID (val)));
596           group->request =
597             ((EXTRACT_IR (val) & EXTRACT_ID (val))
598              | (EXTRACT_IR (val) & group->request)
599              | (~EXTRACT_IR (val) & ~EXTRACT_ID (val) & group->request));
600           break;
601         case 1: /* level/enable */
602           HW_TRACE ((me, "write-icr group=%d:1 level 0x%02x",
603                      group->gid, val));
604           group->level = EXTRACT_LV (val);
605           group->enable = EXTRACT_IE (val);
606           break;
607         default:
608           /* ignore */
609           break;
610         }
611       push_interrupt_level (me, controller);
612       break;
613
614     default:
615       break;
616
617     }
618 }
619
620
621 /* Read the IAGR (Interrupt accepted group register) */
622
623 static unsigned8
624 read_iagr (struct hw *me,
625            struct mn103int *controller,
626            unsigned_word offset)
627 {
628   unsigned8 val;
629   switch (offset)
630     {
631     case 0:
632       {
633         if (!(controller->group[controller->interrupt_accepted_group].request
634               & controller->group[controller->interrupt_accepted_group].enable))
635           {
636             /* oops, lost the request */
637             val = 0;
638             HW_TRACE ((me, "read-iagr:0 lost-0"));
639           }
640         else
641           {
642             val = (controller->interrupt_accepted_group << 2);
643             HW_TRACE ((me, "read-iagr:0 %d", (int) val));
644           }
645         break;
646       }
647     case 1:
648       val = 0;
649       HW_TRACE ((me, "read-iagr:1 %d", (int) val));
650       break;
651     default:
652       val = 0;
653       HW_TRACE ((me, "read-iagr 0x%08lx bad offset", (long) offset));
654       break;
655     }
656   return val;
657 }
658
659
660 /* Reads/writes to the EXTMD (external interrupt trigger configuration
661    register) */
662
663 static struct mn103int_group *
664 external_group (struct mn103int *controller,
665                 unsigned_word offset)
666 {
667   switch (offset)
668     {
669     case 0:
670       return &controller->group[16];
671     case 1:
672       return &controller->group[20];
673     default:
674       return NULL;
675     }
676 }
677
678 static unsigned8
679 read_extmd (struct hw *me,
680             struct mn103int *controller,
681             unsigned_word offset)
682 {
683   int gid;
684   unsigned8 val = 0;
685   struct mn103int_group *group = external_group (controller, offset);
686   if (group != NULL)
687     {
688       for (gid = 0; gid < 4; gid++)
689         {
690           val |= (group[gid].trigger << (gid * 2));
691         }
692     }
693   HW_TRACE ((me, "read-extmd 0x%02lx", (long) val));
694   return val;
695 }
696
697 static void
698 write_extmd (struct hw *me,
699              struct mn103int *controller,
700              unsigned_word offset,
701              unsigned8 val)
702 {
703   int gid;
704   struct mn103int_group *group = external_group (controller, offset);
705   if (group != NULL)
706     {
707       for (gid = 0; gid < 4; gid++)
708         {
709           group[gid].trigger = (val >> (gid * 2)) & 0x3;
710           /* MAYBE: interrupts already pending? */
711         }
712     }
713   HW_TRACE ((me, "write-extmd 0x%02lx", (long) val));
714 }
715
716
717 /* generic read/write */
718
719 static int
720 decode_addr (struct hw *me,
721              struct mn103int *controller,
722              unsigned_word address,
723              unsigned_word *offset)
724 {
725   int i;
726   for (i = 0; i < NR_BLOCKS; i++)
727     {
728       if (address >= controller->block[i].base
729           && address <= controller->block[i].bound)
730         {
731           *offset = address - controller->block[i].base;
732           return i;
733         }
734     }
735   hw_abort (me, "bad address");
736   return -1;
737 }
738
739 static unsigned
740 mn103int_io_read_buffer (struct hw *me,
741                          void *dest,
742                          int space,
743                          unsigned_word base,
744                          unsigned nr_bytes)
745 {
746   struct mn103int *controller = hw_data (me);
747   unsigned8 *buf = dest;
748   unsigned byte;
749   /* HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); */
750   for (byte = 0; byte < nr_bytes; byte++)
751     {
752       unsigned_word address = base + byte;
753       unsigned_word offset;
754       switch (decode_addr (me, controller, address, &offset))
755         {
756         case ICR_BLOCK:
757           buf[byte] = read_icr (me, controller, offset);
758           break;
759         case IAGR_BLOCK:
760           buf[byte] = read_iagr (me, controller, offset);
761           break;
762         case EXTMD_BLOCK:
763           buf[byte] = read_extmd (me, controller, offset);
764           break;
765         default:
766           hw_abort (me, "bad switch");
767         }
768     }
769   return nr_bytes;
770 }     
771
772 static unsigned
773 mn103int_io_write_buffer (struct hw *me,
774                           const void *source,
775                           int space,
776                           unsigned_word base,
777                           unsigned nr_bytes)
778 {
779   struct mn103int *controller = hw_data (me);
780   const unsigned8 *buf = source;
781   unsigned byte;
782   /* HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); */
783   for (byte = 0; byte < nr_bytes; byte++)
784     {
785       unsigned_word address = base + byte;
786       unsigned_word offset;
787       switch (decode_addr (me, controller, address, &offset))
788         {
789         case ICR_BLOCK:
790           write_icr (me, controller, offset, buf[byte]);
791           break;
792         case IAGR_BLOCK:
793           /* not allowed */
794           break;
795         case EXTMD_BLOCK:
796           write_extmd (me, controller, offset, buf[byte]);
797           break;
798         default:
799           hw_abort (me, "bad switch");
800         }
801     }
802   return nr_bytes;
803 }     
804
805
806 const struct hw_descriptor dv_mn103int_descriptor[] = {
807   { "mn103int", mn103int_finish, },
808   { NULL },
809 };