* interp.c (sim_open): Create second 1mb memory region at 0x40000000.
[external/binutils.git] / sim / mn10300 / dv-mn103int.c
1 /*  This file is part of the program GDB, the GU 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-base.h"
25
26 /* DEVICE
27
28    
29    mn103int - mn10300 interrupt controller
30
31    
32    DESCRIPTION
33
34    
35    Implements the mn10300 interrupt controller described in the
36    mn10300 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 0x68 0x34000200 0x8 0x3400280
48    0x8' locates the interrupt controller at the addresses specified in
49    the mn10300 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 25
87    groups (0..24) 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 sensative interrupts, the interrupt controller ignores
104    active HIGH/LOW settings and instead always interprets a nonzero
105    port value as an interupt assertion and a zero port value as a
106    negation.
107
108    */
109
110
111 /* The interrupt groups - numbered according to mn10300 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   INT_GROUP,
123 };
124
125 struct mn103int_group {
126   int level;
127   unsigned enable;
128   unsigned request;
129   unsigned input;
130   enum mn103int_trigger trigger;
131   enum mn103int_type type;
132 };
133
134 enum {
135   FIRST_NMI_GROUP = 0,
136   LAST_NMI_GROUP = 1,
137   FIRST_INT_GROUP = 2,
138   LAST_INT_GROUP = 24,
139   NR_GROUPS,
140 };
141
142 enum {
143   LOWEST_LEVEL = 7,
144 };
145
146 /* The interrupt controller register address blocks */
147
148 struct mn103int_block {
149   unsigned_word base;
150   unsigned_word bound;
151 };
152
153 enum { ICR_BLOCK, IAGR_BLOCK, EXTMD_BLOCK, NR_BLOCKS };
154
155
156 struct mn103int {
157   struct mn103int_block block[NR_BLOCKS];
158   struct mn103int_group group[NR_GROUPS];
159   unsigned interrupt_accepted_group;
160 };
161
162
163
164 /* output port ID's */ 
165
166 enum {
167   NMI_PORT,
168   LEVEL_PORT,
169 };
170
171
172 /* input port ID's */
173
174 enum {
175   G0_PORT = 0,
176   G1_PORT = 4,
177   G2_PORT = 8,
178   G3_PORT = 12,
179   G4_PORT = 16,
180   G5_PORT = 20,
181   G6_PORT = 24,
182   G7_PORT = 28,
183   G8_PORT = 32,
184   G9_PORT = 36,
185   G10_PORT = 40,
186   G11_PORT = 44,
187   G12_PORT = 48,
188   G13_PORT = 52,
189   G14_PORT = 56,
190   G15_PORT = 60,
191   G16_PORT = 64,
192   G17_PORT = 68,
193   G18_PORT = 72,
194   G19_PORT = 76,
195   G20_PORT = 80,
196   G21_PORT = 84,
197   G22_PORT = 88,
198   G23_PORT = 92,
199   G24_PORT = 96,
200   NR_G_PORTS = 100,
201   ACK_PORT,
202 };
203
204 static const struct hw_port_descriptor mn103int_ports[] = {
205
206   /* interrupt outputs */
207
208   { "nmi", NMI_PORT, 0, output_port, },
209   { "level", LEVEL_PORT, 0, output_port, },
210
211   /* interrupt ack (latch) input from cpu */
212
213   { "ack", ACK_PORT, 0, input_port, },
214
215   /* interrupt inputs (as names) */
216
217   { "nmirq", G0_PORT + 0, 0, input_port, },
218   { "watchdog", G0_PORT + 1, 0, input_port, },
219   { "syserr", G0_PORT + 2, 0, input_port, },
220
221   { "timer-0-underflow", G2_PORT + 0, 0, input_port, },
222   { "timer-1-underflow", G2_PORT + 1, 0, input_port, },
223   { "timer-2-underflow", G2_PORT + 2, 0, input_port, },
224   { "timer-3-underflow", G2_PORT + 3, 0, input_port, },
225   { "timer-4-underflow", G3_PORT + 0, 0, input_port, },
226   { "timer-5-underflow", G3_PORT + 1, 0, input_port, },
227   { "timer-6-underflow", G3_PORT + 2, 0, input_port, },
228   { "timer-7-underflow", G3_PORT + 3, 0, input_port, },
229
230   { "timer-8-underflow", G4_PORT + 0, 0, input_port, },
231   { "timer-8-compare-a", G4_PORT + 1, 0, input_port, },
232   { "timer-8-compare-b", G4_PORT + 2, 0, input_port, },
233
234   { "timer-9-underflow", G5_PORT + 0, 0, input_port, },
235   { "timer-9-compare-a", G5_PORT + 1, 0, input_port, },
236   { "timer-9-compare-b", G5_PORT + 2, 0, input_port, },
237
238   { "timer-10-underflow", G6_PORT + 0, 0, input_port, },
239   { "timer-10-compare-a", G6_PORT + 1, 0, input_port, },
240   { "timer-10-compare-b", G6_PORT + 2, 0, input_port, },
241   { "timer-10-compare-c", G6_PORT + 3, 0, input_port, },
242
243   { "timer-11-underflow", G7_PORT + 0, 0, input_port, },
244   { "timer-11-compare-a", G7_PORT + 1, 0, input_port, },
245   { "timer-11-compare-b", G7_PORT + 2, 0, input_port, },
246   { "timer-11-compare-c", G7_PORT + 3, 0, input_port, },
247
248   { "timer-12-underflow", G8_PORT + 0, 0, input_port, },
249   { "timer-12-compare-a", G8_PORT + 1, 0, input_port, },
250   { "timer-12-compare-b", G8_PORT + 2, 0, input_port, },
251   { "timer-12-compare-c", G8_PORT + 3, 0, input_port, },
252
253   { "timer-11-compare-d", G9_PORT + 0, 0, input_port, },
254   { "timer-12-compare-d", G9_PORT + 1, 0, input_port, },
255
256   { "dma-0-end", G10_PORT, 0, input_port, },
257   { "dma-1-end", G11_PORT, 0, input_port, },
258   { "dma-2-end", G12_PORT, 0, input_port, },
259   { "dma-3-end", G13_PORT, 0, input_port, },
260
261   { "serial-0-recieve", G14_PORT + 0, 0, input_port, },
262   { "serial-0-transmit", G14_PORT + 1, 0, input_port, },
263
264   { "serial-1-recieve", G15_PORT + 0, 0, input_port, },
265   { "serial-1-transmit", G15_PORT + 1, 0, input_port, },
266
267   { "irq-0", G16_PORT, 0, input_port, },
268   { "irq-1", G17_PORT, 0, input_port, },
269   { "irq-2", G18_PORT, 0, input_port, },
270   { "irq-3", G19_PORT, 0, input_port, },
271   { "irq-4", G20_PORT, 0, input_port, },
272   { "irq-5", G21_PORT, 0, input_port, },
273   { "irq-6", G22_PORT, 0, input_port, },
274   { "irq-7", G23_PORT, 0, input_port, },
275
276   { "ad-end", G24_PORT, 0, input_port, },
277
278   /* interrupt inputs (as generic numbers) */
279
280   { "int", 0, NR_G_PORTS, input_port, },
281
282   { NULL, },
283 };
284
285
286 /* Macros for extracting/restoring the various register bits */
287
288 #define EXTRACT_ID(X) (LSEXTRACTED8 ((X), 3, 0))
289 #define INSERT_ID(X) (LSINSERTED8 ((X), 3, 0))
290
291 #define EXTRACT_IR(X) (LSEXTRACTED8 ((X), 7, 4))
292 #define INSERT_IR(X) (LSINSERTED8 ((X), 7, 4))
293
294 #define EXTRACT_IE(X) (LSEXTRACTED8 ((X), 3, 0))
295 #define INSERT_IE(X) (LSINSERTED8 ((X), 3, 0))
296
297 #define EXTRACT_LV(X) (LSEXTRACTED8 ((X), 6, 4))
298 #define INSERT_LV(X) (LSINSERTED8 ((X), 6, 4))
299
300
301
302 /* Finish off the partially created hw device.  Attach our local
303    callbacks.  Wire up our port names etc */
304
305 static hw_io_read_buffer_callback mn103int_io_read_buffer;
306 static hw_io_write_buffer_callback mn103int_io_write_buffer;
307 static hw_port_event_callback mn103int_port_event;
308
309 static void
310 attach_mn103int_regs (struct hw *me,
311                       struct mn103int *controller)
312 {
313   int i;
314   if (hw_find_property (me, "reg") == NULL)
315     hw_abort (me, "Missing \"reg\" property");
316   for (i = 0; i < NR_BLOCKS; i++)
317     {
318       unsigned_word attach_address;
319       int attach_space;
320       unsigned attach_size;
321       reg_property_spec reg;
322       if (!hw_find_reg_array_property (me, "reg", i, &reg))
323         hw_abort (me, "\"reg\" property must contain three addr/size entries");
324       hw_unit_address_to_attach_address (hw_parent (me),
325                                          &reg.address,
326                                          &attach_space,
327                                          &attach_address,
328                                          me);
329       controller->block[i].base = attach_address;
330       hw_unit_size_to_attach_size (hw_parent (me),
331                                    &reg.size,
332                                    &attach_size, me);
333       controller->block[i].bound = attach_address + (attach_size - 1);
334       hw_attach_address (hw_parent (me),
335                          0,
336                          attach_space, attach_address, attach_size,
337                          me);
338     }
339 }
340
341 static void
342 mn103int_finish (struct hw *me)
343 {
344   int gid;
345   struct mn103int *controller;
346
347   controller = HW_ZALLOC (me, struct mn103int);
348   set_hw_data (me, controller);
349   set_hw_io_read_buffer (me, mn103int_io_read_buffer);
350   set_hw_io_write_buffer (me, mn103int_io_write_buffer);
351   set_hw_ports (me, mn103int_ports);
352   set_hw_port_event (me, mn103int_port_event);
353
354   /* Attach ourself to our parent bus */
355   attach_mn103int_regs (me, controller);
356
357   /* Initialize all the groups according to their default configuration */
358   for (gid = 0; gid < NR_GROUPS; gid++)
359     {
360       struct mn103int_group *group = &controller->group[gid];
361       group->enable = 0xf;
362       group->trigger = NEGATIVE_EDGE;
363       if (FIRST_NMI_GROUP <= gid && gid <= LAST_NMI_GROUP)
364         {
365           group->type = NMI_GROUP;
366         }
367       else if (FIRST_INT_GROUP <= gid && gid <= LAST_INT_GROUP)
368         {
369           group->type = INT_GROUP;
370         }
371       else
372         hw_abort (me, "internal error - unknown group id");
373     }
374 }
375
376
377
378 /* Perform the nasty work of figuring out which of the interrupt
379    groups should have its interrupt delivered. */
380
381 static int
382 find_highest_interrupt_group (struct hw *me,
383                               struct mn103int *controller)
384 {
385   int gid;
386   int selected;
387
388   /* FIRST_NMI_GROUP (group zero) is used as a special default value
389      when searching for an interrupt group */
390   selected = FIRST_NMI_GROUP; 
391   controller->group[FIRST_NMI_GROUP].level = 7;
392   
393   for (gid = FIRST_INT_GROUP; gid <= LAST_INT_GROUP; gid++)
394     {
395       struct mn103int_group *group = &controller->group[gid];
396       if ((group->request & group->enable) != 0)
397         {
398           if (group->level > controller->group[selected].level)
399             {
400               selected = gid;
401             }
402         }
403     }
404   return selected;
405 }
406
407
408 /* Notify the processor of an interrupt level update */
409
410 static void
411 push_interrupt_level (struct hw *me,
412                       struct mn103int *controller)
413 {
414   int selected = find_highest_interrupt_group (me, controller);
415   int level = controller->group[selected].level;
416   HW_TRACE ((me, "port-out - selected=%d level=%d", selected, level));
417   hw_port_event (me, LEVEL_PORT, level, NULL, NULL_CIA);
418 }
419
420
421 /* An event arrives on an interrupt port */
422
423 static void
424 mn103int_port_event (struct hw *me,
425                      int my_port,
426                      struct hw *source,
427                      int source_port,
428                      int level,
429                      sim_cpu *processor,
430                      sim_cia cia)
431 {
432   struct mn103int *controller = hw_data (me);
433
434   switch (my_port)
435     {
436
437     case ACK_PORT:
438       {
439         int selected = find_highest_interrupt_group (me, controller);
440         if (controller->group[selected].level != level)
441           hw_abort (me, "botched level synchronisation");
442         controller->interrupt_accepted_group = selected;        
443         HW_TRACE ((me, "port-event port=ack level=%d - selected=%d",
444                    level, selected));
445         break;
446       }
447
448     default:
449       {
450         int gid;
451         int iid;
452         struct mn103int_group *group;
453         unsigned interrupt;
454         if (my_port > NR_G_PORTS)
455           hw_abort (me, "Event on unknown port %d", my_port);
456
457         /* map the port onto an interrupt group */
458         gid = (my_port % NR_G_PORTS) / 4;
459         group = &controller->group[gid];
460         iid = (my_port % 4);
461         interrupt = 1 << iid;
462
463         /* update our cached input */
464         if (level)
465           group->input |= interrupt;
466         else
467           group->input &= ~interrupt;
468
469         /* update the request bits */
470         switch (group->trigger)
471           {
472           case ACTIVE_LOW:
473           case ACTIVE_HIGH:
474             if (level)
475               group->request |= interrupt;
476             break;
477           case NEGATIVE_EDGE:
478           case POSITIVE_EDGE:
479             group->request |= interrupt;
480           }
481
482         /* force a corresponding output */
483         switch (group->type)
484           {
485
486           case NMI_GROUP:
487             {
488               /* for NMI's the event is the trigger */
489               HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - NMI",
490                          my_port, gid, iid));
491               if ((group->request & group->enable) != 0)
492                 {
493                   HW_TRACE ((me, "port-out NMI"));
494                   hw_port_event (me, NMI_PORT, 0, NULL, NULL_CIA);
495                 }
496               break;
497             }
498               
499           case INT_GROUP:
500             {
501               /* if an interrupt is now pending */
502               HW_TRACE ((me, "port-in port=%d group=%d interrupt=%d - INT",
503                          my_port, gid, iid));
504               push_interrupt_level (me, controller);
505               break;
506             }
507           }
508         break;
509       }
510
511     }
512 }
513
514 /* Read/write to to an ICR (group control register) */
515
516 static unsigned8
517 read_icr (struct hw *me,
518           struct mn103int *controller,
519           struct mn103int_group *group,
520           unsigned_word offset)
521 {
522   unsigned8 val = 0;
523   switch (group->type)
524     {
525
526     case NMI_GROUP:
527       switch (offset)
528         {
529         case 0:
530           val = INSERT_ID (group->request);
531           HW_TRACE ((me, "read-icr 0x%02x", val));
532           break;
533         }
534       break;
535
536     case INT_GROUP:
537       switch (offset)
538         {
539         case 0:
540           val = (INSERT_IR (group->request)
541                  | INSERT_ID (group->request & group->enable));
542           HW_TRACE ((me, "read-icr 0:0x%02x", val));
543           break;
544         case 1:
545           val = (INSERT_LV (group->level)
546                  | INSERT_IE (group->enable));
547           HW_TRACE ((me, "read-icr 1:0x%02x", val));
548           break;
549         }
550     }
551
552   return val;
553 }
554
555 static void
556 write_icr (struct hw *me,
557            struct mn103int *controller,
558            struct mn103int_group *group,
559            unsigned_word offset,
560                  unsigned8 val)
561 {
562   switch (group->type)
563     {
564
565     case NMI_GROUP:
566       switch (offset)
567         {
568         case 0:
569           HW_TRACE ((me, "write-icr 0x%02x", val));
570           group->request &= ~EXTRACT_ID (val);
571           break;
572         default:
573           break;
574         }
575       break;
576
577     case INT_GROUP:
578       switch (offset)
579         {
580         case 0: /* request/detect */
581           /* Clear any ID bits and then set them according to IR */
582           HW_TRACE ((me, "write-icr 0:0x%02x", val));
583           group->request &= EXTRACT_ID (val);
584           group->request |= EXTRACT_IR (val) & EXTRACT_ID (val);
585           break;
586         case 1: /* level/enable */
587           HW_TRACE ((me, "write-icr 1:0x%02x", val));
588           group->level = EXTRACT_LV (val);
589           group->enable = EXTRACT_IE (val);
590           break;
591         default:
592           /* ignore */
593           break;
594         }
595       push_interrupt_level (me, controller);
596       break;
597
598     }
599 }
600
601
602 /* Read the IAGR (Interrupt accepted group register) */
603
604 static unsigned8
605 read_iagr (struct hw *me,
606            struct mn103int *controller,
607            unsigned_word offset)
608 {
609   unsigned8 val;
610   switch (offset)
611     {
612     case 0:
613       {
614         val = (controller->interrupt_accepted_group << 2);
615         if (!(controller->group[val].request
616               & controller->group[val].enable))
617           /* oops, lost the request */
618           val = 0;
619         break;
620       }
621     default:
622       val = 0;
623     }
624   return val;
625 }
626
627
628 /* Reads/writes to the EXTMD (external interrupt trigger configuration
629    register) */
630
631 static struct mn103int_group *
632 external_group (struct mn103int *controller,
633                 unsigned_word offset)
634 {
635   switch (offset)
636     {
637     case 0:
638       return &controller->group[16];
639     case 1:
640       return &controller->group[20];
641     default:
642       return NULL;
643     }
644 }
645
646 static unsigned8
647 read_extmd (struct hw *me,
648             struct mn103int *controller,
649             unsigned_word offset)
650 {
651   int gid;
652   unsigned8 val = 0;
653   struct mn103int_group *group = external_group (controller, offset);
654   if (group != NULL)
655     {
656       for (gid = 0; gid < 4; gid++)
657         {
658           val |= (group[gid].trigger << (gid * 2));
659         }
660     }
661   return val;
662 }
663
664 static void
665 write_extmd (struct hw *me,
666              struct mn103int *controller,
667              unsigned_word offset,
668              unsigned8 val)
669 {
670   int gid;
671   struct mn103int_group *group = external_group (controller, offset);
672   if (group != NULL)
673     {
674       for (gid = 0; gid < 4; gid++)
675         {
676           group[gid].trigger = (val >> (gid * 2)) & 0x3;
677           /* MAYBE: interrupts already pending? */
678         }
679     }
680 }
681
682
683 /* generic read/write */
684
685 static int
686 decode_addr (struct hw *me,
687              struct mn103int *controller,
688              unsigned_word addr)
689 {
690   int i;
691   for (i = 0; i < NR_BLOCKS; i++)
692     {
693       if (addr >= controller->block[i].base
694           && addr <= controller->block[i].bound)
695         return i;
696     }
697   hw_abort (me, "bad address");
698   return -1;
699 }
700
701 static struct mn103int_group *
702 decode_group (struct hw *me,
703               struct mn103int *controller,
704               unsigned_word addr)
705 {
706   unsigned_word offset = (addr - controller->block[ICR_BLOCK].base);
707   int gid = (offset / 8) % NR_GROUPS;
708   return &controller->group[gid];
709 }
710
711 static unsigned
712 mn103int_io_read_buffer (struct hw *me,
713                          void *dest,
714                          int space,
715                          unsigned_word base,
716                          unsigned nr_bytes,
717                          sim_cpu *processor,
718                          sim_cia cia)
719 {
720   struct mn103int *controller = hw_data (me);
721   unsigned8 *buf = dest;
722   unsigned byte;
723   for (byte = 0; byte < nr_bytes; byte++)
724     {
725       unsigned_word address = base + byte;
726       switch (decode_addr (me, controller, address))
727         {
728         case ICR_BLOCK:
729           buf[byte] = read_icr (me, controller,
730                                 decode_group (me, controller, address),
731                                 address);
732           break;
733         case IAGR_BLOCK:
734           buf[byte] = read_iagr (me, controller, address);
735           break;
736         case EXTMD_BLOCK:
737           buf[byte] = read_extmd (me, controller, address);
738           break;
739         default:
740           hw_abort (me, "bad switch");
741         }
742     }
743   return nr_bytes;
744 }     
745
746 static unsigned
747 mn103int_io_write_buffer (struct hw *me,
748                           const void *source,
749                           int space,
750                           unsigned_word base,
751                           unsigned nr_bytes,
752                           sim_cpu *cpu,
753                           sim_cia cia)
754 {
755   struct mn103int *controller = hw_data (me);
756   const unsigned8 *buf = source;
757   unsigned byte;
758   for (byte = 0; byte < nr_bytes; byte++)
759     {
760       unsigned_word address = base + byte;
761       switch (decode_addr (me, controller, address))
762         {
763         case ICR_BLOCK:
764           write_icr (me, controller,
765                      decode_group (me, controller, address),
766                      address, buf[byte]);
767           break;
768         case IAGR_BLOCK:
769           /* not allowed */
770           break;
771         case EXTMD_BLOCK:
772           write_extmd (me, controller, address, buf[byte]);
773           break;
774         default:
775           hw_abort (me, "bad switch");
776         }
777     }
778   return nr_bytes;
779 }     
780
781
782 const struct hw_device_descriptor dv_mn103int_descriptor[] = {
783   { "mn103int", mn103int_finish, },
784   { NULL },
785 };