diff options
Diffstat (limited to 'sim/ppc/hw_pal.c')
-rw-r--r-- | sim/ppc/hw_pal.c | 114 |
1 files changed, 77 insertions, 37 deletions
diff --git a/sim/ppc/hw_pal.c b/sim/ppc/hw_pal.c index 429f457..64a56f8 100644 --- a/sim/ppc/hw_pal.c +++ b/sim/ppc/hw_pal.c @@ -27,18 +27,12 @@ #endif #include "device_table.h" -#include "cpu.h" +#include "cpu.h" #include <stdio.h> #include <fcntl.h> -#if 0 -#ifdef HAVE_TIME_H -#include <time.h> -#endif -#endif - #ifdef HAVE_STRING_H #include <string.h> #else @@ -59,31 +53,65 @@ #define WITH_STDIO DO_USE_STDIO #endif -/* Device: - - pal@<address> +/* 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. - - <address> + 0: write - halts simulation with exit code byte[0]. - - <address> + 4: read - processor nr in byte[0]. - - <address> + 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: - <address> + 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 = <address> <size> (required) + + Specify the address (within the parent bus) that this device is to + live. + + */ enum { @@ -259,13 +287,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) @@ -306,26 +327,45 @@ hw_pal_instance_write_callback(device_instance *instance, 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 device_callbacks const hw_pal_callbacks = { { generic_device_init_address, }, { NULL, }, /* address */ { hw_pal_io_read_buffer_callback, hw_pal_io_write_buffer_callback, }, { NULL, }, /* DMA */ - { NULL, }, /* interrupt */ + { NULL, NULL, hw_pal_interrupt_ports }, /* interrupt */ { NULL, }, /* unit */ - { hw_pal_instance_create_callback, - hw_pal_instance_delete_callback, - hw_pal_instance_read_callback, - hw_pal_instance_write_callback, }, + 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); |