diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:34:07 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:34:07 +0000 |
commit | 071ea11e85eb9d529cc5eb3d35f6247466a21b99 (patch) | |
tree | 5deda65b8d7b04d1f4cbc534c3206d328e1267ec /sim/common/dv-pal.c | |
parent | 1730ec6b1848f0f32154277f788fb29f88d8475b (diff) | |
download | gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.zip gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.gz gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.bz2 |
Initial creation of sourceware repository
Diffstat (limited to 'sim/common/dv-pal.c')
-rw-r--r-- | sim/common/dv-pal.c | 605 |
1 files changed, 0 insertions, 605 deletions
diff --git a/sim/common/dv-pal.c b/sim/common/dv-pal.c deleted file mode 100644 index a696d39..0000000 --- a/sim/common/dv-pal.c +++ /dev/null @@ -1,605 +0,0 @@ -/* This file is part of the program psim. - - Copyright (C) 1994-1996,1998, Andrew Cagney <cagney@highland.com.au> - - 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 - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - 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. - - */ - - -#include "sim-main.h" -#include "hw-base.h" - -/* NOTE: pal is naughty and grubs around looking at things outside of - its immediate domain */ -#include "hw-tree.h" - -#ifdef HAVE_STRING_H -#include <string.h> -#else -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif - -/* DEVICE - - - pal - glue logic device containing assorted junk - - - 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). - - The pal contains the following registers: - - |0 reset register (write, 8bit) - |4 processor id register (read, 8bit) - |8 interrupt register (8 - port, 9 - level) (write, 16bit) - |12 processor count register (read, 8bit) - - |16 tty input fifo register (read, 8bit) - |20 tty input status register (read, 8bit) - |24 tty output fifo register (write, 8bit) - |28 tty output status register (read, 8bit) - - |32 countdown register (read/write, 32bit, big-endian) - |36 countdown value register (read, 32bit, big-endian) - |40 timer register (read/write, 32bit, big-endian) - |44 timer value register (read, 32bit, big-endian) - - RESET (write): halts the simulator. The value written to the - register is used as an exit status. - - PROCESSOR ID (read): returns the processor identifier (0 .. N-1) of - the processor performing the read. - - INTERRUPT (write): This register must be written using a two byte - store. The low byte specifies a port and the upper byte specifies - the a level. LEVEL is driven on the specified port. 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 - being asserted. - - PROCESSOR COUNT (read): returns the total number of processors - active in the current simulation. - - TTY INPUT FIFO (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. - - TTY OUTPUT FIFO (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. - - COUNDOWN (read/write): The countdown registers provide a - non-repeating timed interrupt source. Writing a 32 bit big-endian - zero value to this register clears the countdown timer. Writing a - non-zero 32 bit big-endian value to this register sets the - countdown timer to expire in VALUE ticks (ticks is target - dependant). Reading the countdown register returns the last value - writen. - - COUNTDOWN VALUE (read): Reading this 32 bit big-endian register - returns the number of ticks remaining until the countdown timer - expires. - - TIMER (read/write): The timer registers provide a periodic timed - interrupt source. Writing a 32 bit big-endian zero value to this - register clears the periodic timer. Writing a 32 bit non-zero - value to this register sets the periodic timer to triger every - VALUE ticks (ticks is target dependant). Reading the timer - register returns the last value written. - - TIMER VALUE (read): Reading this 32 bit big-endian register returns - the number of ticks until the next periodic interrupt. - - - PROPERTIES - - - reg = <address> <size> (required) - - Specify the address (within the parent bus) that this device is to - be located. - - poll? = <boolean> - - If present and true, indicates that the device should poll its - input. - - - PORTS - - - int[0..NR_PROCESSORS] (output) - - Driven as a result of a write to the interrupt-port / - interrupt-level register pair. - - - countdown - - Driven whenever the countdown counter reaches zero. - - - timer - - Driven whenever the timer counter reaches zero. - - - BUGS - - - At present the common simulator framework does not support input - polling. - - */ - - -enum { - hw_pal_reset_register = 0x0, - hw_pal_cpu_nr_register = 0x4, - hw_pal_int_register = 0x8, - hw_pal_nr_cpu_register = 0xa, - hw_pal_read_fifo = 0x10, - hw_pal_read_status = 0x14, - hw_pal_write_fifo = 0x18, - hw_pal_write_status = 0x1a, - hw_pal_countdown = 0x20, - hw_pal_countdown_value = 0x24, - hw_pal_timer = 0x28, - hw_pal_timer_value = 0x2c, - hw_pal_address_mask = 0x3f, -}; - - -typedef struct _hw_pal_console_buffer { - char buffer; - int status; -} hw_pal_console_buffer; - -typedef struct _hw_pal_counter { - struct hw_event *handler; - signed64 start; - unsigned32 delta; - int periodic_p; -} hw_pal_counter; - - -typedef struct _hw_pal_device { - hw_pal_console_buffer input; - hw_pal_console_buffer output; - hw_pal_counter countdown; - hw_pal_counter timer; - struct hw *disk; - do_hw_poll_read_method *reader; -} hw_pal_device; - -enum { - COUNTDOWN_PORT, - TIMER_PORT, - INT_PORT, -}; - -static const struct hw_port_descriptor hw_pal_ports[] = { - { "countdown", COUNTDOWN_PORT, 0, output_port, }, - { "timer", TIMER_PORT, 0, output_port, }, - { "int", INT_PORT, MAX_NR_PROCESSORS, output_port, }, - { NULL } -}; - - -/* countdown and simple timer */ - -static void -do_counter_event (struct hw *me, - void *data) -{ - hw_pal_counter *counter = (hw_pal_counter *) data; - if (counter->periodic_p) - { - HW_TRACE ((me, "timer expired")); - counter->start = hw_event_queue_time (me); - hw_port_event (me, TIMER_PORT, 1); - hw_event_queue_schedule (me, counter->delta, do_counter_event, counter); - } - else - { - HW_TRACE ((me, "countdown expired")); - counter->delta = 0; - hw_port_event (me, COUNTDOWN_PORT, 1); - } -} - -static void -do_counter_read (struct hw *me, - hw_pal_device *pal, - const char *reg, - hw_pal_counter *counter, - unsigned32 *word, - unsigned nr_bytes) -{ - unsigned32 val; - if (nr_bytes != 4) - hw_abort (me, "%s - bad read size must be 4 bytes", reg); - val = counter->delta; - HW_TRACE ((me, "read - %s %ld", reg, (long) val)); - *word = H2BE_4 (val); -} - -static void -do_counter_value (struct hw *me, - hw_pal_device *pal, - const char *reg, - hw_pal_counter *counter, - unsigned32 *word, - unsigned nr_bytes) -{ - unsigned32 val; - if (nr_bytes != 4) - hw_abort (me, "%s - bad read size must be 4 bytes", reg); - if (counter->delta != 0) - val = (counter->start + counter->delta - - hw_event_queue_time (me)); - else - val = 0; - HW_TRACE ((me, "read - %s %ld", reg, (long) val)); - *word = H2BE_4 (val); -} - -static void -do_counter_write (struct hw *me, - hw_pal_device *pal, - const char *reg, - hw_pal_counter *counter, - const unsigned32 *word, - unsigned nr_bytes) -{ - if (nr_bytes != 4) - hw_abort (me, "%s - bad write size must be 4 bytes", reg); - if (counter->handler != NULL) - { - hw_event_queue_deschedule (me, counter->handler); - counter->handler = NULL; - } - counter->delta = BE2H_4 (*word); - counter->start = hw_event_queue_time (me); - HW_TRACE ((me, "write - %s %ld", reg, (long) counter->delta)); - if (counter->delta > 0) - hw_event_queue_schedule (me, counter->delta, do_counter_event, counter); -} - - - - -/* check the console for an available character */ -static void -scan_hw_pal (struct hw *me) -{ - hw_pal_device *hw_pal = (hw_pal_device *)hw_data (me); - char c; - int count; - count = do_hw_poll_read (me, hw_pal->reader, 0/*STDIN*/, &c, sizeof(c)); - switch (count) - { - case HW_IO_NOT_READY: - case HW_IO_EOF: - hw_pal->input.buffer = 0; - hw_pal->input.status = 0; - break; - default: - hw_pal->input.buffer = c; - hw_pal->input.status = 1; - } -} - -/* write the character to the hw_pal */ - -static void -write_hw_pal (struct hw *me, - char val) -{ - hw_pal_device *hw_pal = (hw_pal_device *) hw_data (me); - sim_io_write_stdout (hw_system (me), &val, 1); - hw_pal->output.buffer = val; - hw_pal->output.status = 1; -} - - -/* Reads/writes */ - -static unsigned -hw_pal_io_read_buffer (struct hw *me, - void *dest, - int space, - unsigned_word addr, - unsigned nr_bytes) -{ - hw_pal_device *hw_pal = (hw_pal_device *) hw_data (me); - unsigned_1 *byte = (unsigned_1 *) dest; - memset (dest, 0, nr_bytes); - switch (addr & hw_pal_address_mask) - { - - case hw_pal_cpu_nr_register: -#ifdef CPU_INDEX - *byte = CPU_INDEX (hw_system_cpu (me)); -#else - *byte = 0; -#endif - HW_TRACE ((me, "read - cpu-nr %d\n", *byte)); - break; - - case hw_pal_nr_cpu_register: - if (hw_tree_find_property (me, "/openprom/options/smp") == NULL) - { - *byte = 1; - HW_TRACE ((me, "read - nr-cpu %d (not defined)\n", *byte)); - } - else - { - *byte = hw_tree_find_integer_property (me, "/openprom/options/smp"); - HW_TRACE ((me, "read - nr-cpu %d\n", *byte)); - } - break; - - case hw_pal_read_fifo: - *byte = hw_pal->input.buffer; - HW_TRACE ((me, "read - input-fifo %d\n", *byte)); - break; - - case hw_pal_read_status: - scan_hw_pal (me); - *byte = hw_pal->input.status; - HW_TRACE ((me, "read - input-status %d\n", *byte)); - break; - - case hw_pal_write_fifo: - *byte = hw_pal->output.buffer; - HW_TRACE ((me, "read - output-fifo %d\n", *byte)); - break; - - case hw_pal_write_status: - *byte = hw_pal->output.status; - HW_TRACE ((me, "read - output-status %d\n", *byte)); - break; - - case hw_pal_countdown: - do_counter_read (me, hw_pal, "countdown", - &hw_pal->countdown, dest, nr_bytes); - break; - - case hw_pal_countdown_value: - do_counter_value (me, hw_pal, "countdown-value", - &hw_pal->countdown, dest, nr_bytes); - break; - - case hw_pal_timer: - do_counter_read (me, hw_pal, "timer", - &hw_pal->timer, dest, nr_bytes); - break; - - case hw_pal_timer_value: - do_counter_value (me, hw_pal, "timer-value", - &hw_pal->timer, dest, nr_bytes); - break; - - default: - HW_TRACE ((me, "read - ???\n")); - break; - - } - return nr_bytes; -} - - -static unsigned -hw_pal_io_write_buffer (struct hw *me, - const void *source, - int space, - unsigned_word addr, - unsigned nr_bytes) -{ - hw_pal_device *hw_pal = (hw_pal_device*) hw_data (me); - unsigned_1 *byte = (unsigned_1 *) source; - - switch (addr & hw_pal_address_mask) - { - - case hw_pal_reset_register: - hw_halt (me, sim_exited, byte[0]); - break; - - case hw_pal_int_register: - hw_port_event (me, - INT_PORT + byte[0], /*port*/ - (nr_bytes > 1 ? byte[1] : 0)); /* val */ - break; - - case hw_pal_read_fifo: - hw_pal->input.buffer = byte[0]; - HW_TRACE ((me, "write - input-fifo %d\n", byte[0])); - break; - - case hw_pal_read_status: - hw_pal->input.status = byte[0]; - HW_TRACE ((me, "write - input-status %d\n", byte[0])); - break; - - case hw_pal_write_fifo: - write_hw_pal (me, byte[0]); - HW_TRACE ((me, "write - output-fifo %d\n", byte[0])); - break; - - case hw_pal_write_status: - hw_pal->output.status = byte[0]; - HW_TRACE ((me, "write - output-status %d\n", byte[0])); - break; - - case hw_pal_countdown: - do_counter_write (me, hw_pal, "countdown", - &hw_pal->countdown, source, nr_bytes); - break; - - case hw_pal_timer: - do_counter_write (me, hw_pal, "timer", - &hw_pal->timer, source, nr_bytes); - break; - - } - return nr_bytes; -} - - -/* instances of the hw_pal struct hw */ - -#if NOT_YET -static void -hw_pal_instance_delete_callback(hw_instance *instance) -{ - /* nothing to delete, the hw_pal is attached to the struct hw */ - return; -} -#endif - -#if NOT_YET -static int -hw_pal_instance_read_callback (hw_instance *instance, - void *buf, - unsigned_word len) -{ - DITRACE (pal, ("read - %s (%ld)", (const char*) buf, (long int) len)); - return sim_io_read_stdin (buf, len); -} -#endif - -#if NOT_YET -static int -hw_pal_instance_write_callback (hw_instance *instance, - const void *buf, - unsigned_word len) -{ - int i; - const char *chp = buf; - hw_pal_device *hw_pal = hw_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]); - sim_io_flush_stdoutput (); - return i; -} -#endif - -#if NOT_YET -static const hw_instance_callbacks hw_pal_instance_callbacks = { - hw_pal_instance_delete_callback, - hw_pal_instance_read_callback, - hw_pal_instance_write_callback, -}; -#endif - -#if 0 -static hw_instance * -hw_pal_create_instance (struct hw *me, - const char *path, - const char *args) -{ - return hw_create_instance_from (me, NULL, - hw_data (me), - path, args, - &hw_pal_instance_callbacks); -} -#endif - - -static void -hw_pal_attach_address (struct hw *me, - int level, - int space, - address_word addr, - address_word nr_bytes, - struct hw *client) -{ - hw_pal_device *pal = (hw_pal_device*) hw_data (me); - pal->disk = client; -} - - -#if 0 -static hw_callbacks const hw_pal_callbacks = { - { generic_hw_init_address, }, - { hw_pal_attach_address, }, /* address */ - { hw_pal_io_read_buffer_callback, - hw_pal_io_write_buffer_callback, }, - { NULL, }, /* DMA */ - { NULL, NULL, hw_pal_interrupt_ports }, /* interrupt */ - { generic_hw_unit_decode, - generic_hw_unit_encode, - generic_hw_address_to_attach_address, - generic_hw_size_to_attach_size }, - hw_pal_create_instance, -}; -#endif - - -static void -hw_pal_finish (struct hw *hw) -{ - /* create the descriptor */ - hw_pal_device *hw_pal = HW_ZALLOC (hw, hw_pal_device); - hw_pal->output.status = 1; - hw_pal->output.buffer = '\0'; - hw_pal->input.status = 0; - hw_pal->input.buffer = '\0'; - set_hw_data (hw, hw_pal); - set_hw_attach_address (hw, hw_pal_attach_address); - set_hw_io_read_buffer (hw, hw_pal_io_read_buffer); - set_hw_io_write_buffer (hw, hw_pal_io_write_buffer); - set_hw_ports (hw, hw_pal_ports); - /* attach ourselves */ - do_hw_attach_regs (hw); - /* If so configured, enable polled input */ - if (hw_find_property (hw, "poll?") != NULL - && hw_find_boolean_property (hw, "poll?")) - { - hw_pal->reader = sim_io_poll_read; - } - else - { - hw_pal->reader = sim_io_read; - } - /* tag the periodic timer */ - hw_pal->timer.periodic_p = 1; -} - - -const struct hw_device_descriptor dv_pal_descriptor[] = { - { "pal", hw_pal_finish, }, - { NULL }, -}; |