OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [ppc/] [hw_pal.c] - Blame information for rev 865

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.