From 5edbffe3f64131c582839e0bbd389fda5eeb407c Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 22 Oct 2001 14:46:02 +0000 Subject: 01-10-22 Andy Dachs * mpc8260ads added as new BSP. tm27 reported not to run at this time. * ChangeLog, Makefile.am, README, aclocal.m4, bsp_specs, clock/.cvsignore, clock/Makefile.am, clock/p_clock.c, configure.in, console/Makefile.am, console/console.c, include/Makefile.am, include/bsp.h, include/coverhd.h, irq/.cvsignore, irq/Makefile.am, irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c, network/Makefile.am, network/README, network/if_hdlcsubr.c, network/if_hdlcsubr.h, network/network.c, start/Makefile.am, start/start.S, startup/Makefile.am, startup/bspstart.c, startup/cpuinit.c, startup/linkcmds, startup/setvec.c, times, vectors/.cvsignore, vectors/Makefile.am, vectors/vectors.S, vectors/vectors.h, vectors/vectors_init.c, wrapup/Makefile.am: New files. --- .../libbsp/powerpc/mpc8260ads/console/Makefile.am | 33 ++ .../libbsp/powerpc/mpc8260ads/console/console.c | 478 +++++++++++++++++++++ 2 files changed, 511 insertions(+) create mode 100644 c/src/lib/libbsp/powerpc/mpc8260ads/console/Makefile.am create mode 100644 c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c (limited to 'c/src/lib/libbsp/powerpc/mpc8260ads/console') diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/console/Makefile.am b/c/src/lib/libbsp/powerpc/mpc8260ads/console/Makefile.am new file mode 100644 index 0000000000..26f76d08b9 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/console/Makefile.am @@ -0,0 +1,33 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 + +PGM = $(ARCH)/console.rel + +C_FILES = console.c +C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) + +OBJS = $(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../../../../../../automake/compile.am +include $(top_srcdir)/../../../../../../automake/lib.am + +# +# (OPTIONAL) Add local stuff here using += +# + +$(PGM): $(OBJS) + $(make-rel) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile + +all-local: $(ARCH) $(OBJS) $(PGM) + +.PRECIOUS: $(PGM) + +EXTRA_DIST = console.c + +include $(top_srcdir)/../../../../../../automake/local.am diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c b/c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c new file mode 100644 index 0000000000..476408e3ee --- /dev/null +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/console/console.c @@ -0,0 +1,478 @@ +/* + * console.c + * + * This file contains the MBX8xx termios serial I/O package. + * Only asynchronous I/O is supported. + * + * The SCCs and SMCs are assigned as follows + * + * Channel Device Minor Note + * SMC1 /dev/tty0 0 + * SMC2 /dev/tty1 1 + * SCC1 2 N/A. Hardwired as ethernet port + * SCC2 /dev/tty2 3 + * SCC3 /dev/tty3 4 + * SCC4 /dev/tty4 5 + * + * All ports support termios. The use of termios is recommended for real-time + * applications. Termios provides buffering and input processing. When not + * using termios, processing is limited to the substitution of LF for CR on + * input, and the output of a CR following the output of a LF character. + * Note that the terminal should not send CR/LF pairs when the return key + * is pressed, and that output lines are terminated with LF/CR, not CR/LF + * (although that would be easy to change). + * + * I/O may be interrupt-driven (recommended for real-time applications) or + * polled. Polled I/O may be performed by this device driver entirely, or + * in part by EPPCBug. With EPPCBug 1.1, polled I/O is limited to the + * EPPCBug debug console. This is a limitation of the firmware. Later + * firmware may be able to do I/O through any port. This code assumes + * that the EPPCBug console is the default: SMC1. If the console and + * printk ports are set to anything else with EPPCBug polled I/O, the + * system will hang. Only port SMC1 is usable with EPPCBug polled I/O. + * + * LIMITATIONS: + * + * It is not possible to use different I/O modes on the different ports. The + * exception is with printk. The printk port can use a different mode from + * the other ports. If this is done, it is important not to open the printk + * port from an RTEMS application. + * + * Currently, the I/O modes are determined at build time. It would be much + * better to have the mode selected at boot time based on parameters in + * NVRAM. + * + * Interrupt-driven I/O requires termios. + * + * TESTS: + * + * TO RUN THE TESTS, USE POLLED I/O WITHOUT TERMIOS SUPPORT. Some tests + * play with the interrupt masks and turn off I/O. Those tests will hang + * when interrupt-driven I/O is used. Other tests, such as cdtest, do I/O + * from the static constructors before the console is open. This test + * will not work with interrupt-driven I/O. Because of the buffering + * performed in termios, test output may not be in sequence.The tests + * should all be fixed to work with interrupt-driven I/O and to + * produce output in the expected sequence. Obviously, the termios test + * requires termios support in the driver. + * + * Set CONSOLE_MINOR to the appropriate device minor number in the + * config file. This allows the RTEMS application console to be different + * from the EPPBug debug console or the GDB port. + * + * This driver handles all five available serial ports: it distinguishes + * the sub-devices using minor device numbers. It is not possible to have + * other protocols running on the other ports when this driver is used as + * currently written. + * + * Based on code (alloc860.c in eth_comm port) by + * Jay Monkman (jmonkman@frasca.com), + * Copyright (C) 1998 by Frasca International, Inc. + * + * Modifications by Darlene Stewart + * and Charles-Antoine Gauthier . + * Copyright (c) 2000, National Research Council of Canada + * + * Modifications by Andy Dachs for MPC8260 + * support. + * + * The SCCs and SMCs on the eval board are assigned as follows + * + * Channel Device Minor Termios + * SMC1 /dev/tty3 4 no + * SMC2 /dev/tty4 5 no + * SCC1 /dev/tty0 0 no + * SCC2 /dev/console 1 yes + * SCC3 /dev/tty1 2 no * USED FOR NETWORK I/F + * SCC4 /dev/tty2 3 no * USED FOR NETWORK I/F + * + */ +#include +#include +#include /* Must be before libio.h */ +#include +#include +#include + +static void _BSP_output_char( char c ); +static rtems_status_code do_poll_read( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); +static rtems_status_code do_poll_write( rtems_device_major_number major, rtems_device_minor_number minor, void * arg); + + +BSP_output_char_function_type BSP_output_char = _BSP_output_char; + + + + +/* + * do_poll_read + * + * Input characters through polled I/O. Returns has soon as a character has + * been received. Otherwise, if we wait for the number of requested characters, + * we could be here forever! + * + * CR is converted to LF on input. The terminal should not send a CR/LF pair + * when the return or enter key is pressed. + * + * Input parameters: + * major - ignored. Should be the major number for this driver. + * minor - selected channel. + * arg->buffer - where to put the received characters. + * arg->count - number of characters to receive before returning--Ignored. + * + * Output parameters: + * arg->bytes_moved - the number of characters read. Always 1. + * + * Return value: RTEMS_SUCCESSFUL + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +static rtems_status_code do_poll_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args = arg; + int c; + +#define BSP_READ m8xx_uart_pollRead + + while( (c = BSP_READ(minor)) == -1 ); + rw_args->buffer[0] = (unsigned8)c; + if( rw_args->buffer[0] == '\r' ) + rw_args->buffer[0] = '\n'; + rw_args->bytes_moved = 1; + return RTEMS_SUCCESSFUL; +} + + +/* + * do_poll_write + * + * Output characters through polled I/O. Returns only once every character has + * been sent. + * + * CR is transmitted AFTER a LF on output. + * + * Input parameters: + * major - ignored. Should be the major number for this driver. + * minor - selected channel + * arg->buffer - where to get the characters to transmit. + * arg->count - the number of characters to transmit before returning. + * + * Output parameters: + * arg->bytes_moved - the number of characters read + * + * Return value: RTEMS_SUCCESSFUL + * + * CANNOT BE COMBINED WITH INTERRUPT DRIVEN I/O! + */ +static rtems_status_code do_poll_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args = arg; + unsigned32 i; + char cr ='\r'; + +#define BSP_WRITE m8xx_uart_pollWrite + + for( i = 0; i < rw_args->count; i++ ) { + BSP_WRITE(minor, &(rw_args->buffer[i]), 1); + if ( rw_args->buffer[i] == '\n' ) + BSP_WRITE(minor, &cr, 1); + } + rw_args->bytes_moved = i; + return RTEMS_SUCCESSFUL; + +} + + +/* + * Print functions prototyped in bspIo.h + */ + +static void _BSP_output_char( char c ) +{ + char cr = '\r'; + + /* + * Can't rely on console_initialize having been called before this function + * is used, so it may fail unless output is done through EPPC-Bug. + */ +#define PRINTK_WRITE m8xx_uart_pollWrite + + PRINTK_WRITE( PRINTK_MINOR, &c, 1 ); + if( c == '\n' ) + PRINTK_WRITE( PRINTK_MINOR, &cr, 1 ); + +} + + +/* + *************** + * BOILERPLATE * + *************** + * + * All these functions are prototyped in rtems/c/src/lib/include/console.h. + */ + +/* + * Initialize and register the device + */ +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + rtems_device_minor_number console_minor; + + /* + * Set up TERMIOS if needed + */ + + console_minor = CONSOLE_MINOR; + +#if UARTS_USE_TERMIOS == 1 + + rtems_termios_initialize (); +#else + rtems_termios_initialize (); +#endif /* UARTS_USE_TERMIOS */ + + /* + * Do common initialization. + */ + m8xx_uart_initialize(); + + /* + * Do device-specific initialization + */ +#if 0 + m8xx_uart_smc_initialize(SMC1_MINOR); /* /dev/tty4 */ + m8xx_uart_smc_initialize(SMC2_MINOR); /* /dev/tty5 */ +#endif + + m8xx_uart_scc_initialize(SCC1_MINOR); /* /dev/tty0 */ + m8xx_uart_scc_initialize(SCC2_MINOR); /* /dev/tty1 */ + +#if 0 /* used as network connections */ + m8xx_uart_scc_initialize(SCC3_MINOR); /* /dev/tty2 */ + m8xx_uart_scc_initialize(SCC4_MINOR); /* /dev/tty3 */ +#endif + + + + /* + * Set up interrupts + */ + m8xx_uart_interrupts_initialize(); + + status = rtems_io_register_name ("/dev/tty0", major, SCC1_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + chmod("/dev/tty0",0660); + chown("/dev/tty0",2,0); + + + status = rtems_io_register_name ("/dev/tty1", major, SCC2_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + chmod("/dev/tty1",0660); + chown("/dev/tty1",2,0); + +#if 0 + status = rtems_io_register_name ("/dev/tty2", major, SCC3_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty3", major, SCC4_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty4", major, SMC1_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + + status = rtems_io_register_name ("/dev/tty5", major, SMC2_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); +#endif + /* Now register the RTEMS console */ + status = rtems_io_register_name ("/dev/console", major, console_minor); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + chmod("/dev/console",0666); + chown("/dev/console",2,0); + + return RTEMS_SUCCESSFUL; +} + + +/* + * Open the device + */ +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + /* Used to track termios private data for callbacks */ + extern struct rtems_termios_tty *ttyp[]; + + rtems_libio_open_close_args_t *args = arg; + rtems_status_code sc; + + + static const rtems_termios_callbacks intrCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + m8xx_uart_write, /* write */ + m8xx_uart_setAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; + + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + m8xx_uart_pollRead, /* pollRead */ + m8xx_uart_pollWrite, /* write */ + m8xx_uart_setAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + +#if UARTS_USE_TERMIOS == 1 + +#if UARTS_IO_MODE == 1 /* RTEMS interrupt-driven I/O with termios */ + sc = rtems_termios_open( major, minor, arg, &intrCallbacks ); + ttyp[minor] = args->iop->data1; /* Keep cookie returned by termios_open */ +#else /* RTEMS polled I/O with termios */ + sc = rtems_termios_open( major, minor, arg, &pollCallbacks ); +#endif + +#else /* UARTS_USE_TERMIOS != 1 */ + /* no termios -- default to polled I/O */ + sc = RTEMS_SUCCESSFUL; +#endif /* UARTS_USE_TERMIOS != 1 */ + + return sc; + +} + + +/* + * Close the device + */ +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + +#if UARTS_USE_TERMIOS == 1 + return rtems_termios_close( arg ); +#else + return RTEMS_SUCCESSFUL; +#endif + +} + + +/* + * Read from the device + */ +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + +#if UARTS_USE_TERMIOS == 1 + return rtems_termios_read( arg ); +#else + return do_poll_read( major, minor, arg ); +#endif + +} + + +/* + * Write to the device + */ +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + +#if UARTS_USE_TERMIOS == 1 + return rtems_termios_write( arg ); +#else + /* no termios -- default to polled */ + return do_poll_write( major, minor, arg ); +#endif + +} + + +/* + * Handle ioctl request. + */ +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + if ( minor > NUM_PORTS-1 ) + return RTEMS_INVALID_NUMBER; + + +#if UARTS_USE_TERMIOS == 1 + return rtems_termios_ioctl( arg ); +#else + return RTEMS_SUCCESSFUL; +#endif + +} + +/* + * Support routine for console-generic + */ + +int mbx8xx_console_get_configuration(void) +{ +#if UARTS_IO_MODE == 1 + return 0x02; +#else + return 0; +#endif + +} + -- cgit v1.2.3