forked from Imagelibrary/rtems
added tty driver to simhppa
This commit is contained in:
254
c/src/lib/libbsp/hppa1.1/simhppa/tty/tty.c
Normal file
254
c/src/lib/libbsp/hppa1.1/simhppa/tty/tty.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user