Make simulator build again on SunOS and HP/US systems
[deliverable/binutils-gdb.git] / sim / ppc / hw_pic.c
1 /* ICU device: icu@<address>
2
3 <address> : read - processor nr
4 <address> : write - interrupt processor nr
5 <address> + 4 : read - nr processors
6
7 Single byte registers that control a simple ICU.
8
9 Illustrates passing of events to parent device. Passing of
10 interrupts to an interrupt destination. */
11
12
13 static unsigned
14 icu_io_read_buffer_callback(device *me,
15 void *dest,
16 int space,
17 unsigned_word addr,
18 unsigned nr_bytes,
19 cpu *processor,
20 unsigned_word cia)
21 {
22 memset(dest, 0, nr_bytes);
23 switch (addr & 4) {
24 case 0:
25 *(unsigned_1*)dest = cpu_nr(processor);
26 break;
27 case 4:
28 *(unsigned_1*)dest =
29 device_find_integer_property(me, "/openprom/options/smp");
30 break;
31 }
32 return nr_bytes;
33 }
34
35
36 static unsigned
37 icu_io_write_buffer_callback(device *me,
38 const void *source,
39 int space,
40 unsigned_word addr,
41 unsigned nr_bytes,
42 cpu *processor,
43 unsigned_word cia)
44 {
45 unsigned_1 val = H2T_1(*(unsigned_1*)source);
46 /* tell the parent device that the interrupt lines have changed.
47 For this fake ICU. The interrupt lines just indicate the cpu to
48 interrupt next */
49 device_interrupt_event(me,
50 val, /*my_port*/
51 val, /*val*/
52 processor, cia);
53 return nr_bytes;
54 }
55
56 static void
57 icu_do_interrupt(event_queue *queue,
58 void *data)
59 {
60 cpu *target = (cpu*)data;
61 /* try to interrupt the processor. If the attempt fails, try again
62 on the next tick */
63 if (!external_interrupt(target))
64 event_queue_schedule(queue, 1, icu_do_interrupt, target);
65 }
66
67
68 static void
69 icu_interrupt_event_callback(device *me,
70 int my_port,
71 device *source,
72 int source_port,
73 int level,
74 cpu *processor,
75 unsigned_word cia)
76 {
77 /* the interrupt controller can't interrupt a cpu at any time.
78 Rather it must synchronize with the system clock before
79 performing an interrupt on the given processor */
80 psim *system = cpu_system(processor);
81 cpu *target = psim_cpu(system, my_port);
82 if (target != NULL) {
83 event_queue *events = cpu_event_queue(target);
84 event_queue_schedule(events, 1, icu_do_interrupt, target);
85 }
86 }
87
88 static device_callbacks const icu_callbacks = {
89 { generic_device_init_address, },
90 { NULL, }, /* address */
91 { icu_io_read_buffer_callback,
92 icu_io_write_buffer_callback, },
93 { NULL, }, /* DMA */
94 { icu_interrupt_event_callback, },
95 { NULL, }, /* unit */
96 };
97
98
This page took 0.03067 seconds and 4 git commands to generate.