diff options
Diffstat (limited to 'sim/ppc/hw_pal.c')
-rw-r--r-- | sim/ppc/hw_pal.c | 385 |
1 files changed, 0 insertions, 385 deletions
diff --git a/sim/ppc/hw_pal.c b/sim/ppc/hw_pal.c deleted file mode 100644 index 64a56f8..0000000 --- a/sim/ppc/hw_pal.c +++ /dev/null @@ -1,385 +0,0 @@ -/* This file is part of the program psim. - - Copyright (C) 1994-1996, 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. - - */ - - -#ifndef _HW_PAL_C_ -#define _HW_PAL_C_ - -#ifndef STATIC_INLINE_HW_PAL -#define STATIC_INLINE_HW_PAL STATIC_INLINE -#endif - -#include "device_table.h" - -#include "cpu.h" - -#include <stdio.h> -#include <fcntl.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 - -#if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL) -#undef WITH_STDIO -#define WITH_STDIO DO_USE_STDIO -#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. 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: - - |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. - - 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 - - reg = <address> <size> (required) - - Specify the address (within the parent bus) that this device is to - live. - - */ - - -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_address_mask = 0x1f, -}; - - -typedef struct _hw_pal_console_buffer { - char buffer; - int status; -} hw_pal_console_buffer; - -typedef struct _hw_pal_device { - hw_pal_console_buffer input; - hw_pal_console_buffer output; -} hw_pal_device; - - -/* check the console for an available character */ -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 - } -} - -/* write the character to the hw_pal */ -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) ; - } - - hw_pal->output.buffer = val; - hw_pal->output.status = 1; -} - - -static unsigned -hw_pal_io_read_buffer_callback(device *me, - void *dest, - int space, - unsigned_word addr, - unsigned nr_bytes, - cpu *processor, - unsigned_word cia) -{ - hw_pal_device *hw_pal = (hw_pal_device*)device_data(me); - unsigned_1 val; - switch (addr & hw_pal_address_mask) { - case hw_pal_cpu_nr_register: - val = cpu_nr(processor); - break; - case hw_pal_nr_cpu_register: - val = device_find_integer_property(me, "/openprom/options/smp"); - break; - case hw_pal_read_fifo: - val = hw_pal->input.buffer; - break; - case hw_pal_read_status: - scan_hw_pal(hw_pal); - val = hw_pal->input.status; - break; - case hw_pal_write_fifo: - val = hw_pal->output.buffer; - break; - case hw_pal_write_status: - val = hw_pal->output.status; - break; - default: - val = 0; - } - memset(dest, 0, nr_bytes); - *(unsigned_1*)dest = val; - return nr_bytes; -} - - -static unsigned -hw_pal_io_write_buffer_callback(device *me, - const void *source, - int space, - unsigned_word addr, - unsigned nr_bytes, - cpu *processor, - unsigned_word cia) -{ - hw_pal_device *hw_pal = (hw_pal_device*)device_data(me); - unsigned_1 *byte = (unsigned_1*)source; - - switch (addr & hw_pal_address_mask) { - case hw_pal_reset_register: - cpu_halt(processor, cia, was_exited, byte[0]); - break; - case hw_pal_int_register: - device_interrupt_event(me, - byte[0], /*port*/ - (nr_bytes > 1 ? byte[1] : 0), /* val */ - processor, cia); - break; - case hw_pal_read_fifo: - hw_pal->input.buffer = byte[0]; - break; - case hw_pal_read_status: - hw_pal->input.status = byte[0]; - break; - case hw_pal_write_fifo: - write_hw_pal(hw_pal, byte[0]); - break; - case hw_pal_write_status: - hw_pal->output.status = byte[0]; - break; - } - return nr_bytes; -} - - -/* instances of the hw_pal device */ - -static void -hw_pal_instance_delete_callback(device_instance *instance) -{ - /* nothing to delete, the hw_pal is attached to the device */ - return; -} - -static int -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); - } -} - -static int -hw_pal_instance_write_callback(device_instance *instance, - const void *buf, - unsigned_word len) -{ - int i; - const char *chp = buf; - hw_pal_device *hw_pal = device_instance_data(instance); - for (i = 0; i < len; i++) - write_hw_pal(hw_pal, chp[i]); - - if (WITH_STDIO == DO_USE_STDIO) { - fflush (stdout); - } - 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, NULL, hw_pal_interrupt_ports }, /* interrupt */ - { NULL, }, /* unit */ - hw_pal_create_instance, -}; - - -static void * -hw_pal_create(const char *name, - const device_unit *unit_address, - const char *args) -{ - /* create the descriptor */ - hw_pal_device *hw_pal = ZALLOC(hw_pal_device); - hw_pal->output.status = 1; - hw_pal->output.buffer = '\0'; - hw_pal->input.status = 0; - hw_pal->input.buffer = '\0'; - return hw_pal; -} - - -const device_descriptor hw_pal_device_descriptor[] = { - { "pal", hw_pal_create, &hw_pal_callbacks }, - { NULL }, -}; - -#endif /* _HW_PAL_C_ */ |