diff options
Diffstat (limited to 'c/src/lib/libbsp/powerpc/eth_comm/console')
-rw-r--r-- | c/src/lib/libbsp/powerpc/eth_comm/console/Makefile.in | 54 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/eth_comm/console/console.c | 233 |
2 files changed, 287 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/eth_comm/console/Makefile.in b/c/src/lib/libbsp/powerpc/eth_comm/console/Makefile.in new file mode 100644 index 0000000000..d3ddaf5053 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/eth_comm/console/Makefile.in @@ -0,0 +1,54 @@ +# +# $Id: +# + +@SET_MAKE@ +srcdir = @srcdir@ +VPATH = @srcdir@ +RTEMS_ROOT = @top_srcdir@ +PROJECT_ROOT = @PROJECT_ROOT@ + +PGM=${ARCH}/console.rel + +# C source names, if any, go here -- minus the .c +C_PIECES=console +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= + +SRCS=$(C_FILES) $(H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg +include $(RTEMS_ROOT)/make/leaf.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${PGM}: ${SRCS} ${OBJS} + $(make-rel) + +all: ${ARCH} $(SRCS) $(PGM) + +# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile +install: all diff --git a/c/src/lib/libbsp/powerpc/eth_comm/console/console.c b/c/src/lib/libbsp/powerpc/eth_comm/console/console.c new file mode 100644 index 0000000000..b857c0e280 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/eth_comm/console/console.c @@ -0,0 +1,233 @@ +#define I_WANT_TERMIOS +/* + * BSP specific Serial I/O Functions for the eth-comm BSP + * + * This file contains the BSP specific functions for + * performing serial I/O. These are the functions + * RTEMS uses (the 6 listed in the device driver + * structure) + * + * The SCCs and SMCs are assigned as follows + * + * Channel Device Minor Termios + * SMC1 /dev/tty0 0 no + * SMC2 /dev/tty1 1 no + * SCC1 ethernet + * SCC2 /dev/console 3 yes + * SCC3 /dev/tty3 4 no + * SCC4 /dev/tty4 5 no + * + * FIXME: This should use termios for /dev/console, but it doesn't + * appear to work correctly yet. On startup, with termios enabled, + * the board hangs for a few seconds before running correctly + * + * Author: Jay Monkman (jmonkman@frasca.com) + * Copyright (C) 1998 by Frasca International, Inc. + * + */ +#include <rtems/libio.h> +#include <mpc860.h> +#include <mpc860/console.h> +#include <termios.h> + +rtems_device_driver console_initialize(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + rtems_status_code status; + rtems_isr_entry old_handler; + rtems_status_code sc; + +#ifdef I_WANT_TERMIOS + /* + * Set up TERMIOS (for /dev/console) + */ + rtems_termios_initialize(); +#endif + + /* + * Set up Buffer Descriptors + */ + m860_console_initialize(); + + /* + * Do device-specific initialization + */ + m860_scc_initialize(2); /* /dev/console */ + m860_scc_initialize(3); /* /dev/tty3 */ + m860_scc_initialize(4); /* /dev/tty4 */ + m860_smc_initialize(1); /* /dev/tty0 */ + m860_smc_initialize(2); /* /dev/tty1 */ + + sc = rtems_interrupt_catch (m860_scc2_console_interrupt_handler, + PPC_IRQ_CPM_SCC2, + &old_handler); + sc = rtems_interrupt_catch (m860_scc3_console_interrupt_handler, + PPC_IRQ_CPM_SCC3, + &old_handler); + sc = rtems_interrupt_catch (m860_scc4_console_interrupt_handler, + PPC_IRQ_CPM_SCC4, + &old_handler); + sc = rtems_interrupt_catch (m860_smc1_console_interrupt_handler, + PPC_IRQ_CPM_SMC1, + &old_handler); + sc = rtems_interrupt_catch (m860_smc2_console_interrupt_handler, + PPC_IRQ_CPM_SMC2, + &old_handler); + + /* + * Register the devices + */ + status = rtems_io_register_name ("/dev/console", major, SCC2_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + status = rtems_io_register_name ("/dev/tty0", major, SMC1_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + status = rtems_io_register_name ("/dev/tty1", major, SMC2_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + status = rtems_io_register_name ("/dev/tty3", major, SCC3_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + status = rtems_io_register_name ("/dev/tty4", major, SCC4_MINOR); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + return RTEMS_SUCCESSFUL; +} + +rtems_device_driver console_open(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ + volatile m860SCCRegisters_t *sccregs; + +#ifdef I_WANT_TERMIOS + static const rtems_termios_callbacks sccPollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + m860_char_poll_read, /* pollRead */ + m860_char_poll_write, /* write */ + m860_scc_set_attributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; +#endif /* I_WANT_TERMIOS */ + + sccregs = 0; + + switch (minor) { + case 0: + m860.smc1.smcm = 1; /* Enable SMC1 RX interrupts */ + m860.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ + break; + case 1: + m860.smc2.smcm = 1; /* Enable SMC2 RX interrupts */ + m860.cimr |= 1UL << 3; /* Enable SMC2 interrupts */ + break; + case 2: + m860.cimr |= 1UL << 30; /* Enable SCC1 interrupts */ + sccregs = &m860.scc1; + break; + case 3: +#ifndef I_WANT_TERMIOS + m860.cimr |= 1UL << 29; /* Enable SCC2 interrupts */ +#endif /* I_WANT_TERMIOS */ + sccregs = &m860.scc2; + break; + case 4: + m860.cimr |= 1UL << 28; /* Enable SCC3 interrupts */ + sccregs = &m860.scc3; + break; + case 5: + m860.cimr |= 1UL << 27; /* Enable SCC4 interrupts */ + sccregs = &m860.scc4; + break; + default: + rtems_panic ("CONSOLE: bad minor number"); + } + + if (sccregs) + sccregs->sccm=0x3; + +#ifdef I_WANT_TERMIOS + if (minor == SCC2_MINOR) { + return rtems_termios_open (major, minor, arg, &sccPollCallbacks); + } + else { + return RTEMS_SUCCESSFUL; + } +#else + return RTEMS_SUCCESSFUL; +#endif +} + +rtems_device_driver console_close(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ +#ifdef I_WANT_TERMIOS + if (minor == SCC2_MINOR) { + return rtems_termios_close (arg); + } + else { + return RTEMS_SUCCESSFUL; + } +#else + return RTEMS_SUCCESSFUL; +#endif +} + +rtems_device_driver console_read(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ +#ifdef I_WANT_TERMIOS + if (minor == SCC2_MINOR) { + return rtems_termios_read(arg); + } + else { + return m860_console_read(major, minor, arg); + } +#else + return m860_console_read(major, minor, arg); +#endif +} + +rtems_device_driver console_write(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ +#ifdef I_WANT_TERMIOS + if (minor == SCC2_MINOR) { + return rtems_termios_write(arg); + } + else { + return m860_console_write(major, minor, arg); + } +#else + return m860_console_write(major, minor, arg); +#endif +} + +/* + * Handle ioctl request. + * Should set hardware line speed, bits/char, etc. + */ +rtems_device_driver console_control(rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg) +{ +#ifdef I_WANT_TERMIOS + if (minor == SCC2_MINOR) { + return rtems_termios_ioctl (arg); + } + else { + return RTEMS_SUCCESSFUL; + } +#else + return RTEMS_SUCCESSFUL; +#endif +} + |