* interp.c (sim_open): Create second 1mb memory region at 0x40000000.
[binutils-gdb.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 };