More changes for GO32 canadian cross builds
[deliverable/binutils-gdb.git] / sim / ppc / hw_pic.c
CommitLineData
d4d3c7ad
MM
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
13static unsigned
14icu_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
36static unsigned
37icu_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
56static void
57icu_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
68static void
69icu_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
88static 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.026752 seconds and 4 git commands to generate.