summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-08-17 15:56:55 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-08-17 15:56:55 +0000
commit556fb911c8e8b8de70f38b376e33fd8c8bc87dc6 (patch)
tree7f30c4da40ecd81450ebb7856dc4260c131877d8
parentId reinserted (diff)
downloadrtems-556fb911c8e8b8de70f38b376e33fd8c8bc87dc6.tar.bz2
added tty driver to simhppa
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/hppa1.1/simhppa/tty/tty.c254
1 files changed, 254 insertions, 0 deletions
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 <bsp.h>
+#include <rtems/libio.h>
+
+#include <errno.h>
+
+#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;
+}
+