Fix interrupt settings for mn103002, not mn10300 implementation.
[binutils-gdb.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 };