X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fppc%2Fhw_pal.c;h=0789929cde067130165ea41d40d8ed6748663acd;hb=2951f6c068f961a2ea1de892fc82cf0229af67da;hp=429f45763847126a4956f1f7a6a21dace0fb5b3a;hpb=f64dbcddaf55af68fd430ba6f2b851dd1220099c;p=deliverable%2Fbinutils-gdb.git
diff --git a/sim/ppc/hw_pal.c b/sim/ppc/hw_pal.c
index 429f457638..0789929cde 100644
--- a/sim/ppc/hw_pal.c
+++ b/sim/ppc/hw_pal.c
@@ -4,7 +4,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -13,8 +13,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ along with this program; if not, see .
*/
@@ -27,17 +26,8 @@
#endif
#include "device_table.h"
-#include "cpu.h"
-
-#include
-#include
-
-#if 0
-#ifdef HAVE_TIME_H
-#include
-#endif
-#endif
+#include "cpu.h"
#ifdef HAVE_STRING_H
#include
@@ -54,36 +44,72 @@
#include
#endif
-#if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL)
-#undef WITH_STDIO
-#define WITH_STDIO DO_USE_STDIO
-#endif
-/* Device:
-
- pal@
+/* DEVICE
+
+ pal - glue logic device containing assorted junk
+
- Description:
+ DESCRIPTION
+
Typical hardware dependant hack. This device allows the firmware
to gain access to all the things the firmware needs (but the OS
- doesn't). All registers are little endian (byte 0 is the least
- significant) and must be accessed correctly aligned.
-
- + 0: write - halts simulation with exit code byte[0].
-
- + 4: read - processor nr in byte[0].
-
- + 8: write - send interrupt message to port byte[0] with
- value byte[1].
+ doesn't).
+
+ The pal contains the following registers. Except for the interrupt
+ level register, each of the below is 8 bytes in size and must be
+ accessed using correct alignment. For 16 and 32 bit accesses the
+ bytes not directed to the register are ignored:
- + 12: read - nr processors in byte[0].
+ |0 reset register (write)
+ |4 processor id register (read)
+ |8 interrupt port (write)
+ |9 interrupt level (write)
+ |12 processor count register (read)
+ |16 tty input fifo register (read)
+ |20 tty input status register (read)
+ |24 tty output fifo register (write)
+ |28 tty output status register (read)
+
+ Reset register (write) halts the simulator exiting with the
+ value written.
+ Processor id register (read) returns the processor number (0
+ .. N-1) of the processor performing the read.
- Properties:
+ The interrupt registers should be accessed as a pair (using a 16 or
+ 32 bit store). The low byte specifies the interrupt port while the
+ high byte specifies the level to drive that port at. By
+ convention, the pal's interrupt ports (int0, int1, ...) are wired
+ up to the corresponding processor's level sensative external
+ interrupt pin. Eg: A two byte write to address 8 of 0x0102
+ (big-endian) will result in processor 2's external interrupt pin to
+ be asserted.
+
+ Processor count register (read) returns the total number of
+ processors active in the current simulation.
+
+ TTY input fifo register (read), if the TTY input status register
+ indicates a character is available by being nonzero, returns the
+ next available character from the pal's tty input port.
+
+ Similarly, the TTY output fifo register (write), if the TTY output
+ status register indicates the output fifo is not full by being
+ nonzero, outputs the character written to the tty's output port.
+
+
+ PROPERTIES
- NONE. */
+
+ reg = (required)
+
+ Specify the address (within the parent bus) that this device is to
+ live.
+
+
+ */
enum {
@@ -107,6 +133,7 @@ typedef struct _hw_pal_console_buffer {
typedef struct _hw_pal_device {
hw_pal_console_buffer input;
hw_pal_console_buffer output;
+ device *disk;
} hw_pal_device;
@@ -114,51 +141,18 @@ typedef struct _hw_pal_device {
static void
scan_hw_pal(hw_pal_device *hw_pal)
{
- if (WITH_STDIO == DO_USE_STDIO) {
- int c = getchar ();
- if (c == EOF) {
- hw_pal->input.buffer = 0;
- hw_pal->input.status = 0;
- } else {
- hw_pal->input.buffer = c;
- hw_pal->input.status = 1;
- }
-
- } else {
-#if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL)
- error ("O_NDELAY, F_GETFL, or F_SETFL not defined");
-
-#else
- /* check for input */
- int flags;
- int status;
- /* get the old status */
- flags = fcntl(0, F_GETFL, 0);
- if (flags == -1) {
- perror("hw_pal");
- return;
- }
- /* temp, disable blocking IO */
- status = fcntl(0, F_SETFL, flags | O_NDELAY);
- if (status == -1) {
- perror("hw_pal");
- return;
- }
- /* try for input */
- status = read(0, &hw_pal->input.buffer, 1);
- if (status == 1) {
- hw_pal->input.status = 1;
- }
- else {
- hw_pal->input.status = 0;
- }
- /* return to regular vewing */
- flags = fcntl(0, F_SETFL, flags);
- if (flags == -1) {
- perror("hw_pal");
- return;
- }
-#endif
+ char c;
+ int count;
+ count = sim_io_read_stdin(&c, sizeof(c));
+ switch (count) {
+ case sim_io_not_ready:
+ case sim_io_eof:
+ hw_pal->input.buffer = 0;
+ hw_pal->input.status = 0;
+ break;
+ default:
+ hw_pal->input.buffer = c;
+ hw_pal->input.status = 1;
}
}
@@ -167,13 +161,7 @@ static void
write_hw_pal(hw_pal_device *hw_pal,
char val)
{
- if (WITH_STDIO == DO_USE_STDIO) {
- putchar (val);
-
- } else {
- printf_filtered("%c", val) ;
- }
-
+ sim_io_write_stdout(&val, 1);
hw_pal->output.buffer = val;
hw_pal->output.status = 1;
}
@@ -193,25 +181,32 @@ hw_pal_io_read_buffer_callback(device *me,
switch (addr & hw_pal_address_mask) {
case hw_pal_cpu_nr_register:
val = cpu_nr(processor);
+ DTRACE(pal, ("read - cpu-nr %d\n", val));
break;
case hw_pal_nr_cpu_register:
- val = device_find_integer_property(me, "/openprom/options/smp");
+ val = tree_find_integer_property(me, "/openprom/options/smp");
+ DTRACE(pal, ("read - nr-cpu %d\n", val));
break;
case hw_pal_read_fifo:
val = hw_pal->input.buffer;
+ DTRACE(pal, ("read - input-fifo %d\n", val));
break;
case hw_pal_read_status:
scan_hw_pal(hw_pal);
val = hw_pal->input.status;
+ DTRACE(pal, ("read - input-status %d\n", val));
break;
case hw_pal_write_fifo:
val = hw_pal->output.buffer;
+ DTRACE(pal, ("read - output-fifo %d\n", val));
break;
case hw_pal_write_status:
val = hw_pal->output.status;
+ DTRACE(pal, ("read - output-status %d\n", val));
break;
default:
val = 0;
+ DTRACE(pal, ("read - ???\n"));
}
memset(dest, 0, nr_bytes);
*(unsigned_1*)dest = val;
@@ -243,15 +238,19 @@ hw_pal_io_write_buffer_callback(device *me,
break;
case hw_pal_read_fifo:
hw_pal->input.buffer = byte[0];
+ DTRACE(pal, ("write - input-fifo %d\n", byte[0]));
break;
case hw_pal_read_status:
hw_pal->input.status = byte[0];
+ DTRACE(pal, ("write - input-status %d\n", byte[0]));
break;
case hw_pal_write_fifo:
write_hw_pal(hw_pal, byte[0]);
+ DTRACE(pal, ("write - output-fifo %d\n", byte[0]));
break;
case hw_pal_write_status:
hw_pal->output.status = byte[0];
+ DTRACE(pal, ("write - output-status %d\n", byte[0]));
break;
}
return nr_bytes;
@@ -259,13 +258,6 @@ hw_pal_io_write_buffer_callback(device *me,
/* instances of the hw_pal device */
-static void *
-hw_pal_instance_create_callback(device *me,
- const char *args)
-{
- /* make life easier, attach the hw_pal data to the instance */
- return device_data(me);
-}
static void
hw_pal_instance_delete_callback(device_instance *instance)
@@ -279,14 +271,8 @@ hw_pal_instance_read_callback(device_instance *instance,
void *buf,
unsigned_word len)
{
- char *buf_char = (char *)buf;
- if (WITH_STDIO == DO_USE_STDIO) {
- char *line = fgets (buf_char, len, stdin);
- return ((!line) ? -1 : strlen (buf_char));
-
- } else {
- return read(0, buf_char, len);
- }
+ DITRACE(pal, ("read - %s (%ld)", (const char*)buf, (long int)len));
+ return sim_io_read_stdin(buf, len);
}
static int
@@ -297,35 +283,69 @@ hw_pal_instance_write_callback(device_instance *instance,
int i;
const char *chp = buf;
hw_pal_device *hw_pal = device_instance_data(instance);
+ DITRACE(pal, ("write - %s (%ld)", (const char*)buf, (long int)len));
for (i = 0; i < len; i++)
write_hw_pal(hw_pal, chp[i]);
-
- if (WITH_STDIO == DO_USE_STDIO) {
- fflush (stdout);
- }
+ sim_io_flush_stdoutput();
return i;
}
+static const device_instance_callbacks hw_pal_instance_callbacks = {
+ hw_pal_instance_delete_callback,
+ hw_pal_instance_read_callback,
+ hw_pal_instance_write_callback,
+};
+
+static device_instance *
+hw_pal_create_instance(device *me,
+ const char *path,
+ const char *args)
+{
+ return device_create_instance_from(me, NULL,
+ device_data(me),
+ path, args,
+ &hw_pal_instance_callbacks);
+}
+
+static const device_interrupt_port_descriptor hw_pal_interrupt_ports[] = {
+ { "int", 0, MAX_NR_PROCESSORS },
+ { NULL }
+};
+
+
+static void
+hw_pal_attach_address(device *me,
+ attach_type attach,
+ int space,
+ unsigned_word addr,
+ unsigned nr_bytes,
+ access_type access,
+ device *client)
+{
+ hw_pal_device *pal = (hw_pal_device*)device_data(me);
+ pal->disk = client;
+}
+
+
static device_callbacks const hw_pal_callbacks = {
{ generic_device_init_address, },
- { NULL, }, /* address */
+ { hw_pal_attach_address, }, /* address */
{ hw_pal_io_read_buffer_callback,
hw_pal_io_write_buffer_callback, },
{ NULL, }, /* DMA */
- { NULL, }, /* interrupt */
- { NULL, }, /* unit */
- { hw_pal_instance_create_callback,
- hw_pal_instance_delete_callback,
- hw_pal_instance_read_callback,
- hw_pal_instance_write_callback, },
+ { NULL, NULL, hw_pal_interrupt_ports }, /* interrupt */
+ { generic_device_unit_decode,
+ generic_device_unit_encode,
+ generic_device_address_to_attach_address,
+ generic_device_size_to_attach_size },
+ hw_pal_create_instance,
};
static void *
hw_pal_create(const char *name,
const device_unit *unit_address,
- const char *args,
- device *parent)
+ const char *args)
{
/* create the descriptor */
hw_pal_device *hw_pal = ZALLOC(hw_pal_device);