Add hw_{malloc,zalloc,free} functions to hw_device. Any memory
[deliverable/binutils-gdb.git] / sim / common / dv-pal.c
CommitLineData
b1e9223c
AC
1/* This file is part of the program psim.
2
3 Copyright (C) 1994-1996,1998, 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#include "sim-main.h"
23#include "hw-base.h"
24
25/* NOTE: pal is naughty and grubs around looking at things outside of
26 its immediate domain */
27#include "hw-tree.h"
28
29#ifdef HAVE_STRING_H
30#include <string.h>
31#else
32#ifdef HAVE_STRINGS_H
33#include <strings.h>
34#endif
35#endif
36
37#ifdef HAVE_UNISTD_H
38#include <unistd.h>
39#endif
40#ifdef HAVE_STDLIB_H
41#include <stdlib.h>
42#endif
43
44#define DTRACE(x,y)
45
46/* DEVICE
47
48
49 pal - glue logic device containing assorted junk
50
51
52 DESCRIPTION
53
54
55 Typical hardware dependant hack. This device allows the firmware
56 to gain access to all the things the firmware needs (but the OS
57 doesn't).
58
59 The pal contains the following registers. Except for the interrupt
60 level register, each of the below is 8 bytes in size and must be
61 accessed using correct alignment. For 16 and 32 bit accesses the
62 bytes not directed to the register are ignored:
63
64 |0 reset register (write)
65 |4 processor id register (read)
66 |8 interrupt port (write)
67 |9 interrupt level (write)
68 |12 processor count register (read)
69 |16 tty input fifo register (read)
70 |20 tty input status register (read)
71 |24 tty output fifo register (write)
72 |28 tty output status register (read)
73
74 Reset register (write) halts the simulator exiting with the
75 value written.
76
77 Processor id register (read) returns the processor number (0
78 .. N-1) of the processor performing the read.
79
80 The interrupt registers should be accessed as a pair (using a 16 or
81 32 bit store). The low byte specifies the interrupt port while the
82 high byte specifies the level to drive that port at. By
83 convention, the pal's interrupt ports (int0, int1, ...) are wired
84 up to the corresponding processor's level sensative external
85 interrupt pin. Eg: A two byte write to address 8 of 0x0102
86 (big-endian) will result in processor 2's external interrupt pin to
87 be asserted.
88
89 Processor count register (read) returns the total number of
90 processors active in the current simulation.
91
92 TTY input fifo register (read), if the TTY input status register
93 indicates a character is available by being nonzero, returns the
94 next available character from the pal's tty input port.
95
96 Similarly, the TTY output fifo register (write), if the TTY output
97 status register indicates the output fifo is not full by being
98 nonzero, outputs the character written to the tty's output port.
99
100
101 PROPERTIES
102
103
104 reg = <address> <size> (required)
105
106 Specify the address (within the parent bus) that this device is to
107 live.
108
109
110 */
111
112
113enum {
114 hw_pal_reset_register = 0x0,
115 hw_pal_cpu_nr_register = 0x4,
116 hw_pal_int_register = 0x8,
117 hw_pal_nr_cpu_register = 0xa,
118 hw_pal_read_fifo = 0x10,
119 hw_pal_read_status = 0x14,
120 hw_pal_write_fifo = 0x18,
121 hw_pal_write_status = 0x1a,
122 hw_pal_address_mask = 0x1f,
123};
124
125
126typedef struct _hw_pal_console_buffer {
127 char buffer;
128 int status;
129} hw_pal_console_buffer;
130
131typedef struct _hw_pal_device {
132 hw_pal_console_buffer input;
133 hw_pal_console_buffer output;
134 struct hw *disk;
135} hw_pal_device;
136
137
138/* check the console for an available character */
139static void
140scan_hw_pal (struct hw *me)
141{
142#if 0
143 hw_pal_struct hw *hw_pal = (hw_pal_struct hw *) hw_data (me);
144#endif
145 char c;
146 int count;
147 count = sim_io_read_stdin (hw_system (me), &c, sizeof(c));
148#if 0
149 switch (count)
150 {
151 case sim_io_not_ready:
152 case sim_io_eof:
153 hw_pal->input.buffer = 0;
154 hw_pal->input.status = 0;
155 break;
156 default:
157 hw_pal->input.buffer = c;
158 hw_pal->input.status = 1;
159 }
160#endif
161}
162
163/* write the character to the hw_pal */
164static void
165write_hw_pal (struct hw *me,
166 char val)
167{
168 hw_pal_device *hw_pal = (hw_pal_device *) hw_data (me);
169 sim_io_write_stdout (hw_system (me), &val, 1);
170 hw_pal->output.buffer = val;
171 hw_pal->output.status = 1;
172}
173
174
175static unsigned
176hw_pal_io_read_buffer (struct hw *me,
177 void *dest,
178 int space,
179 unsigned_word addr,
180 unsigned nr_bytes,
181 sim_cpu *cpu,
182 sim_cia cia)
183{
184 hw_pal_device *hw_pal = (hw_pal_device *) hw_data (me);
185 unsigned_1 val;
186 switch (addr & hw_pal_address_mask)
187 {
188 case hw_pal_cpu_nr_register:
189#ifdef CPU_INDEX
190 val = CPU_INDEX (cpu);
191#else
192 val = 0;
193#endif
194 DTRACE (pal, ("read - cpu-nr %d\n", val));
195 break;
196 case hw_pal_nr_cpu_register:
197 val = hw_tree_find_integer_property (me, "/openprom/options/smp");
198 DTRACE (pal, ("read - nr-cpu %d\n", val));
199 break;
200 case hw_pal_read_fifo:
201 val = hw_pal->input.buffer;
202 DTRACE (pal, ("read - input-fifo %d\n", val));
203 break;
204 case hw_pal_read_status:
205 scan_hw_pal (me);
206 val = hw_pal->input.status;
207 DTRACE (pal, ("read - input-status %d\n", val));
208 break;
209 case hw_pal_write_fifo:
210 val = hw_pal->output.buffer;
211 DTRACE (pal, ("read - output-fifo %d\n", val));
212 break;
213 case hw_pal_write_status:
214 val = hw_pal->output.status;
215 DTRACE (pal, ("read - output-status %d\n", val));
216 break;
217 default:
218 val = 0;
219 DTRACE (pal, ("read - ???\n"));
220 }
221 memset (dest, 0, nr_bytes);
222 *(unsigned_1*)dest = val;
223 return nr_bytes;
224}
225
226
227static unsigned
228hw_pal_io_write_buffer (struct hw *me,
229 const void *source,
230 int space,
231 unsigned_word addr,
232 unsigned nr_bytes,
233 sim_cpu *cpu,
234 sim_cia cia)
235{
236 hw_pal_device *hw_pal = (hw_pal_device*) hw_data (me);
237 unsigned_1 *byte = (unsigned_1*) source;
238
239 switch (addr & hw_pal_address_mask)
240 {
241 case hw_pal_reset_register:
242 sim_engine_halt (NULL, cpu, NULL, cia, sim_exited, byte[0]);
243 break;
244 case hw_pal_int_register:
245 hw_port_event (me,
246 byte[0], /*port*/
247 (nr_bytes > 1 ? byte[1] : 0), /* val */
248 cpu, cia);
249 break;
250 case hw_pal_read_fifo:
251 hw_pal->input.buffer = byte[0];
252 DTRACE (pal, ("write - input-fifo %d\n", byte[0]));
253 break;
254 case hw_pal_read_status:
255 hw_pal->input.status = byte[0];
256 DTRACE (pal, ("write - input-status %d\n", byte[0]));
257 break;
258 case hw_pal_write_fifo:
259 write_hw_pal (me, byte[0]);
260 DTRACE (pal, ("write - output-fifo %d\n", byte[0]));
261 break;
262 case hw_pal_write_status:
263 hw_pal->output.status = byte[0];
264 DTRACE (pal, ("write - output-status %d\n", byte[0]));
265 break;
266 }
267 return nr_bytes;
268}
269
270
271/* instances of the hw_pal struct hw */
272
273#if NOT_YET
274static void
275hw_pal_instance_delete_callback(hw_instance *instance)
276{
277 /* nothing to delete, the hw_pal is attached to the struct hw */
278 return;
279}
280#endif
281
282#if NOT_YET
283static int
284hw_pal_instance_read_callback (hw_instance *instance,
285 void *buf,
286 unsigned_word len)
287{
288 DITRACE (pal, ("read - %s (%ld)", (const char*) buf, (long int) len));
289 return sim_io_read_stdin (buf, len);
290}
291#endif
292
293#if NOT_YET
294static int
295hw_pal_instance_write_callback (hw_instance *instance,
296 const void *buf,
297 unsigned_word len)
298{
299 int i;
300 const char *chp = buf;
301 hw_pal_device *hw_pal = hw_instance_data (instance);
302 DITRACE (pal, ("write - %s (%ld)", (const char*) buf, (long int) len));
303 for (i = 0; i < len; i++)
304 write_hw_pal (hw_pal, chp[i]);
305 sim_io_flush_stdoutput ();
306 return i;
307}
308#endif
309
310#if NOT_YET
311static const hw_instance_callbacks hw_pal_instance_callbacks = {
312 hw_pal_instance_delete_callback,
313 hw_pal_instance_read_callback,
314 hw_pal_instance_write_callback,
315};
316#endif
317
318#if 0
319static hw_instance *
320hw_pal_create_instance (struct hw *me,
321 const char *path,
322 const char *args)
323{
324 return hw_create_instance_from (me, NULL,
325 hw_data (me),
326 path, args,
327 &hw_pal_instance_callbacks);
328}
329#endif
330
331static const struct hw_port_descriptor hw_pal_ports[] = {
332 { "int", 0, MAX_NR_PROCESSORS },
333 { NULL }
334};
335
336
337static void
338hw_pal_attach_address (struct hw *me,
339 int level,
340 int space,
341 address_word addr,
342 address_word nr_bytes,
343 struct hw *client)
344{
345 hw_pal_device *pal = (hw_pal_device*) hw_data (me);
346 pal->disk = client;
347}
348
349
350#if 0
351static hw_callbacks const hw_pal_callbacks = {
352 { generic_hw_init_address, },
353 { hw_pal_attach_address, }, /* address */
354 { hw_pal_io_read_buffer_callback,
355 hw_pal_io_write_buffer_callback, },
356 { NULL, }, /* DMA */
357 { NULL, NULL, hw_pal_interrupt_ports }, /* interrupt */
358 { generic_hw_unit_decode,
359 generic_hw_unit_encode,
360 generic_hw_address_to_attach_address,
361 generic_hw_size_to_attach_size },
362 hw_pal_create_instance,
363};
364#endif
365
366
367static void
368hw_pal_finish (struct hw *hw)
369{
370 /* create the descriptor */
e5f0d498 371 hw_pal_device *hw_pal = HW_ZALLOC (hw, hw_pal_device);
b1e9223c
AC
372 hw_pal->output.status = 1;
373 hw_pal->output.buffer = '\0';
374 hw_pal->input.status = 0;
375 hw_pal->input.buffer = '\0';
376 set_hw_data (hw, hw_pal);
377 set_hw_attach_address (hw, hw_pal_attach_address);
378 set_hw_io_read_buffer (hw, hw_pal_io_read_buffer);
379 set_hw_io_write_buffer (hw, hw_pal_io_write_buffer);
380 set_hw_ports (hw, hw_pal_ports);
381}
382
383
384const struct hw_device_descriptor dv_pal_descriptor[] = {
385 { "pal", hw_pal_finish, },
386 { NULL },
387};
This page took 0.035025 seconds and 4 git commands to generate.