diff options
Diffstat (limited to 'c/src/lib/libcpu/powerpc/ppc403')
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/Makefile.am | 5 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/clock/clock.c | 57 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/console/Makefile.am | 7 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/console/console.c | 2 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/console/console405.c | 554 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c | 46 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h | 11 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/timer/timer.c | 20 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/tty_drv/.cvsignore | 2 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/tty_drv/Makefile.am | 32 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.c | 557 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.h | 63 |
12 files changed, 1337 insertions, 19 deletions
diff --git a/c/src/lib/libcpu/powerpc/ppc403/Makefile.am b/c/src/lib/libcpu/powerpc/ppc403/Makefile.am index bd55ab2ed0..4354510022 100644 --- a/c/src/lib/libcpu/powerpc/ppc403/Makefile.am +++ b/c/src/lib/libcpu/powerpc/ppc403/Makefile.am @@ -4,7 +4,12 @@ AUTOMAKE_OPTIONS = foreign 1.4 +if ppc403 SUBDIRS = console clock timer vectors ictrl +endif +if ppc405 +SUBDIRS = console tty_drv clock timer vectors ictrl +endif include $(top_srcdir)/../../../../../automake/subdirs.am include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c b/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c index d7e9514b5f..5ba10ace42 100644 --- a/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c +++ b/c/src/lib/libcpu/powerpc/ppc403/clock/clock.c @@ -25,7 +25,6 @@ * for these modifications: * COPYRIGHT (c) 1997 by IMD, Puchheim, Germany. * - * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * @@ -33,6 +32,8 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * + * Modifications for PPC405GP by Dennis Ehlin + * * $Id$ */ @@ -59,7 +60,11 @@ static inline rtems_unsigned32 get_itimer(void) { register rtems_unsigned32 rc; +#ifndef ppc405 /* this is a ppc403 */ asm volatile ("mfspr %0, 0x3dd" : "=r" ((rc))); /* TBLO */ +#else /* ppc405 */ + asm volatile ("mfspr %0, 0x10c" : "=r" ((rc))); /* 405GP TBL */ +#endif /* ppc405 */ return rc; } @@ -71,11 +76,10 @@ static inline rtems_unsigned32 get_itimer(void) rtems_isr Clock_isr(rtems_vector_number vector) { + rtems_unsigned32 clicks_til_next_interrupt; if (!auto_restart) { - rtems_unsigned32 clicks_til_next_interrupt; rtems_unsigned32 itimer_value; - /* * setup for next interrupt; making sure the new value is reasonably * in the future.... in case we lost out on an interrupt somehow @@ -131,24 +135,25 @@ Clock_isr(rtems_vector_number vector) void Install_clock(rtems_isr_entry clock_isr) { rtems_isr_entry previous_isr; - rtems_unsigned32 pvr, iocr; + rtems_unsigned32 iocr; register rtems_unsigned32 tcr; +#ifdef ppc403 + rtems_unsigned32 pvr; +#endif /* ppc403 */ Clock_driver_ticks = 0; +#ifndef ppc405 /* this is a ppc403 */ asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */ - if (rtems_cpu_configuration_get_timer_internal_clock()) { iocr &= ~4; /* timer clocked from system clock */ } else { iocr |= 4; /* select external timer clock */ } - asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */ asm volatile ("mfspr %0, 0x11f" : "=r" ((pvr))); /* PVR */ - if (((pvr & 0xffff0000) >> 16) != 0x0020) return; /* Not a ppc403 */ @@ -162,10 +167,26 @@ void Install_clock(rtems_isr_entry clock_isr) else if ((pvr & 0xff00) == 0x0100) /* 403GB */ auto_restart = 1; +#else /* ppc405 */ + asm volatile ("mfdcr %0, 0x0b2" : "=r" (iocr)); /*405GP CPC0_CR1 */ + if (rtems_cpu_configuration_get_timer_internal_clock()) { + iocr &=~0x800000 ;/* timer clocked from system clock CETE*/ + } + else { + iocr |= 0x800000; /* select external timer clock CETE*/ + } + asm volatile ("mtdcr 0x0b2, %0" : "=r" (iocr) : "0" (iocr)); /* 405GP CPC0_CR1 */ + + /* + * Enable auto restart + */ + + auto_restart=1; + +#endif /* ppc405 */ pit_value = rtems_configuration_get_microseconds_per_tick() * rtems_cpu_configuration_get_clicks_per_usec(); - /* * initialize the interval here * First tick is set to right amount of time in the future @@ -176,16 +197,19 @@ void Install_clock(rtems_isr_entry clock_isr) rtems_interrupt_catch(clock_isr, PPC_IRQ_PIT, &previous_isr); + /* + * Set PIT value + */ + asm volatile ("mtspr 0x3db, %0" : : "r" (pit_value)); /* PIT */ - asm volatile ("mfspr %0, 0x3da" : "=r" ((tcr))); /* TCR */ - - tcr &= ~ 0x04400000; - - tcr |= (auto_restart ? 0x04400000 : 0x04000000); - + /* + * Set timer to autoreload, bit TCR->ARE = 1 0x0400000 + * Enable PIT interrupt, bit TCR->PIE = 1 0x4000000 + */ tick_time = get_itimer() + pit_value; - + asm volatile ("mfspr %0, 0x3da" : "=r" ((tcr))); /* TCR */ + tcr = (tcr & ~0x04400000) | (auto_restart ? 0x04400000 : 0x04000000); asm volatile ("mtspr 0x3da, %0" : "=r" ((tcr)) : "0" ((tcr))); /* TCR */ atexit(Clock_exit); @@ -208,6 +232,9 @@ ReInstall_clock(rtems_isr_entry new_clock_isr) /* * Called via atexit() * Remove the clock interrupt handler by setting handler to NULL + * + * This will not work on the 405GP because + * when bit's are set in TCR they can only be unset by a reset */ void diff --git a/c/src/lib/libcpu/powerpc/ppc403/console/Makefile.am b/c/src/lib/libcpu/powerpc/ppc403/console/Makefile.am index 923bbe4886..bda2b1c06f 100644 --- a/c/src/lib/libcpu/powerpc/ppc403/console/Makefile.am +++ b/c/src/lib/libcpu/powerpc/ppc403/console/Makefile.am @@ -6,7 +6,12 @@ AUTOMAKE_OPTIONS = foreign 1.4 PGM = $(ARCH)/console.rel +if ppc403 C_FILES = console.c +endif +if ppc405 +C_FILES = console405.c +endif console_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o) @@ -25,6 +30,6 @@ all-local: $(ARCH) $(console_rel_OBJECTS) $(PGM) .PRECIOUS: $(PGM) -EXTRA_DIST = console.c console.c.polled +EXTRA_DIST = console.c console.c.polled console405.c include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libcpu/powerpc/ppc403/console/console.c b/c/src/lib/libcpu/powerpc/ppc403/console/console.c index 9313a9bc90..c92ea2129d 100644 --- a/c/src/lib/libcpu/powerpc/ppc403/console/console.c +++ b/c/src/lib/libcpu/powerpc/ppc403/console/console.c @@ -147,7 +147,7 @@ typedef volatile struct async *pasync; static const pasync port = (pasync)0x40000000; static void *spittyp; /* handle for termios */ -int ppc403_spi_interrupt = 1; /* do not use interrupts... */ +int ppc403_spi_interrupt = 1; /* use interrupts... */ /* * Rx Interrupt handler diff --git a/c/src/lib/libcpu/powerpc/ppc403/console/console405.c b/c/src/lib/libcpu/powerpc/ppc403/console/console405.c new file mode 100644 index 0000000000..3be6423fa3 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/console/console405.c @@ -0,0 +1,554 @@ +/* + * This file contains the PowerPC 405GP console IO package. + * + * Author: Thomas Doerfler <td@imd.m.isar.de> + * IMD Ingenieurbuero fuer Microcomputertechnik + * + * COPYRIGHT (c) 1998 by IMD + * + * Changes from IMD are covered by the original distributions terms. + * changes include interrupt support and termios support + * for backward compatibility, the original polled driver has been + * renamed to console.c.polled + * + * This file has been initially created (polled version) by + * + * 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. + * + * Modifications for spooling (interrupt driven) console driver + * by Thomas Doerfler <td@imd.m.isar.de> + * for these modifications: + * COPYRIGHT (c) 1997 by IMD, Puchheim, Germany. + * + * + * 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. IMD 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, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * Modifications for PPC405GP by Dennis Ehlin + * + * console405.c,v 1.4 1995/12/05 19:23:02 joel Exp + */ + +#define NO_BSP_INIT + +#include <rtems.h> +#include <rtems/libio.h> +#include "../ictrl/ictrl.h" +#include <stdlib.h> /* for atexit() */ + + + +struct async { +/*---------------------------------------------------------------------------+ +| Data Register. ++---------------------------------------------------------------------------*/ + unsigned char RBR; /* 0x00 */ + #define THR RBR +/*---------------------------------------------------------------------------+ +| Interrupt registers ++---------------------------------------------------------------------------*/ + unsigned char IER; /* 0x01 */ + #define IER_RCV 0x01 + #define IER_XMT 0x02 + #define IER_LS 0x04 + #define IER_MS 0x08 + + unsigned char ISR; /* 0x02 */ + #define ISR_MS 0x00 + #define ISR_nIP 0x01 + #define ISR_Tx 0x02 + #define ISR_Rx 0x04 + #define ISR_LS 0x06 + #define ISR_RxTO 0x0C + #define ISR_64BFIFO 0x20 + #define ISR_FIFOworks 0x40 + #define ISR_FIFOen 0x80 + +/*---------------------------------------------------------------------------+ +| FIFO Control registers ++---------------------------------------------------------------------------*/ + #define FCR ISR + #define FCR_FE 0x01 /* FIFO enable */ + #define FCR_CRF 0x02 /* Clear receive FIFO */ + #define FCR_CTF 0x04 /* Clear transmit FIFO */ + #define FCR_DMA 0x08 /* DMA mode select */ + #define FCR_F64 0x20 /* Enable 64 byte fifo (16750+) */ + #define FCR_RT14 0xC0 /* Set Rx trigger at 14 */ + #define FCR_RT8 0x80 /* Set Rx trigger at 8 */ + #define FCR_RT4 0x40 /* Set Rx trigger at 4 */ + #define FCR_RT1 0x00 /* Set Rx trigger at 1 */ + +/*---------------------------------------------------------------------------+ +| Baud rate divisor registers ++---------------------------------------------------------------------------*/ + #define DLL RBR + #define DLM IER + +/*---------------------------------------------------------------------------+ +| Alternate function registers ++---------------------------------------------------------------------------*/ + #define AFR ISR + +/*---------------------------------------------------------------------------+ +| Line control Register. ++---------------------------------------------------------------------------*/ + unsigned char LCR; /* 0x03 */ + #define LCR_WL5 0x00 /* Word length 5 */ + #define LCR_WL6 0x01 /* Word length 6 */ + #define LCR_WL7 0x02 /* Word length 7 */ + #define LCR_WL8 0x03 /* Word length 8 */ + + #define LCR_SB1 0x00 /* 1 stop bits */ + #define LCR_SB1_5 0x04 /* 1.5 stop bits , only valid with 5 bit words*/ + #define LCR_SB1_5 0x04 /* 2 stop bits */ + + #define LCR_PN 0x00 /* Parity NONE */ + #define LCR_PE 0x0C /* Parity EVEN */ + #define LCR_PO 0x08 /* Parity ODD */ + #define LCR_PM 0x28 /* Forced "mark" parity */ + #define LCR_PS 0x38 /* Forced "space" parity */ + + #define LCR_DL 0x80 /* Enable baudrate latch */ + +/*---------------------------------------------------------------------------+ +| Modem control Register. ++---------------------------------------------------------------------------*/ + unsigned char MCR; /* 0x04 */ + #define MCR_DTR 0x01 + #define MCR_RTS 0x02 + #define MCR_INT 0x08 /* Enable interrupts */ + #define MCR_LOOP 0x10 /* Loopback mode */ + +/*---------------------------------------------------------------------------+ +| Line status Register. ++---------------------------------------------------------------------------*/ + unsigned char LSR; /* 0x05 */ + #define LSR_RSR 0x01 + #define LSR_OE 0x02 + #define LSR_PE 0x04 + #define LSR_FE 0x08 + #define LSR_BI 0x10 + #define LSR_THE 0x20 + #define LSR_TEMT 0x40 + #define LSR_FIE 0x80 + +/*---------------------------------------------------------------------------+ +| Modem status Register. ++---------------------------------------------------------------------------*/ + unsigned char MSR; /* 0x06 */ + #define MSR_DCTS 0x01 + #define MSR_DDSR 0x02 + #define MSR_TERI 0x04 + #define MSR_DDCD 0x08 + #define MSR_CTS 0x10 + #define MSR_DSR 0x20 + #define MSR_RI 0x40 + #define MSR_CD 0x80 + +/*---------------------------------------------------------------------------+ +| Scratch pad Register. ++---------------------------------------------------------------------------*/ + unsigned char SCR; /* 0x07 */ +}; + + +#define USE_UART 0 /* 0=UART0 1=UART1 */ +#define UART_INTERNAL_CLOCK_DIVISOR 16 + +typedef volatile struct async *pasync; +static const pasync port = (pasync)(0xEF600300 + (USE_UART*0x100)); /* 0xEF600300 - port A, 0xEF600400 - port B */ + +static void *spittyp; /* handle for termios */ +int ppc403_spi_interrupt = 0; /* do not use interrupts... */ + + +int round(double x) +{ + return (int)((int)((x-(int)x)*1000)>500 ? x+1 : x); +} + +void +spiBaudSet(unsigned32 baudrate) +{ + unsigned32 tmp; + + tmp = round( (double)rtems_cpu_configuration_get_serial_per_sec() / (baudrate * 16) ); + + port->LCR = port->LCR | LCR_DL; + + port->DLL = tmp & 0xff; + port->DLM = tmp >> 8; + + port->LCR = port->LCR & ~LCR_DL; +} +/* + * Hardware-dependent portion of tcsetattr(). + */ +static int +spiSetAttributes (int minor, const struct termios *t) +{ + int baud; + + /* FIXME: check c_cflag & CRTSCTS for hardware flowcontrol */ + /* FIXME: check and IMPLEMENT XON/XOFF */ + switch (t->c_cflag & CBAUD) { + default: baud = -1; break; + case B50: baud = 50; break; + case B75: baud = 75; break; + case B110: baud = 110; break; + case B134: baud = 134; break; + case B150: baud = 150; break; + case B200: baud = 200; break; + case B300: baud = 300; break; + case B600: baud = 600; break; + case B1200: baud = 1200; break; + case B1800: baud = 1800; break; + case B2400: baud = 2400; break; + case B4800: baud = 4800; break; + case B9600: baud = 9600; break; + case B19200: baud = 19200; break; + case B38400: baud = 38400; break; + case B57600: baud = 57600; break; + case B115200: baud = 115200; break; + case B230400: baud = 230400; break; + case B460800: baud = 460800; break; + } + if (baud > 0) { + spiBaudSet(baud); + } + return 0; +} + +static int +spiPollRead (int minor) +{ + + /* Wait for character */ + while ((port->LSR & LSR_RSR)==0);; + + return port->RBR; +} + + +static int +spiPollWrite(int minor,const char *buf,int len) +{ + + while (len-- > 0) { + while (!(port->LSR & LSR_THE));; + port->THR = *buf++; + } + return 0; +} + +/* + * enable/disable RTS line to start/stop remote transmitter + */ +static int +spiStartRemoteTx (int minor) +{ +/* Not implemented ! + rtems_interrupt_level level; + + rtems_interrupt_disable (level); + port->SPCTL |= CRRts; activate RTS + rtems_interrupt_enable (level); +*/ + return 0; +} + +static int +spiStopRemoteTx (int minor) +{ +/* Not implemented ! + rtems_interrupt_level level; + + rtems_interrupt_disable (level); + port->SPCTL &= ~CRRts; deactivate RTS + rtems_interrupt_enable (level); +*/ + return 0; +} + +static int InterruptWrite (int minor, const char *buf, int len) +{ + port->IER |= IER_XMT; /* always enable tx interrupt */ + port->THR = *buf; /* write char to send */ + return 0; +} + +static rtems_isr serial_ISR(rtems_vector_number v) +{ + unsigned char _isr; + char ch; + int res; + + _isr=port->ISR & 0x0E; + + if ((_isr == ISR_Rx) || (_isr==ISR_RxTO)) { + ch = port->RBR; + rtems_termios_enqueue_raw_characters (spittyp,&ch,1); + } + + if (_isr == ISR_Tx) { + res = rtems_termios_dequeue_characters (spittyp,1); + if (res==0) { + port->IER &= ~IER_XMT; + } + + } +} + + +/* + * + * deinit SPI + * + */ +void +spiDeInit(void) +{ + /* + * disable interrupts for serial port + * set it to state to work with polling boot monitor, if any... + */ + + + /* set up baud rate to original state */ + spiBaudSet(rtems_cpu_configuration_get_serial_rate()); + + port->IER = 0; + +} + +/* + * + * init SPI + * + */ +rtems_status_code +spiInitialize(void) +{ + register unsigned tmp; + rtems_isr_entry previous_isr; /* this is a dummy */ + unsigned char _ier; + + /* + * Initialise the serial port + */ + + /* + * Select clock source and set uart internal clock divisor + */ + + asm volatile ("mfdcr %0, 0x0b1" : "=r" (tmp)); /* CPC_CR0 0x0b1 */ + + /* UART0 bit 24 0x80, UART1 bit 25 0x40 */ + tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? (USE_UART ? 0x40 : 0x80) : 0); + + tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? 0: ((UART_INTERNAL_CLOCK_DIVISOR -1) << 1)); + + asm volatile ("mtdcr 0x0b1, %0" : "=r" (tmp) : "0" (tmp)); /* CPC_CR0 0x0b1*/ + + /* Disable port interrupts while changing hardware */ + _ier = port->IER; + port->IER = 0; + + /* set up port control: 8 bit,1 stop,no parity */ + port->LCR = LCR_WL8 | LCR_SB1 | LCR_PN; + + /* set up baud rate */ + spiBaudSet(rtems_cpu_configuration_get_serial_rate()); + + if (ppc403_spi_interrupt) { + + /* add rx/tx isr to vector table */ + if (USE_UART==0) + ictrl_set_vector(serial_ISR,PPC_IRQ_EXT_UART0,&previous_isr); + else + ictrl_set_vector(serial_ISR,PPC_IRQ_EXT_UART1,&previous_isr); + + /* Enable and clear FIFO */ + port->FCR = FCR_FE | FCR_CRF | FCR_CTF | FCR_RT8; + + /* Enable recive interrupts, don't enable TxInt yet */ + port->IER=IER_RCV; + } + else { + port->IER=_ier; + } + + atexit(spiDeInit); + + return RTEMS_SUCCESSFUL; +} + +/* + *************** + * BOILERPLATE * + *************** + */ + +/* 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; + + /* + * Set up TERMIOS + */ + rtems_termios_initialize (); + + /* + * Do device-specific initialization + */ + spiInitialize (); + + /* + * Register the device + */ + status = rtems_io_register_name ("/dev/console", major, 0); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + return RTEMS_SUCCESSFUL; +} + + +/* + * Open entry point + */ + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_status_code sc; + static const rtems_termios_callbacks intrCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + InterruptWrite, /* write */ + spiSetAttributes, /* setAttributes */ + spiStopRemoteTx, /* stopRemoteTx */ + spiStartRemoteTx, /* startRemoteTx */ + 1 /* outputUsesInterrupts */ + }; + + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + spiPollRead, /* pollRead */ + spiPollWrite, /* write */ + spiSetAttributes, /* setAttributes */ + spiStopRemoteTx, /* stopRemoteTx */ + spiStartRemoteTx, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + if (ppc403_spi_interrupt) { + rtems_libio_open_close_args_t *args = arg; + sc = rtems_termios_open (major, minor, arg, &intrCallbacks); + spittyp = args->iop->data1; + } + else { + sc = rtems_termios_open (major, minor, arg, &pollCallbacks); + } + return sc; +} + +/* + * Close entry point + */ + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close (arg); +} + +/* + * 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 +) +{ + return rtems_termios_read (arg); +} + +/* + * 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 +) +{ + return rtems_termios_write (arg); +} + +/* + * IO Control entry point + */ + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl (arg); +} + diff --git a/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c b/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c index 6ba3947bc8..eb8bcb7bd8 100644 --- a/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c +++ b/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.c @@ -18,6 +18,8 @@ * IMD makes no representations about the suitability * of this software for any purpose. * + * Modifications for PPC405GP by Dennis Ehlin + * */ #include "ictrl.h" @@ -41,6 +43,47 @@ rtems_isr_entry ictrl_vector_table[PPC_IRQ_EXT_MAX]; /* * clear bits in EXISR that have a bit set in mask */ +#if defined(ppc405) +RTEMS_INLINE_ROUTINE void +clr_exisr(unsigned32 mask) +{ + asm volatile ("mtdcr 0xC0,%0"::"r" (mask));/*EXISR*/ +} + +/* + * get value of EXISR + */ +RTEMS_INLINE_ROUTINE unsigned32 +get_exisr(void) +{ + unsigned32 val; + + asm volatile ("mfdcr %0,0xC0":"=r" (val));/*EXISR*/ + return val; +} + +/* + * get value of EXIER + */ +RTEMS_INLINE_ROUTINE unsigned32 +get_exier(void) +{ + unsigned32 val; + asm volatile ("mfdcr %0,0xC2":"=r" (val));/*EXIER*/ + return val; +} + +/* + * set value of EXIER + */ +RTEMS_INLINE_ROUTINE void +set_exier(unsigned32 val) +{ + asm volatile ("mtdcr 0xC2,%0"::"r" (val));/*EXIER*/ +} + +#else /* not ppc405 */ + RTEMS_INLINE_ROUTINE void clr_exisr(unsigned32 mask) { @@ -78,7 +121,7 @@ set_exier(unsigned32 val) { asm volatile ("mtdcr 0x42,%0"::"r" (val));/*EXIER*/ } - +#endif /* ppc405 */ /* * enable an external interrupt, make this interrupt consistent */ @@ -191,7 +234,6 @@ ictrl_set_vector(rtems_isr_entry new_handler, /* check for valid vector range */ if ((vector >= PPC_IRQ_EXT_BASE) && (vector < PPC_IRQ_EXT_BASE + PPC_IRQ_EXT_MAX)) { - /* return old handler entry */ *old_handler = ictrl_vector_table[vector - PPC_IRQ_EXT_BASE]; diff --git a/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h b/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h index 5891d8aa2e..6c6f77f0e5 100644 --- a/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h +++ b/c/src/lib/libcpu/powerpc/ppc403/ictrl/ictrl.h @@ -19,6 +19,8 @@ * IMD makes no representations about the suitability * of this software for any purpose. * + * Modifications for PPC405GP by Dennis Ehlin + * */ @@ -40,10 +42,19 @@ extern "C" { /* mask for external interrupt status in EXIER/EXISR register */ /* note: critical interrupt is in these registers aswell */ +#ifndef ppc405 #define PPC_EXI_MASK 0x0FFFFFFF +#else /* ppc405 */ +#define PPC_EXI_MASK 0xFFFFFFFF +#endif /* ppc405 */ +#ifndef ppc405 #define PPC_IRQ_EXT_SPIR (PPC_IRQ_EXT_BASE+4) #define PPC_IRQ_EXT_SPIT (PPC_IRQ_EXT_BASE+5) +#else /* ppc405 */ +#define PPC_IRQ_EXT_UART0 (PPC_IRQ_EXT_BASE+0) +#define PPC_IRQ_EXT_UART1 (PPC_IRQ_EXT_BASE+1) +#endif /* ppc405 */ #define PPC_IRQ_EXT_JTAGR (PPC_IRQ_EXT_BASE+6) #define PPC_IRQ_EXT_JTAGT (PPC_IRQ_EXT_BASE+7) #define PPC_IRQ_EXT_DMA0 (PPC_IRQ_EXT_BASE+8) diff --git a/c/src/lib/libcpu/powerpc/ppc403/timer/timer.c b/c/src/lib/libcpu/powerpc/ppc403/timer/timer.c index 93a188da60..a29851e349 100644 --- a/c/src/lib/libcpu/powerpc/ppc403/timer/timer.c +++ b/c/src/lib/libcpu/powerpc/ppc403/timer/timer.c @@ -30,7 +30,10 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * + * Modifications for PPC405GP by Dennis Ehlin + * * $Id$ + * */ #include <rtems.h> @@ -45,7 +48,13 @@ static inline rtems_unsigned32 get_itimer(void) { rtems_unsigned32 ret; +#ifndef ppc405 asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); /* TBLO */ +#else /* ppc405 */ +/* asm volatile ("mfspr %0, 0x3dd" : "=r" ((ret))); TBLO */ + + asm volatile ("mfspr %0, 0x10c" : "=r" ((ret))); /* 405GP TBL */ +#endif /* ppc405 */ return ret; } @@ -54,10 +63,21 @@ void Timer_initialize() { rtems_unsigned32 iocr; +#ifndef ppc405 asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); /* IOCR */ iocr &= ~4; iocr |= 4; /* Select external timer clock */ asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); /* IOCR */ +#else /* ppc405 */ + asm volatile ("mfdcr %0, 0x0b2" : "=r" (iocr)); /*405GP CPC0_CR1 */ +/* asm volatile ("mfdcr %0, 0xa0" : "=r" (iocr)); IOCR */ + + /* iocr |= 0x800000; select external timer clock CETE*/ + iocr &= ~0x800000; /* timer clocked from system clock CETE*/ + + asm volatile ("mtdcr 0x0b2, %0" : "=r" (iocr) : "0" (iocr)); /* 405GP CPC0_CR1 */ +/* asm volatile ("mtdcr 0xa0, %0" : "=r" (iocr) : "0" (iocr)); IOCR */ +#endif /* ppc405 */ Timer_starting = get_itimer(); } diff --git a/c/src/lib/libcpu/powerpc/ppc403/tty_drv/.cvsignore b/c/src/lib/libcpu/powerpc/ppc403/tty_drv/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/tty_drv/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/c/src/lib/libcpu/powerpc/ppc403/tty_drv/Makefile.am b/c/src/lib/libcpu/powerpc/ppc403/tty_drv/Makefile.am new file mode 100644 index 0000000000..f445fec6d8 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/tty_drv/Makefile.am @@ -0,0 +1,32 @@ +## +## $Id$ +## + +AUTOMAKE_OPTIONS = foreign 1.4 + +PGM = $(ARCH)/tty_drv.rel + +include_HEADERS = tty_drv.h + +C_FILES = tty_drv.c + +tty_drv_rel_OBJECTS = $(C_FILES:%.c=$(ARCH)/%.o) + +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): $(tty_drv_rel_OBJECTS) + $(make-rel) + +all-local: $(ARCH) $(tty_drv_rel_OBJECTS) $(PGM) + +.PRECIOUS: $(PGM) + +EXTRA_DIST = tty_drv.c tty_drv.h + +include $(top_srcdir)/../../../../../automake/local.am diff --git a/c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.c b/c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.c new file mode 100644 index 0000000000..56ff791f41 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.c @@ -0,0 +1,557 @@ +/* + * This file contains the PowerPC 405GP tty driver. + * + * Derived from /c/src/lib/libbsp/i386/shared/comm/tty_drv.c + * + * Modifications to PPC405GP by Dennis Ehlin + * + */ + +#define NO_BSP_INIT + +#include <stdio.h> +#include <rtems/termiostypes.h> +#include <termios.h> +#include <assert.h> +#include <rtems.h> +#include <rtems/libio.h> +#include "../ictrl/ictrl.h" +#include <stdlib.h> /* for atexit() */ + + +struct ttyasync { +/*---------------------------------------------------------------------------+ +| Data Register. ++---------------------------------------------------------------------------*/ + unsigned char RBR; /* 0x00 */ + #define THR RBR +/*---------------------------------------------------------------------------+ +| Interrupt registers ++---------------------------------------------------------------------------*/ + unsigned char IER; /* Interrupt Enable Register 0x01 */ + #define IER_RCV 0x01 + #define IER_XMT 0x02 + #define IER_LS 0x04 + #define IER_MS 0x08 + + unsigned char ISR; /* Interrupt Status Register 0x02 */ + #define ISR_MS 0x00 + #define ISR_nIP 0x01 + #define ISR_Tx 0x02 + #define ISR_Rx 0x04 + #define ISR_LS 0x06 + #define ISR_RxTO 0x0C + #define ISR_64BFIFO 0x20 + #define ISR_FIFOworks 0x40 + #define ISR_FIFOen 0x80 + +/*---------------------------------------------------------------------------+ +| FIFO Control registers ++---------------------------------------------------------------------------*/ + #define FCR ISR + #define FCR_FE 0x01 /* FIFO enable */ + #define FCR_CRF 0x02 /* Clear receive FIFO */ + #define FCR_CTF 0x04 /* Clear transmit FIFO */ + #define FCR_DMA 0x08 /* DMA mode select */ + #define FCR_F64 0x20 /* Enable 64 byte fifo (16750+) */ + #define FCR_RT14 0xC0 /* Set Rx trigger at 14 */ + #define FCR_RT8 0x80 /* Set Rx trigger at 8 */ + #define FCR_RT4 0x40 /* Set Rx trigger at 4 */ + #define FCR_RT1 0x00 /* Set Rx trigger at 1 */ + +/*---------------------------------------------------------------------------+ +| Baud rate divisor registers ++---------------------------------------------------------------------------*/ + #define DLL RBR + #define DLM IER + +/*---------------------------------------------------------------------------+ +| Alternate function registers ++---------------------------------------------------------------------------*/ + #define AFR ISR + +/*---------------------------------------------------------------------------+ +| Line control Register. ++---------------------------------------------------------------------------*/ + unsigned char LCR; /* 0x03 */ + #define LCR_WL5 0x00 /* Word length 5 */ + #define LCR_WL6 0x01 /* Word length 6 */ + #define LCR_WL7 0x02 /* Word length 7 */ + #define LCR_WL8 0x03 /* Word length 8 */ + + #define LCR_SB1 0x00 /* 1 stop bits */ + #define LCR_SB1_5 0x04 /* 1.5 stop bits , only valid with 5 bit words*/ + #define LCR_SB1_5 0x04 /* 2 stop bits */ + + #define LCR_PN 0x00 /* Parity NONE */ + #define LCR_PE 0x0C /* Parity EVEN */ + #define LCR_PO 0x08 /* Parity ODD */ + #define LCR_PM 0x28 /* Forced "mark" parity */ + #define LCR_PS 0x38 /* Forced "space" parity */ + + #define LCR_DL 0x80 /* Enable baudrate latch */ + +/*---------------------------------------------------------------------------+ +| Modem control Register. ++---------------------------------------------------------------------------*/ + unsigned char MCR; /* 0x04 */ + #define MCR_DTR 0x01 + #define MCR_RTS 0x02 + #define MCR_INT 0x08 /* Enable interrupts */ + #define MCR_LOOP 0x10 /* Loopback mode */ + +/*---------------------------------------------------------------------------+ +| Line status Register. ++---------------------------------------------------------------------------*/ + unsigned char LSR; /* 0x05 */ + #define LSR_RSR 0x01 + #define LSR_OE 0x02 + #define LSR_PE 0x04 + #define LSR_FE 0x08 + #define LSR_BI 0x10 + #define LSR_THE 0x20 + #define LSR_TEMT 0x40 + #define LSR_FIE 0x80 + +/*---------------------------------------------------------------------------+ +| Modem status Register. ++---------------------------------------------------------------------------*/ + unsigned char MSR; /* 0x06 */ + #define MSR_DCTS 0x01 + #define MSR_DDSR 0x02 + #define MSR_TERI 0x04 + #define MSR_DDCD 0x08 + #define MSR_CTS 0x10 + #define MSR_DSR 0x20 + #define MSR_RI 0x40 + #define MSR_CD 0x80 + +/*---------------------------------------------------------------------------+ +| Scratch pad Register. ++---------------------------------------------------------------------------*/ + unsigned char SCR; /* 0x07 */ +}; + + +#define TTY0_USE_UART 1 /* 0=UART0 1=UART1 */ +#define TTY0_UART_INTERNAL_CLOCK_DIVISOR 16 +#define TTY0_USE_INTERRUPT + + +typedef volatile struct ttyasync *tty0pasync; +static const tty0pasync tty0port = (tty0pasync)(0xEF600300 + (TTY0_USE_UART*0x100)); /* 0xEF600300 - port A, 0xEF600400 - port B */ + +static void *tty0ttyp; /* handle for termios */ + + +int tty0_round(double x) +{ + return (int)((int)((x-(int)x)*1000)>500 ? x+1 : x); +} + +void +tty0BaudSet(unsigned32 baudrate) +{ + unsigned32 tmp; + + tmp = tty0_round( (double)rtems_cpu_configuration_get_serial_per_sec() / (baudrate * 16) ); + + tty0port->LCR = tty0port->LCR | LCR_DL; + + tty0port->DLL = tmp & 0xff; + tty0port->DLM = tmp >> 8; + + tty0port->LCR = tty0port->LCR & ~LCR_DL; +} +/* + * Hardware-dependent portion of tcsetattr(). + */ +static int +tty0SetAttributes (int minor, const struct termios *t) +{ + int baud; + + /* FIXME: check c_cflag & CRTSCTS for hardware flowcontrol */ + /* FIXME: check and IMPLEMENT XON/XOFF */ + switch (t->c_cflag & CBAUD) { + default: baud = -1; break; + case B50: baud = 50; break; + case B75: baud = 75; break; + case B110: baud = 110; break; + case B134: baud = 134; break; + case B150: baud = 150; break; + case B200: baud = 200; break; + case B300: baud = 300; break; + case B600: baud = 600; break; + case B1200: baud = 1200; break; + case B1800: baud = 1800; break; + case B2400: baud = 2400; break; + case B4800: baud = 4800; break; + case B9600: baud = 9600; break; + case B19200: baud = 19200; break; + case B38400: baud = 38400; break; + case B57600: baud = 57600; break; + case B115200: baud = 115200; break; + case B230400: baud = 230400; break; + case B460800: baud = 460800; break; + } + if (baud > 0) { + tty0BaudSet(baud); + } + return 0; +} + +static int +tty0PollRead (int minor) +{ + + /* Wait for character */ + while ((tty0port->LSR & LSR_RSR)==0);; + + return tty0port->RBR; +} + + +static int +tty0PollWrite(int minor,const char *buf,int len) +{ + + while (len-- > 0) { + while (!(tty0port->LSR & LSR_THE));; + tty0port->THR = *buf++; + } + return 0; +} + +/* ================ Termios support =================*/ + +static int tty0InterruptWrite (int minor, const char *buf, int len) +{ + + if(len <= 0) + { + return 0; + } + + /* Write character */ + + tty0port->THR = (*buf &0xff); + tty0port->IER |= IER_XMT; /* always enable tx interrupt */ + + return 0; + +} + +static rtems_isr tty0serial_ISR(rtems_vector_number v) +{ + char buf[128]; + int off, ret, vect; + + off = 0; + + for(;;) + { + vect = tty0port->ISR & 0x0f; + if(vect & 1) + { + /* no more interrupts */ + if(off > 0) { + /* Update rx buffer */ + rtems_termios_enqueue_raw_characters(tty0ttyp, buf, off ); + + tty0port->IER |= IER_RCV; /* always enable rx interrupt */ + /*rtems_termios_rxirq_occured(tty0ttyp);*/ + } + return; + } + + vect = vect & 0xe; /*mask out all except interrupt pending*/ + + switch(vect) + { + + case ISR_Tx : + /* + * TX holding empty: we have to disable these interrupts + * if there is nothing more to send. + */ + + /* If nothing else to send disable interrupts */ + ret = rtems_termios_dequeue_characters(tty0ttyp, 1); + + if ( ret == 0 ) { + tty0port->IER &= ~IER_XMT; + } + + break; + case ISR_RxTO: + case ISR_Rx : + + /* disable interrupts and notify termios */ + tty0port->IER &= ~IER_RCV; + + /* read all bytes in fifo*/ + while (( off < sizeof(buf) ) && ( tty0port->LSR & LSR_RSR )) + { + buf[off++] = tty0port->RBR; + } + + break; + case ISR_LS: + /* RX error: eat character */ + /* printk("********* Error **********\n"); */ + break; + default: + /* Should not happen */ + /* printk("error vect=%x",vect); */ + return; + } + } + +} + + +/* + * + * deinit TTY0 + * + */ +void +tty0DeInit(void) +{ + /* + * disable interrupts for serial tty0port + * set it to state to work with polling boot monitor, if any... + */ + + /* set up baud rate to original state */ + tty0BaudSet(rtems_cpu_configuration_get_serial_rate()); + + tty0port->IER = 0; + +} + +/* + * + * init SPI + * + */ +rtems_status_code +tty0Initialize(void) +{ + register unsigned tmp; + rtems_isr_entry previous_isr; /* this is a dummy */ + unsigned char _ier; + unsigned char _tmp; + + /* + * Initialise the serial tty0port + */ + + /* + * Select clock source and set uart internal clock divisor + */ + + asm volatile ("mfdcr %0, 0x0b1" : "=r" (tmp)); /* CPC_CR0 0x0b1 */ + + /* UART0 bit 24 0x80, UART1 bit 25 0x40 */ + tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? (TTY0_USE_UART ? 0x40 : 0x80) : 0); + + tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? 0: ((TTY0_UART_INTERNAL_CLOCK_DIVISOR -1) << 1)); + + asm volatile ("mtdcr 0x0b1, %0" : "=r" (tmp) : "0" (tmp)); /* CPC_CR0 0x0b1*/ + + /* Disable tty0port interrupts while changing hardware */ + _ier = tty0port->IER; + tty0port->IER = 0; + + /* set up tty0port control: 8 bit,1 stop,no parity */ + tty0port->LCR = LCR_WL8 | LCR_SB1 | LCR_PN; + + /* set up baud rate */ + tty0BaudSet(rtems_cpu_configuration_get_serial_rate()); + + +#ifdef TTY0_USE_INTERRUPT + + /* add rx/tx isr to vector table */ + + if (TTY0_USE_UART==0) + ictrl_set_vector(tty0serial_ISR,PPC_IRQ_EXT_UART0,&previous_isr); + else + ictrl_set_vector(tty0serial_ISR,PPC_IRQ_EXT_UART1,&previous_isr); + + /* Enable and clear FIFO */ + tty0port->FCR = FCR_FE | FCR_CRF | FCR_CTF | FCR_RT14; + + /* Read status to clear them */ + _tmp = tty0port->LSR; + _tmp = tty0port->RBR; + _tmp = tty0port->MSR; + + /* Enable recive interrupts, don't enable TxInt yet */ + tty0port->IER=IER_RCV; + +#else + + tty0port->IER=_ier; + +#endif + + atexit(tty0DeInit); + + return RTEMS_SUCCESSFUL; +} + +/* + *************** + * BOILERPLATE * + *************** + */ + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver tty0_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + + /* + * Set up TERMIOS + */ + rtems_termios_initialize (); + + /* + * Do device-specific initialization + */ + + /*tty0Initialize (); Moved this to open instead */ + + /* + * Register the device + */ + status = rtems_io_register_name ("/dev/ttyS0", major, 0); + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred (status); + return RTEMS_SUCCESSFUL; +} + + +/* + * Open entry point + */ + +rtems_device_driver tty0_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_status_code sc; + +#ifdef TTY0_USE_INTERRUPT + + static const rtems_termios_callbacks intrCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + NULL, /* pollRead */ + tty0InterruptWrite, /* write */ + tty0SetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + TERMIOS_TASK_DRIVEN /* outputUsesInterrupts */ + }; + rtems_libio_open_close_args_t *args = arg; + + tty0Initialize (); /* Initalize hardware */ + + sc = rtems_termios_open (major, minor, arg, &intrCallbacks); + tty0ttyp = args->iop->data1; + +#else + + static const rtems_termios_callbacks pollCallbacks = { + NULL, /* firstOpen */ + NULL, /* lastClose */ + tty0PollRead, /* pollRead */ + tty0PollWrite, /* write */ + tty0SetAttributes, /* setAttributes */ + NULL, /* stopRemoteTx */ + NULL, /* startRemoteTx */ + 0 /* outputUsesInterrupts */ + }; + + tty0Initialize (); /* Initalize hardware */ + + sc = rtems_termios_open (major, minor, arg, &pollCallbacks); + +#endif + + return sc; +} + +/* + * Close entry point + */ + +rtems_device_driver tty0_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_close (arg); +} + +/* + * read bytes from the serial port. We only have stdin. + */ + +rtems_device_driver tty0_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_read (arg); +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ + +rtems_device_driver tty0_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_write (arg); +} + +/* + * IO Control entry point + */ + +rtems_device_driver tty0_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return rtems_termios_ioctl (arg); +} + diff --git a/c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.h b/c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.h new file mode 100644 index 0000000000..d2024c89d7 --- /dev/null +++ b/c/src/lib/libcpu/powerpc/ppc403/tty_drv/tty_drv.h @@ -0,0 +1,63 @@ +#ifdef ppc405 +#ifndef __tty_drv__ +#define __tty_drv__ + +/* functions */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* ttyS1 entry points */ +rtems_device_driver tty0_initialize( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +rtems_device_driver tty0_open( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +rtems_device_driver tty0_control( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + + +/* tty1 & tty2 shared entry points */ +rtems_device_driver tty0_close( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + + +rtems_device_driver tty0_read( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + +rtems_device_driver tty0_write( + rtems_device_major_number, + rtems_device_minor_number, + void * +); + + +#define TTY0_DRIVER_TABLE_ENTRY \ + { tty0_initialize, tty0_open, tty0_close, \ + tty0_read, tty0_write, tty0_control } + + +#ifdef __cplusplus +} +#endif +/* end of include file */ + +#endif /* __tty_drv__ */ +#endif /* ppc405 */ |