Make simulator build again on SunOS and HP/US systems
[deliverable/binutils-gdb.git] / sim / ppc / hw_pal.c
CommitLineData
1ed0c0e7
MM
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_PAL_C_
23#define _HW_PAL_C_
24
25#ifndef STATIC_INLINE_HW_PAL
26#define STATIC_INLINE_HW_PAL STATIC_INLINE
27#endif
28
29#include "device_table.h"
30#include "cpu.h"
31
32
33#include <stdio.h>
34#include <fcntl.h>
35
36#if 0
37#ifdef HAVE_TIME_H
38#include <time.h>
39#endif
40#endif
41
42#ifdef HAVE_STRING_H
43#include <string.h>
44#else
45#ifdef HAVE_STRINGS_H
46#include <strings.h>
47#endif
48#endif
49
50#ifdef HAVE_UNISTD_H
51#include <unistd.h>
52#endif
53#ifdef HAVE_STDLIB_H
54#include <stdlib.h>
55#endif
56
f64dbcdd
MM
57#if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL)
58#undef WITH_STDIO
59#define WITH_STDIO DO_USE_STDIO
60#endif
1ed0c0e7
MM
61
62/* Device:
63
64 pal@<address>
65
66
67 Description:
68
69 Typical hardware dependant hack. This device allows the firmware
70 to gain access to all the things the firmware needs (but the OS
71 doesn't). All registers are little endian (byte 0 is the least
72 significant) and must be accessed correctly aligned.
73
74 <address> + 0: write - halts simulation with exit code byte[0].
75
76 <address> + 4: read - processor nr in byte[0].
77
78 <address> + 8: write - send interrupt message to port byte[0] with
79 value byte[1].
80
81 <address> + 12: read - nr processors in byte[0].
82
83
84 Properties:
85
86 NONE. */
87
88
89enum {
90 hw_pal_reset_register = 0x0,
91 hw_pal_cpu_nr_register = 0x4,
92 hw_pal_int_register = 0x8,
93 hw_pal_nr_cpu_register = 0xa,
94 hw_pal_read_fifo = 0x10,
95 hw_pal_read_status = 0x14,
96 hw_pal_write_fifo = 0x18,
97 hw_pal_write_status = 0x1a,
98 hw_pal_address_mask = 0x1f,
99};
100
101
102typedef struct _hw_pal_console_buffer {
103 char buffer;
104 int status;
105} hw_pal_console_buffer;
106
107typedef struct _hw_pal_device {
108 hw_pal_console_buffer input;
109 hw_pal_console_buffer output;
110} hw_pal_device;
111
112
113/* check the console for an available character */
114static void
115scan_hw_pal(hw_pal_device *hw_pal)
116{
117 if (WITH_STDIO == DO_USE_STDIO) {
118 int c = getchar ();
119 if (c == EOF) {
120 hw_pal->input.buffer = 0;
121 hw_pal->input.status = 0;
122 } else {
123 hw_pal->input.buffer = c;
124 hw_pal->input.status = 1;
125 }
126
127 } else {
f64dbcdd
MM
128#if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL)
129 error ("O_NDELAY, F_GETFL, or F_SETFL not defined");
130
131#else
1ed0c0e7
MM
132 /* check for input */
133 int flags;
134 int status;
135 /* get the old status */
136 flags = fcntl(0, F_GETFL, 0);
137 if (flags == -1) {
138 perror("hw_pal");
139 return;
140 }
141 /* temp, disable blocking IO */
142 status = fcntl(0, F_SETFL, flags | O_NDELAY);
143 if (status == -1) {
144 perror("hw_pal");
145 return;
146 }
147 /* try for input */
148 status = read(0, &hw_pal->input.buffer, 1);
149 if (status == 1) {
150 hw_pal->input.status = 1;
151 }
152 else {
153 hw_pal->input.status = 0;
154 }
155 /* return to regular vewing */
156 flags = fcntl(0, F_SETFL, flags);
157 if (flags == -1) {
158 perror("hw_pal");
159 return;
160 }
f64dbcdd 161#endif
1ed0c0e7
MM
162 }
163}
164
165/* write the character to the hw_pal */
166static void
167write_hw_pal(hw_pal_device *hw_pal,
168 char val)
169{
170 if (WITH_STDIO == DO_USE_STDIO) {
171 putchar (val);
172
173 } else {
174 printf_filtered("%c", val) ;
175 }
176
177 hw_pal->output.buffer = val;
178 hw_pal->output.status = 1;
179}
180
181
182static unsigned
183hw_pal_io_read_buffer_callback(device *me,
184 void *dest,
185 int space,
186 unsigned_word addr,
187 unsigned nr_bytes,
188 cpu *processor,
189 unsigned_word cia)
190{
191 hw_pal_device *hw_pal = (hw_pal_device*)device_data(me);
192 unsigned_1 val;
193 switch (addr & hw_pal_address_mask) {
194 case hw_pal_cpu_nr_register:
195 val = cpu_nr(processor);
196 break;
197 case hw_pal_nr_cpu_register:
198 val = device_find_integer_property(me, "/openprom/options/smp");
199 break;
200 case hw_pal_read_fifo:
201 val = hw_pal->input.buffer;
202 break;
203 case hw_pal_read_status:
204 scan_hw_pal(hw_pal);
205 val = hw_pal->input.status;
206 break;
207 case hw_pal_write_fifo:
208 val = hw_pal->output.buffer;
209 break;
210 case hw_pal_write_status:
211 val = hw_pal->output.status;
212 break;
213 default:
214 val = 0;
215 }
216 memset(dest, 0, nr_bytes);
217 *(unsigned_1*)dest = val;
218 return nr_bytes;
219}
220
221
222static unsigned
223hw_pal_io_write_buffer_callback(device *me,
224 const void *source,
225 int space,
226 unsigned_word addr,
227 unsigned nr_bytes,
228 cpu *processor,
229 unsigned_word cia)
230{
231 hw_pal_device *hw_pal = (hw_pal_device*)device_data(me);
232 unsigned_1 *byte = (unsigned_1*)source;
233
234 switch (addr & hw_pal_address_mask) {
235 case hw_pal_reset_register:
236 cpu_halt(processor, cia, was_exited, byte[0]);
237 break;
238 case hw_pal_int_register:
239 device_interrupt_event(me,
240 byte[0], /*port*/
241 (nr_bytes > 1 ? byte[1] : 0), /* val */
242 processor, cia);
243 break;
244 case hw_pal_read_fifo:
245 hw_pal->input.buffer = byte[0];
246 break;
247 case hw_pal_read_status:
248 hw_pal->input.status = byte[0];
249 break;
250 case hw_pal_write_fifo:
251 write_hw_pal(hw_pal, byte[0]);
252 break;
253 case hw_pal_write_status:
254 hw_pal->output.status = byte[0];
255 break;
256 }
257 return nr_bytes;
258}
259
260
261/* instances of the hw_pal device */
262static void *
263hw_pal_instance_create_callback(device *me,
264 const char *args)
265{
266 /* make life easier, attach the hw_pal data to the instance */
267 return device_data(me);
268}
269
270static void
271hw_pal_instance_delete_callback(device_instance *instance)
272{
273 /* nothing to delete, the hw_pal is attached to the device */
274 return;
275}
276
277static int
278hw_pal_instance_read_callback(device_instance *instance,
279 void *buf,
280 unsigned_word len)
281{
282 char *buf_char = (char *)buf;
1ed0c0e7
MM
283 if (WITH_STDIO == DO_USE_STDIO) {
284 char *line = fgets (buf_char, len, stdin);
285 return ((!line) ? -1 : strlen (buf_char));
286
287 } else {
288 return read(0, buf_char, len);
289 }
290}
291
292static int
293hw_pal_instance_write_callback(device_instance *instance,
294 const void *buf,
295 unsigned_word len)
296{
297 int i;
298 const char *chp = buf;
299 hw_pal_device *hw_pal = device_instance_data(instance);
300 for (i = 0; i < len; i++)
301 write_hw_pal(hw_pal, chp[i]);
302
303 if (WITH_STDIO == DO_USE_STDIO) {
304 fflush (stdout);
305 }
306 return i;
307}
308
309static device_callbacks const hw_pal_callbacks = {
310 { generic_device_init_address, },
311 { NULL, }, /* address */
312 { hw_pal_io_read_buffer_callback,
313 hw_pal_io_write_buffer_callback, },
314 { NULL, }, /* DMA */
315 { NULL, }, /* interrupt */
316 { NULL, }, /* unit */
317 { hw_pal_instance_create_callback,
318 hw_pal_instance_delete_callback,
319 hw_pal_instance_read_callback,
320 hw_pal_instance_write_callback, },
321};
322
323
324static void *
325hw_pal_create(const char *name,
326 const device_unit *unit_address,
327 const char *args,
328 device *parent)
329{
330 /* create the descriptor */
331 hw_pal_device *hw_pal = ZALLOC(hw_pal_device);
332 hw_pal->output.status = 1;
333 hw_pal->output.buffer = '\0';
334 hw_pal->input.status = 0;
335 hw_pal->input.buffer = '\0';
336 return hw_pal;
337}
338
339
340const device_descriptor hw_pal_device_descriptor[] = {
341 { "pal", hw_pal_create, &hw_pal_callbacks },
342 { NULL },
343};
344
345#endif /* _HW_PAL_C_ */
This page took 0.036893 seconds and 4 git commands to generate.