xref: /netbsd-src/external/gpl3/gdb/dist/sim/ppc/hw_cpu.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*  This file is part of the program psim.
2 
3     Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19     */
20 
21 
22 #ifndef _HW_CPU_C_
23 #define _HW_CPU_C_
24 
25 #ifndef STATIC_INLINE_HW_CPU
26 #define STATIC_INLINE_HW_CPU STATIC_INLINE
27 #endif
28 
29 #include "device_table.h"
30 #include "hw_cpu.h"
31 
32 #include "interrupts.h"
33 #include "cpu.h"
34 
35 
36 /* DEVICE
37 
38 
39    cpu - Interface to a Processor
40 
41 
42    DESCRIPTION
43 
44 
45    The CPU device provides the connection between the interrupt net
46    (linking the devices and the interrupt controller) and the
47    simulated model of each processor.  This device contains interrupt
48    ports that correspond directly to the external interrupt stimulus
49    that can be sent to a given processor.  Sending an interrupt to one
50    of the ports results in an interrupt being delivered to the
51    corresponding processor.
52 
53    Typically, an interrupt controller would have its inputs connected
54    to device interrupt sources and its outputs (sreset, int, et.al.)
55    connected to this device.
56 
57 
58    PROPERTIES
59 
60 
61    cpu-nr = <integer> (required)
62 
63 
64    Specify the processor (1..N) that this cpu device node should
65    control.
66 
67 
68    EXAMPLES
69 
70 
71    Connect an OpenPIC interrupt controller interrupt ports to
72    processor zero.
73 
74    | -o '/phb/opic@0 > irq0 int /cpus/cpu@0' \
75    | -o '/phb/opic@0 > init hreset /cpus/cpu@0' \
76 
77 
78    */
79 
80 typedef struct _hw_cpu_device {
81   int cpu_nr;
82   cpu *processor;
83 } hw_cpu_device;
84 
85 static const device_interrupt_port_descriptor hw_cpu_interrupt_ports[] = {
86   { "hreset", hw_cpu_hard_reset },
87   { "sreset", hw_cpu_soft_reset },
88   { "int", hw_cpu_external_interrupt },
89   { "mci", hw_cpu_machine_check_interrupt },
90   { "smi", hw_cpu_system_management_interrupt },
91   { NULL }
92 };
93 
94 
95 static void *
96 hw_cpu_create(const char *name,
97 	      const device_unit *unit_address,
98 	      const char *args)
99 {
100   hw_cpu_device *hw_cpu = ZALLOC(hw_cpu_device);
101   return hw_cpu;
102 }
103 
104 
105 /* during address initialization ensure that any missing cpu
106    properties are added to this devices node */
107 
108 static void
109 hw_cpu_init_address(device *me)
110 {
111   hw_cpu_device *hw_cpu = (hw_cpu_device*)device_data(me);
112   /* populate the node with properties */
113   /* clear our data */
114   memset(hw_cpu, 0x0, sizeof(hw_cpu_device));
115   hw_cpu->cpu_nr = device_find_integer_property(me, "cpu-nr");
116   hw_cpu->processor = psim_cpu(device_system(me), hw_cpu->cpu_nr);
117 }
118 
119 
120 /* Take the interrupt and synchronize its delivery with the clock.  If
121    we've not yet scheduled an interrupt for the next clock tick, take
122    the oportunity to do it now */
123 
124 static void
125 hw_cpu_interrupt_event(device *me,
126 		       int my_port,
127 		       device *source,
128 		       int source_port,
129 		       int level,
130 		       cpu *processor,
131 		       unsigned_word cia)
132 {
133   hw_cpu_device *hw_cpu = (hw_cpu_device*)device_data(me);
134   if (my_port < 0 || my_port >= hw_cpu_nr_interrupt_ports)
135     error("hw_cpu_interrupt_event_callback: interrupt port out of range %d\n",
136 	  my_port);
137   switch (my_port) {
138     /*case hw_cpu_hard_reset:*/
139     /*case hw_cpu_soft_reset:*/
140   case hw_cpu_external_interrupt:
141     external_interrupt(hw_cpu->processor, level);
142     break;
143     /*case hw_cpu_machine_check_interrupt:*/
144   default:
145     error("hw_cpu_deliver_interrupt: unimplemented interrupt port %d\n",
146 	  my_port);
147     break;
148   }
149 }
150 
151 
152 static device_callbacks const hw_cpu_callbacks = {
153   { hw_cpu_init_address, }, /* init */
154   { NULL, }, /* address */
155   { NULL, }, /* io */
156   { NULL, }, /* DMA */
157   { hw_cpu_interrupt_event, NULL, hw_cpu_interrupt_ports }, /* interrupts */
158   { NULL, NULL, },
159 };
160 
161 const device_descriptor hw_cpu_device_descriptor[] = {
162   { "hw-cpu", hw_cpu_create, &hw_cpu_callbacks },
163   { "cpu", hw_cpu_create, &hw_cpu_callbacks },
164   { NULL, },
165 };
166 
167 #endif /* _HW_CPU_C_ */
168