forked from Imagelibrary/rtems
* e500/mmu/mmu.c, mpc505/ictrl/ictrl.c, mpc505/timer/timer.c, mpc5xx/ictrl/ictrl.c, mpc5xx/timer/timer.c, mpc6xx/altivec/vec_sup.c, mpc6xx/clock/c_clock.c, mpc6xx/mmu/bat.c, mpc6xx/mmu/bat.h, mpc6xx/mmu/pte121.c, mpc8260/timer/timer.c, mpc8xx/timer/timer.c, new-exceptions/cpu.c, new-exceptions/bspsupport/ppc_exc_initialize.c, ppc403/clock/clock.c, ppc403/console/console.c, ppc403/console/console.c.polled, ppc403/console/console405.c, ppc403/irq/ictrl.c, ppc403/tty_drv/tty_drv.c, rtems/powerpc/cache.h, shared/include/powerpc-utility.h, shared/src/cache.c: Use "__asm__" instead of "asm" for improved c99-compliance.
396 lines
9.6 KiB
Plaintext
396 lines
9.6 KiB
Plaintext
/*
|
|
* This file contains the PowerPC 403GA console IO package.
|
|
*
|
|
* Author: Andrew Bray <andy@i-cubed.co.uk>
|
|
*
|
|
* COPYRIGHT (c) 1995 by i-cubed ltd.
|
|
*
|
|
* 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 i-cubed limited not be used in
|
|
* advertising or publicity pertaining to distribution of the
|
|
* software without specific, written prior permission.
|
|
* i-cubed limited makes no representations about the suitability
|
|
* of this software for any purpose.
|
|
*
|
|
* Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
|
|
*
|
|
* COPYRIGHT (c) 1989-2007.
|
|
* On-Line Applications Research Corporation (OAR).
|
|
*
|
|
* The license and distribution terms for this file may be
|
|
* found in the file LICENSE in this distribution or at
|
|
* http://www.rtems.com/license/LICENSE.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#define NO_BSP_INIT
|
|
|
|
#include <rtems.h>
|
|
#include <rtems/libio.h>
|
|
|
|
struct async {
|
|
/*-----------------------------------------------------------------------------+
|
|
| Line Status Register.
|
|
+-----------------------------------------------------------------------------*/
|
|
unsigned char SPLS;
|
|
unsigned char SPLSset;
|
|
#define LSRDataReady 0x80
|
|
#define LSRFramingError 0x40
|
|
#define LSROverrunError 0x20
|
|
#define LSRParityError 0x10
|
|
#define LSRBreakInterrupt 0x08
|
|
#define LSRTxHoldEmpty 0x04
|
|
#define LSRTxShiftEmpty 0x02
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
| Handshake Status Register.
|
|
+-----------------------------------------------------------------------------*/
|
|
unsigned char SPHS;
|
|
unsigned char SPHSset;
|
|
#define HSRDsr 0x80
|
|
#define HSRCts 0x40
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
| Baud rate divisor registers
|
|
+-----------------------------------------------------------------------------*/
|
|
unsigned char BRDH;
|
|
unsigned char BRDL;
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
| Control Register.
|
|
+-----------------------------------------------------------------------------*/
|
|
unsigned char SPCTL;
|
|
#define CRNormal 0x00
|
|
#define CRLoopback 0x40
|
|
#define CRAutoEcho 0x80
|
|
#define CRDtr 0x20
|
|
#define CRRts 0x10
|
|
#define CRWordLength7 0x00
|
|
#define CRWordLength8 0x08
|
|
#define CRParityDisable 0x00
|
|
#define CRParityEnable 0x04
|
|
#define CREvenParity 0x00
|
|
#define CROddParity 0x02
|
|
#define CRStopBitsOne 0x00
|
|
#define CRStopBitsTwo 0x01
|
|
#define CRDisableDtrRts 0x00
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
| Receiver Command Register.
|
|
+-----------------------------------------------------------------------------*/
|
|
unsigned char SPRC;
|
|
#define RCRDisable 0x00
|
|
#define RCREnable 0x80
|
|
#define RCRIntDisable 0x00
|
|
#define RCRIntEnabled 0x20
|
|
#define RCRDMACh2 0x40
|
|
#define RCRDMACh3 0x60
|
|
#define RCRErrorInt 0x10
|
|
#define RCRPauseEnable 0x08
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
| Transmitter Command Register.
|
|
+-----------------------------------------------------------------------------*/
|
|
unsigned char SPTC;
|
|
#define TCRDisable 0x00
|
|
#define TCREnable 0x80
|
|
#define TCRIntDisable 0x00
|
|
#define TCRIntEnabled 0x20
|
|
#define TCRDMACh2 0x40
|
|
#define TCRDMACh3 0x60
|
|
#define TCRTxEmpty 0x10
|
|
#define TCRErrorInt 0x08
|
|
#define TCRStopPause 0x04
|
|
#define TCRBreakGen 0x02
|
|
|
|
/*-----------------------------------------------------------------------------+
|
|
| Miscellanies defines.
|
|
+-----------------------------------------------------------------------------*/
|
|
unsigned char SPTB;
|
|
#define SPRB SPTB
|
|
};
|
|
|
|
#define XOFFchar 0x13
|
|
#define XONchar 0x11
|
|
|
|
typedef volatile struct async *pasync;
|
|
static const pasync port = (pasync)0x40000000;
|
|
|
|
/* console_initialize
|
|
*
|
|
* This routine initializes the console IO driver.
|
|
*
|
|
* Input parameters: NONE
|
|
*
|
|
* Output parameters: NONE
|
|
*
|
|
* Return values:
|
|
*/
|
|
|
|
rtems_device_driver console_initialize(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void *arg
|
|
)
|
|
{
|
|
rtems_status_code status;
|
|
register unsigned tmp;
|
|
extern uint32_t bsp_serial_per_sec;
|
|
extern bool bsp_serial_external_clock;
|
|
extern bool bsp_serial_cts_rts;
|
|
extern uint32_t bsp_serial_rate;
|
|
|
|
/* Initialise the serial port */
|
|
__asm__ volatile ("mfdcr %0, 0xa0" : "=r" (tmp)); /* IOCR */
|
|
tmp &= ~3;
|
|
tmp |= (bsp_serial_external_clock ? 2 : 0) |
|
|
(bsp_serial_cts_rts ? 1 : 0);
|
|
__asm__ volatile ("mtdcr 0xa0, %0" : "=r" (tmp) : "0" (tmp)); /* IOCR */
|
|
port->SPLS = (LSRDataReady | LSRFramingError | LSROverrunError |
|
|
LSRParityError | LSRBreakInterrupt);
|
|
tmp = bsp_serial_per_sec / bsp_get_serial_rate;
|
|
#if 0 /* replaced by IMD... */
|
|
tmp = ((tmp + 8) >> 4) - 1;
|
|
port->BRDL = tmp & 0x255;
|
|
port->BRDH = tmp >> 8;
|
|
#else
|
|
tmp = ((tmp) >> 4) - 1;
|
|
port->BRDL = tmp & 0xff;
|
|
port->BRDH = tmp >> 8;
|
|
#endif
|
|
port->SPCTL = (CRNormal | CRDtr | CRRts | CRWordLength8 | CRParityDisable |
|
|
CRStopBitsOne);
|
|
port->SPRC = (RCREnable | RCRIntDisable | RCRPauseEnable);
|
|
port->SPTC = (TCREnable | TCRIntDisable);
|
|
port->SPHS = (HSRDsr | HSRCts);
|
|
|
|
status = rtems_io_register_name(
|
|
"/dev/console",
|
|
major,
|
|
(rtems_device_minor_number) 0
|
|
);
|
|
|
|
if (status != RTEMS_SUCCESSFUL)
|
|
rtems_fatal_error_occurred(status);
|
|
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
|
|
/* is_character_ready
|
|
*
|
|
* This routine returns TRUE if a character is available.
|
|
*
|
|
* Input parameters: NONE
|
|
*
|
|
* Output parameters: NONE
|
|
*
|
|
* Return values:
|
|
*/
|
|
|
|
bool is_character_ready(
|
|
char *ch
|
|
)
|
|
{
|
|
unsigned char status;
|
|
|
|
if ((status = port->SPLS) & LSRDataReady)
|
|
{
|
|
*ch = port->SPRB;
|
|
return true;
|
|
}
|
|
|
|
/* Clean any dodgy status */
|
|
if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
|
|
LSRBreakInterrupt)) != 0)
|
|
{
|
|
port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
|
|
LSRBreakInterrupt);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/* inbyte
|
|
*
|
|
* This routine reads a character from the SOURCE.
|
|
*
|
|
* Input parameters: NONE
|
|
*
|
|
* Output parameters: NONE
|
|
*
|
|
* Return values:
|
|
* character read from SOURCE
|
|
*/
|
|
|
|
char inbyte( void )
|
|
{
|
|
unsigned char status;
|
|
|
|
while (1)
|
|
{
|
|
if ((status = port->SPLS) & LSRDataReady)
|
|
break;
|
|
|
|
/* Clean any dodgy status */
|
|
if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
|
|
LSRBreakInterrupt)) != 0)
|
|
{
|
|
port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
|
|
LSRBreakInterrupt);
|
|
}
|
|
}
|
|
|
|
return port->SPRB;
|
|
}
|
|
|
|
/* outbyte
|
|
*
|
|
* This routine transmits a character out the SOURCE. It may support
|
|
* XON/XOFF flow control.
|
|
*
|
|
* Input parameters:
|
|
* ch - character to be transmitted
|
|
*
|
|
* Output parameters: NONE
|
|
*/
|
|
|
|
void outbyte(
|
|
char ch
|
|
)
|
|
{
|
|
unsigned char status;
|
|
extern bool bsp_serial_xon_xoff;
|
|
|
|
while (port->SPHS)
|
|
port->SPHS = (HSRDsr | HSRCts);
|
|
|
|
while (1)
|
|
{
|
|
status = port->SPLS;
|
|
|
|
if (port->SPHS)
|
|
port->SPHS = (HSRDsr | HSRCts);
|
|
else if (status & LSRTxHoldEmpty)
|
|
break;
|
|
}
|
|
|
|
if (bsp_serial_xon_xoff)
|
|
while (is_character_ready(&status))
|
|
{
|
|
if (status == XOFFchar)
|
|
do {
|
|
while (!is_character_ready(&status));
|
|
} while (status != XONchar);
|
|
}
|
|
|
|
port->SPTB = ch;
|
|
}
|
|
|
|
/*
|
|
* Open entry point
|
|
*/
|
|
|
|
rtems_device_driver console_open(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void * arg
|
|
)
|
|
{
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*
|
|
* Close entry point
|
|
*/
|
|
|
|
rtems_device_driver console_close(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void * arg
|
|
)
|
|
{
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
|
|
/*
|
|
* read bytes from the serial port. We only have stdin.
|
|
*/
|
|
|
|
rtems_device_driver console_read(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void * arg
|
|
)
|
|
{
|
|
rtems_libio_rw_args_t *rw_args;
|
|
char *buffer;
|
|
int maximum;
|
|
int count = 0;
|
|
|
|
rw_args = (rtems_libio_rw_args_t *) arg;
|
|
|
|
buffer = rw_args->buffer;
|
|
maximum = rw_args->count;
|
|
|
|
for (count = 0; count < maximum; count++) {
|
|
buffer[ count ] = inbyte();
|
|
if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
|
|
buffer[ count++ ] = '\n';
|
|
buffer[ count ] = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
rw_args->bytes_moved = count;
|
|
return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
|
|
}
|
|
|
|
/*
|
|
* write bytes to the serial port. Stdout and stderr are the same.
|
|
*/
|
|
|
|
rtems_device_driver console_write(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void * arg
|
|
)
|
|
{
|
|
int count;
|
|
int maximum;
|
|
rtems_libio_rw_args_t *rw_args;
|
|
char *buffer;
|
|
|
|
rw_args = (rtems_libio_rw_args_t *) arg;
|
|
|
|
buffer = rw_args->buffer;
|
|
maximum = rw_args->count;
|
|
|
|
for (count = 0; count < maximum; count++) {
|
|
if ( buffer[ count ] == '\n') {
|
|
outbyte('\r');
|
|
}
|
|
outbyte( buffer[ count ] );
|
|
}
|
|
return maximum;
|
|
}
|
|
|
|
/*
|
|
* IO Control entry point
|
|
*/
|
|
|
|
rtems_device_driver console_control(
|
|
rtems_device_major_number major,
|
|
rtems_device_minor_number minor,
|
|
void * arg
|
|
)
|
|
{
|
|
return RTEMS_SUCCESSFUL;
|
|
}
|
|
|