xref: /netbsd-src/external/gpl3/gdb/dist/sim/ppc/hw_cpu.c (revision a2e2270fc5bff6bcbd2c81db532c53a470bd1be5)
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 3 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, see <http://www.gnu.org/licenses/>.
17 
18     */
19 
20 
21 #ifndef _HW_CPU_C_
22 #define _HW_CPU_C_
23 
24 #ifndef STATIC_INLINE_HW_CPU
25 #define STATIC_INLINE_HW_CPU STATIC_INLINE
26 #endif
27 
28 #include "device_table.h"
29 #include "hw_cpu.h"
30 
31 #include "interrupts.h"
32 #include "cpu.h"
33 
34 
35 /* DEVICE
36 
37 
38    cpu - Interface to a Processor
39 
40 
41    DESCRIPTION
42 
43 
44    The CPU device provides the connection between the interrupt net
45    (linking the devices and the interrupt controller) and the
46    simulated model of each processor.  This device contains interrupt
47    ports that correspond directly to the external interrupt stimulus
48    that can be sent to a given processor.  Sending an interrupt to one
49    of the ports results in an interrupt being delivered to the
50    corresponding processor.
51 
52    Typically, an interrupt controller would have its inputs connected
53    to device interrupt sources and its outputs (sreset, int, et.al.)
54    connected to this device.
55 
56 
57    PROPERTIES
58 
59 
60    cpu-nr = <integer> (required)
61 
62 
63    Specify the processor (1..N) that this cpu device node should
64    control.
65 
66 
67    EXAMPLES
68 
69 
70    Connect an OpenPIC interrupt controller interrupt ports to
71    processor zero.
72 
73    | -o '/phb/opic@0 > irq0 int /cpus/cpu@0' \
74    | -o '/phb/opic@0 > init hreset /cpus/cpu@0' \
75 
76 
77    */
78 
79 typedef struct _hw_cpu_device {
80   int cpu_nr;
81   cpu *processor;
82 } hw_cpu_device;
83 
84 static const device_interrupt_port_descriptor hw_cpu_interrupt_ports[] = {
85   { "hreset", hw_cpu_hard_reset },
86   { "sreset", hw_cpu_soft_reset },
87   { "int", hw_cpu_external_interrupt },
88   { "mci", hw_cpu_machine_check_interrupt },
89   { "smi", hw_cpu_system_management_interrupt },
90   { NULL }
91 };
92 
93 
94 static void *
hw_cpu_create(const char * name,const device_unit * unit_address,const char * args)95 hw_cpu_create(const char *name,
96 	      const device_unit *unit_address,
97 	      const char *args)
98 {
99   hw_cpu_device *hw_cpu = ZALLOC(hw_cpu_device);
100   return hw_cpu;
101 }
102 
103 
104 /* during address initialization ensure that any missing cpu
105    properties are added to this devices node */
106 
107 static void
hw_cpu_init_address(device * me)108 hw_cpu_init_address(device *me)
109 {
110   hw_cpu_device *hw_cpu = (hw_cpu_device*)device_data(me);
111   /* populate the node with properties */
112   /* clear our data */
113   memset(hw_cpu, 0x0, sizeof(hw_cpu_device));
114   hw_cpu->cpu_nr = device_find_integer_property(me, "cpu-nr");
115   hw_cpu->processor = psim_cpu(device_system(me), hw_cpu->cpu_nr);
116 }
117 
118 
119 /* Take the interrupt and synchronize its delivery with the clock.  If
120    we've not yet scheduled an interrupt for the next clock tick, take
121    the oportunity to do it now */
122 
123 static void
hw_cpu_interrupt_event(device * me,int my_port,device * source,int source_port,int level,cpu * processor,unsigned_word cia)124 hw_cpu_interrupt_event(device *me,
125 		       int my_port,
126 		       device *source,
127 		       int source_port,
128 		       int level,
129 		       cpu *processor,
130 		       unsigned_word cia)
131 {
132   hw_cpu_device *hw_cpu = (hw_cpu_device*)device_data(me);
133   if (my_port < 0 || my_port >= hw_cpu_nr_interrupt_ports)
134     error("hw_cpu_interrupt_event_callback: interrupt port out of range %d\n",
135 	  my_port);
136   switch (my_port) {
137     /*case hw_cpu_hard_reset:*/
138     /*case hw_cpu_soft_reset:*/
139   case hw_cpu_external_interrupt:
140     external_interrupt(hw_cpu->processor, level);
141     break;
142     /*case hw_cpu_machine_check_interrupt:*/
143   default:
144     error("hw_cpu_deliver_interrupt: unimplemented interrupt port %d\n",
145 	  my_port);
146     break;
147   }
148 }
149 
150 
151 static device_callbacks const hw_cpu_callbacks = {
152   { hw_cpu_init_address, }, /* init */
153   { NULL, }, /* address */
154   { NULL, }, /* io */
155   { NULL, }, /* DMA */
156   { hw_cpu_interrupt_event, NULL, hw_cpu_interrupt_ports }, /* interrupts */
157   { NULL, NULL, },
158 };
159 
160 const device_descriptor hw_cpu_device_descriptor[] = {
161   { "hw-cpu", hw_cpu_create, &hw_cpu_callbacks },
162   { "cpu", hw_cpu_create, &hw_cpu_callbacks },
163   { NULL, },
164 };
165 
166 #endif /* _HW_CPU_C_ */
167