From 556fb911c8e8b8de70f38b376e33fd8c8bc87dc6 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 17 Aug 1995 15:56:55 +0000 Subject: added tty driver to simhppa --- c/src/lib/libbsp/hppa1.1/simhppa/tty/tty.c | 254 +++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 c/src/lib/libbsp/hppa1.1/simhppa/tty/tty.c (limited to 'c') diff --git a/c/src/lib/libbsp/hppa1.1/simhppa/tty/tty.c b/c/src/lib/libbsp/hppa1.1/simhppa/tty/tty.c new file mode 100644 index 0000000000..9eb59b2c63 --- /dev/null +++ b/c/src/lib/libbsp/hppa1.1/simhppa/tty/tty.c @@ -0,0 +1,254 @@ +/* + * Tty IO Driver + * This is a "libio" driver based on libc/support/generic/libio interface + * which is on top of the RTEMS IO manager. + * + * These provide UNIX-like read and write calls for the C library. + * + * COPYRIGHT (c) 1994 by Division Incorporated + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Division Incorporated not be + * used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * Division Incorporated makes no representations about the + * suitability of this software for any purpose. + * + * tty.c,v 1.2 1995/05/09 20:17:14 joel Exp + */ + +#include +#include + +#include + +#define PRINT_BUFFER_SIZE (16 * 1024) + +/* + * NOTE: this structure is dumplicated in print_dump.c utility + */ + +struct { + int index; + int size; + char buffer[PRINT_BUFFER_SIZE]; +} print_buffer; + +/* always use printf buffer if non-zero */ +int use_print_buffer; + +static int host_read_syscall(int fd, char *buffer, int count); +static int host_write_syscall(int fd, char *buffer, int count); + +rtems_device_driver +tty_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + rtems_status_code status; + + status = rtems_io_register_name("/dev/tty00", + major, + (rtems_device_minor_number) 0); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver +tty_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver +tty_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver +tty_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + return RTEMS_SUCCESSFUL; +} + + +rtems_device_driver +tty_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + rtems_libio_rw_args_t *rw_args; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + /* + * If we are printing to a buffer, then just return newline on all + * read's. If we return 0 bytes read, then the pause() calls in + * the RTEMS tests get hosed (pause() does a gets()) + */ + + if ( use_print_buffer ) + { + *rw_args->buffer = '\n'; + count = 1; + } + else + { + count = host_read_syscall(0, rw_args->buffer, rw_args->count); + } + + if (count >= 0) + { + rw_args->bytes_moved = count; + return RTEMS_SUCCESSFUL; + } + return RTEMS_UNSATISFIED; +} + +rtems_device_driver +tty_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg + ) +{ + unsigned32 level; + rtems_libio_rw_args_t *rw_args; + int count = 0; + int fd = 1; /* XXX fixme; needs to be saved in iop */ + + rw_args = (rtems_libio_rw_args_t *) arg; + + /* + * HACK alert + * + * Some of the simulators have real problems when multi cpu and + * using the system calls. Until this is fixed, if we are multi + * cpu then we write to a printf buffer + */ + + if ( use_print_buffer ) + { + /* save size in memory for dumper */ + if (print_buffer.size == 0) + print_buffer.size = PRINT_BUFFER_SIZE; + + while (rw_args->count-- > 0) + { + rtems_interrupt_disable(level); + print_buffer.buffer[print_buffer.index] = *rw_args->buffer++; + print_buffer.index++; + print_buffer.index &= (PRINT_BUFFER_SIZE - 1); + print_buffer.buffer[print_buffer.index] = 0; + rtems_interrupt_enable(level); + count++; + } + } + else + { +#if 1 + /* + * if on a multi cpu system and writing to stdout, redirect to stderr + * so we can keep them separate + */ + + if ((cpu_number == 1) && (fd == 1)) + fd = 2; +#endif + count = host_write_syscall(fd, rw_args->buffer, rw_args->count); + } + + if (count >= 0) + { + rw_args->bytes_moved = count; + return RTEMS_SUCCESSFUL; + } + return RTEMS_UNSATISFIED; +} + + +/* + * Host system call hack. + * This little trick gets all the args in the right registers + * for the system call and permits simpler inline asm. + * Since this whole thing (syscalls under simulator) is a hack, + * this little bit more is not going to hurt anything. + */ + + +static int +host_read_syscall( + int fd, + char *buffer, + int count + ) +{ + unsigned32 level; + int rc; + + rtems_interrupt_disable(level); + + /* This is an HPUX system call, with return value copied out */ + asm volatile (" stw %%r19,-28(0,%%r30)\n\ + ldil L%%0xc0000000,%%r1\n\ + ble 4(7,%%r1)\n\ + ldi 3,%%r22\n\ + ldw -28(0,%%r30),%%r19\n\ + copy %%r28, %0" + : "=r" (rc) + : ); + + rtems_interrupt_enable(level); + return rc; +} + +static int +host_write_syscall( + int fd, + char *buffer, + int count + ) +{ + unsigned32 level; + int rc; + + rtems_interrupt_disable(level); + + /* This is an HPUX system call, with return value copied out */ + asm volatile (" stw %%r19,-28(0,%%r30)\n\ + ldil L%%0xc0000000,%%r1\n\ + ble 4(7,%%r1)\n\ + ldi 4,%%r22\n\ + ldw -28(0,%%r30),%%r19\n\ + copy %%r28, %0" + : "=r" (rc) + : ); + + rtems_interrupt_enable(level); + return rc; +} + -- cgit v1.2.3