X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fppc%2Fhw_pal.c;h=0789929cde067130165ea41d40d8ed6748663acd;hb=c88960d081f0b37ec03c66a13115e2a68e40d1ad;hp=dd5a097127681c6d5ca91bc0e9e0ec354611e388;hpb=1ed0c0e75db12ea291a4bfef18fc6e59243ba52a;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/ppc/hw_pal.c b/sim/ppc/hw_pal.c index dd5a097127..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 @@ -55,31 +45,71 @@ #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 { @@ -103,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; @@ -110,46 +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 { - /* 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; - } + 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; } } @@ -158,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; } @@ -184,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; @@ -234,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; @@ -250,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) @@ -270,15 +271,8 @@ hw_pal_instance_read_callback(device_instance *instance, void *buf, unsigned_word len) { - char *buf_char = (char *)buf; - hw_pal_device *hw_pal = device_instance_data(instance); - 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 @@ -289,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);