summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/m68k')
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/ChangeLog11
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/console/Makefile.am4
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/console/console.c448
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/console/sci.c1660
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/console/sci.h245
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/include/bsp.h6
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/include/mrm332.h8
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/spurious/spinit.c10
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/start/Makefile.am8
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/start/start.S151
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/start/start.c259
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/startup/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/startup/bspclean.c2
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/startup/linkcmds4
-rw-r--r--c/src/lib/libbsp/m68k/mrm332/startup/start_c.c124
15 files changed, 2333 insertions, 609 deletions
diff --git a/c/src/lib/libbsp/m68k/mrm332/ChangeLog b/c/src/lib/libbsp/m68k/mrm332/ChangeLog
index 3ccbf7081f..e11a955e63 100644
--- a/c/src/lib/libbsp/m68k/mrm332/ChangeLog
+++ b/c/src/lib/libbsp/m68k/mrm332/ChangeLog
@@ -1,3 +1,14 @@
+2002-02-28 Mike Panetta <ahuitzot@mindspring.com>
+
+ * console/sci.c, console/sci.h,
+ console/console.c: Added new SCI driver.
+ * start/start.c: Removed file.
+ * start/start.S: New file, the asm portion of the updated start code.
+ * start/configure.am: Added start.S, removed start.c
+ * startup/start_c.c: New file, the C portion of the updated start code. Contains most of the code that was in the old start.c.
+ * startup/configure.am: Added start_c.c to C_FILES.
+ * include/bsp.h: Added include <rtems/bspIo.h>
+
2001-11-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Introduce RTEMS_BSP_CONFIGURE.
diff --git a/c/src/lib/libbsp/m68k/mrm332/console/Makefile.am b/c/src/lib/libbsp/m68k/mrm332/console/Makefile.am
index 26f76d08b9..9d67d681fb 100644
--- a/c/src/lib/libbsp/m68k/mrm332/console/Makefile.am
+++ b/c/src/lib/libbsp/m68k/mrm332/console/Makefile.am
@@ -6,9 +6,11 @@ AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/console.rel
-C_FILES = console.c
+C_FILES = console.c sci.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
+H_FILES = sci.h
+
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
diff --git a/c/src/lib/libbsp/m68k/mrm332/console/console.c b/c/src/lib/libbsp/m68k/mrm332/console/console.c
index da683764d5..a2fc709b2c 100644
--- a/c/src/lib/libbsp/m68k/mrm332/console/console.c
+++ b/c/src/lib/libbsp/m68k/mrm332/console/console.c
@@ -1,8 +1,12 @@
/*
- * This file contains the mrm console IO package.
+ * This file contains the generic console driver shell used
+ * by all console drivers using libchip.
*
- * COPYRIGHT (c) 1989-1999.
+ * This driver uses the termios pseudo driver.
+ *
+ * COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -11,387 +15,167 @@
* $Id$
*/
-#include <stdlib.h>
#include <bsp.h>
#include <rtems/libio.h>
+#include <termios.h>
+#include "sci.h"
+//#include "../../../../../../rtems/c/src/lib/libbsp/m68k/opti/console/duart.h"
+//#include "../../../../../../rtems/c/src/lib/libc/libio_.h"
-/* BUFFER_LENGTH must be 2^n for n=1, 2, 3, .... */
-#define BUFFER_LENGTH 256
-#define RTS_STOP_SIZE BUFFER_LENGTH-64
-#define RTS_START_SIZE 16
-
-char xmt_buf[BUFFER_LENGTH];
-char rcv_buf[BUFFER_LENGTH];
-/* in: last entry into the buffer; always on a valid character */
-/* out: points to the next character to be pull from the buffer */
-/* in+1=out => buffer empty */
-/* in+2=out => buffer full */
-struct UART_buf {
- char *offset;
- char *in;
- char *out;
-};
-static volatile struct UART_buf xmt = { xmt_buf, (char *)0, (char *)1};
-static volatile struct UART_buf rcv = { rcv_buf, (char *)0, (char *)1};
-static volatile char _debug_flag = 0;
-
-#if 0
-#define SET_RTS(a) {*PORTF0 = (*PORTF0 & ~0x4) | ( (a)? 0 : 0x4); }
-#define GET_CTS (!(*PORTF0 & 0x2))
-#else
-#define SET_RTS(a) {;}
-#define GET_CTS 1
-#endif
-
-/* _catchSCIint, _catchCTSint, and _catchSPURIOUSint are the
- interrupt front-ends */
-extern void _catchSCIint();
-asm(" .text
- .align 2
- .globl _catchSCIint
-_catchSCIint:
- moveml %d0-%d7/%a0-%a6,%sp@- /* save registers */
- jbsr uart_interrupt
- moveml %sp@+,%d0-%d7/%a0-%a6
- rts
- ");
-
-extern void _catchCTSint();
-asm(" .text
- .align 2
- .globl _catchCTSint
-_catchCTSint:
- moveml %d0-%d7/%a0-%a6,%sp@- /* save registers */
- jbsr cts_interrupt
- moveml %sp@+,%d0-%d7/%a0-%a6
- rts
- ");
-
-extern void _catchSPURIOUSint();
-asm(" .text
- .align 2
- .globl _catchSPURIOUSint
-_catchSPURIOUSint:
- moveml %d0-%d7/%a0-%a6,%sp@- /* save registers */
- jbsr spurious_interrupt
- moveml %sp@+,%d0-%d7/%a0-%a6
- rts
- ");
-
-int _spurious_int_counter=0;
-
-/* note: cts uses int1. If it "bounces", a spurious interrupt is generated */
-void spurious_interrupt(void) {
- _spurious_int_counter++; /* there should never be alot of these */
-}
-
-/* _fake_trap_1 will continue the UART interrupt (%sr *still*
- UART_ISR_LEVEL) as a trap #1 to enter the debugger */
-
-/* *****fix me; this is for 68000 w/jsr ram exception table ******* */
-asm(" .text
- .align 2
-_fake_trap_1:
- unlk %a6 /* clear interrupt frame */
- lea %sp@(4),%sp /* remove jbsr instruction */
- moveml %sp@+,%d0-%d7/%a0-%a6 /* pop registers */
- jmp (33*6-12) /* jump exception 1 */
- ");
-
-/* dispatch UART interrupt */
-void xmit_interrupt(void);
-void rcvr_interrupt(void);
-void _fake_trap_1(void);
-
-void uart_interrupt(void) {
- /* receiver status bits are cleared by a SCSR read followed
- by a SCDR read. transmitter status bits are cleared by
- a SCSR read followed by a SCDR write. */
- if ((*SCSR) & (TDRE | TC))
- xmit_interrupt();
-
- if ((*SCSR) & (RDRF))
- rcvr_interrupt();
-
- if (_debug_flag) {
- _debug_flag = 0; /* reset the flag */
- _fake_trap_1(); /* fake a trap #1 */
- }
-}
-
-/* transfer received character to the buffer */
-void rcvr_interrupt(void) {
- register char *a, c;
- register int length;
-
- while((*SCSR) & (RDRF)) {
- if ((c=*SCDR) == 0x1a) /* use ctl-z to reboot */
- reboot();
-/* else if (c == 0x03) { */ /* use ctl-c to enter debugger */
-/* _debug_flag = 1; */
-/* continue; */
-/* } */
-
- *(char *)((int)rcv.offset +(int)
- (a=(char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1)))) = c;
- if ((char *)(((int)rcv.in+2) & ((int)BUFFER_LENGTH-1)) != rcv.out)
- rcv.in=a;
- };
-
- length = (BUFFER_LENGTH -1) & (
- ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out
- + (int)rcv.in + 1);
- if (length >= RTS_STOP_SIZE)
- SET_RTS(0);
-}
-
-/* tranfer buffered characters to the UART */
-void xmit_interrupt(void) {
- register short int oldsr;
-
- _CPU_ISR_Disable( oldsr ); /* for when outbyte or flush calls */
- while ((*SCSR) & (TDRE)) {
- if ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)
- /* xmit buffer not empty */
- if (GET_CTS) {
- /* send next char */
- *SCDR=*(char *)((int)xmt.offset+(int)xmt.out);
- xmt.out= (char *)(((int)xmt.out+1) & ((int)BUFFER_LENGTH-1));
- *SCCR1 = (*SCCR1 & ~(TIE | TCIE)) | (TIE);
- }
- else {
- /* configue CTS interrupt and shutdown xmit interrupts */
- *SCCR1 &= ~(TIE | TCIE);
- *PFPAR |= 0x2;
- break;
- }
- else {
- /* xmit buffer empty; shutdown interrupts */
- *SCCR1 &= ~(TIE | TCIE);
- break;
- }
- }
- _CPU_ISR_Enable( oldsr );
-}
-
-void cts_interrupt(void) {
- register short int oldsr;
-
- _CPU_ISR_Disable( oldsr ); /* for when outbyte calls */
-
- *PFPAR &= ~0x2;
- *SCCR1 = (*SCCR1 & ~(TIE | TCIE)) | (TIE);
-
- _CPU_ISR_Enable( oldsr );
-}
-
-
-
-/* transfer character from the buffer */
-char inbyte(void) {
- register char a;
- register int length;
-
- while ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out);
- a=*(char *)((int)rcv.offset+(int)rcv.out);
- rcv.out= (char *)(((int)rcv.out+1) & ((int)BUFFER_LENGTH-1));
- length = (BUFFER_LENGTH -1) & (
- ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out
- + (int)rcv.in + 1);
- if (length < RTS_START_SIZE)
- SET_RTS(1);
- return (a);
-}
-
-/* once room is avaliable in the buffer, transfer
- the character into the buffer and enable
- the xmtr interrupt */
-void outbyte(char c) {
- register char *a;
-
- while ((char *)(((int)xmt.in+2) & ((int)BUFFER_LENGTH-1)) == xmt.out);
- *(char *)((int)xmt.offset+(int)
- (a=(char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))))=c;
- xmt.in=a;
-
- if (!(*SCCR1 & (TIE | TCIE)) && (!(*PFPAR & 0x2)) )
- /* if neither interrupts are running, */
- xmit_interrupt(); /* we need to restart the xmiter */
-}
-
-void _UART_flush(void) {
- /* loop till xmt buffer empty. Works with interrupts disabled */
- while ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)
- xmit_interrupt();
- /* loop till UART buffer empty */
- while ( (*SCSR & TC) == 0 );
-}
-
-/* console_initialize
- *
- * This routine initializes the console IO driver.
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return values:
- */
-
-void console_init()
-{
- *QSMCR = ( SAM(QSM_IARB,0,IARB) );
- *QILR = ( SAM(ISRL_QSPI,4,ILQSPI) | SAM(ISRL_SCI,0,ILSCI) );
- *QIVR = ( SAM(EFI_QIVR,0,INTV) );
-
- *SCCR0 = ( (int)( SYS_CLOCK/SCI_BAUD/32.0+0.5 ) & 0x1fff );
- *SCCR1 = ( RIE | TE | RE );
-
- set_vector(_catchSPURIOUSint, EFI_SPINT, 1);
- set_vector(_catchSCIint, EFI_QIVR, 1);
- /* set_vector(_catchCTSint, EFI_INT1, 1); */
-}
-
-rtems_device_driver console_initialize(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- rtems_status_code status;
-
- 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
+/*PAGE
*
- * This routine returns TRUE if a character is available.
+ * console_open
*
- * Input parameters: NONE
+ * open a port as a termios console.
*
- * Output parameters: NONE
+ * the console is opened in bsp_postdriver_hook() in bsppost.c
*
- * Return values:
*/
-rtems_boolean is_character_ready(
- char *ch
-)
-{
- if ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out)
- return(FALSE);
- else
- return(TRUE);
-}
-
-/*
- * Open entry point
- */
-
rtems_device_driver console_open(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
- return RTEMS_SUCCESSFUL;
+ rtems_status_code status;
+
+ /* the console is opened three times at startup */
+ /* for standard input, output, and error */
+
+ /* Get correct callback structure for the device */
+
+ /* argument of FALSE gives us interrupt driven serial io */
+ /* argument of TRUE gives us polling based serial io */
+
+ /* SCI internal uart */
+
+ status = rtems_termios_open( major, minor, arg, SciGetTermiosHandlers( TRUE ) );
+
+ return status;
}
-/*
- * Close entry point
+/*PAGE
+ *
+ * console_close
+ *
+ * This routine closes a port that has been opened as console.
*/
-
+
rtems_device_driver console_close(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
- return RTEMS_SUCCESSFUL;
+ return rtems_termios_close (arg);
}
-/*
- * read bytes from the serial port. We only have stdin.
+/*PAGE
+ *
+ * console_read
+ *
+ * This routine uses the termios driver to read a character.
*/
-
+
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;
-
- 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';
- break;
- }
- }
-
- rw_args->bytes_moved = count;
- return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
+ return rtems_termios_read (arg);
}
-/*
- * write bytes to the serial port. Stdout and stderr are the same.
+/*PAGE
+ *
+ * console_write
+ *
+ * this routine uses the termios driver to write a character.
*/
-
+
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 ] );
- }
-
- rw_args->bytes_moved = maximum;
- return 0;
+ return rtems_termios_write (arg);
}
-/*
- * IO Control entry point
+/*PAGE
+ *
+ * console_control
+ *
+ * this routine uses the termios driver to process io
*/
-
+
rtems_device_driver console_control(
rtems_device_major_number major,
rtems_device_minor_number minor,
void * arg
)
{
+ return rtems_termios_ioctl (arg);
+}
+
+/*PAGE
+ *
+ * console_initialize
+ *
+ * Routine called to initialize the console device driver.
+ */
+
+rtems_device_driver console_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor_arg,
+ void *arg
+)
+{
+ rtems_status_code status;
+
+ /*
+ * initialize the termio interface.
+ */
+ rtems_termios_initialize();
+
+
+ /*
+ * register the SCI device name for termios
+ * do this over in the sci driver init routine?
+ */
+
+ status = rtems_io_register_name( "/dev/sci", major, 0 );
+
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(status);
+ }
+
+
+ /*
+ * Link the uart device to the console device
+ */
+
+#if 1
+ status = rtems_io_register_name( "/dev/console", major, 0 );
+
+ if (status != RTEMS_SUCCESSFUL)
+ {
+ rtems_fatal_error_occurred(status);
+ }
+#else
+ if ( link( "/dev/sci", "/dev/console") < 0 )
+ {
+ rtems_fatal_error_occurred( RTEMS_IO_ERROR );
+ }
+#endif
+
+ /*
+ * Console Initialize Succesful
+ */
+
return RTEMS_SUCCESSFUL;
}
+
diff --git a/c/src/lib/libbsp/m68k/mrm332/console/sci.c b/c/src/lib/libbsp/m68k/mrm332/console/sci.c
new file mode 100644
index 0000000000..43e0a89875
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mrm332/console/sci.c
@@ -0,0 +1,1660 @@
+/*****************************************************************************
+* File: sci.c
+*
+* Desc: This file contains the console IO routines for the SCI port.
+* There are two interfaces in this module. One is for the rtems
+* termios/console code and the other is a device driver interface.
+* This module works together with the termio module which is
+* sometimes referred to as the "line disciplines" which implements
+* terminal i/o processing like tabs, backspaces, and newlines.
+* The rtems printf uses interrupt io and the rtems printk routine
+* uses polled io which is better for debugging.
+*
+* Index: Documentation
+* Section A - Include Files
+* Section B - Manifest Constants
+* Section C - External Data
+* Section D - External Functions
+* Section E - Local Functions
+* Section F - Local Variables
+* Section G - A circular data buffer for rcv chars
+* Section H - RTEMS termios callbacks for the interrupt api
+* Section I - RTEMS termios callbacks for the polled api
+
+* Section 0 - Miscellaneous routines
+* Section 1 - Routines to manipulate the circular buffer
+* Section 2 - Interrupt based entry points for the termios module
+* Section 3 - Polling based entry points for the termios module
+* Section 4 - Device driver public api entry points
+* Section 5 - Hardware level routines
+* Section 6 - Testing and debugging code
+*
+* Refer: Motorola QSM Reference Manual - Chapter 5 - SCI sub-module
+*
+* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS.
+*
+* $Id$
+*
+* $Log$
+*****************************************************************************/
+
+
+/*****************************************************************************
+ Compiler Options for the incurably curious
+*****************************************************************************/
+
+/*
+/opt/rtems/bin/m68k-rtems-gcc
+ --pipe # use pipes, not tmp files
+ -B../../../../../../../../opti/lib/ # where the library is
+ -specs bsp_specs # ???
+ -qrtems # ???
+ -g # add debugging info
+ -Wall # issue all warnings
+ -fasm # allow inline asm???
+ -DCONSOLE_SCI # for opti-r box/rev b proto
+ -mcpu32 # machine = motorola cpu 32
+ -c # compile, don't link
+ -O4 # max optimization
+ -fomit-frame-pointer # stack frames are optional
+ -o o-optimize/sci.o # the object file
+ ../../../../../../../../../rtems/c/src/lib/libbsp/m68k/opti/console/sci.c
+*/
+
+
+/*****************************************************************************
+ Overview of serial port console terminal input/output
+*****************************************************************************/
+
+/*
+ +-----------+ +---------+
+ | app | | app |
+ +-----------+ +---------+
+ | |
+ | (printf,scanf,etc.) |
+ v |
+ +-----------+ |
+ | libc | |
+ +-----------+ |
+ | |
+ | |
+ | (open,close,read,write,ioctl) |
+ ======|==========================================|========================
+ | /dev/console | /dev/sci
+ | (stdin,stdout,stderr) |
+ ======|==========================================|========================
+ | |
+ | |
+ v v
+ +-----------+ +-----------+ +---------+
+ | console | <---> | termios | <---> | sci |
+ | driver | | module | | driver |
+ +-----------+ +-----------+ +---------+
+ |
+ |
+ v
+ +---------+
+ | |
+ | uart |
+ | |
+ +---------+
+*/
+
+
+/*****************************************************************************
+ Section A - Include Files
+*****************************************************************************/
+
+//#include <stdlib.h>
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+#include "sci.h"
+//#include "../misc/include/cpu332.h"
+
+
+/*****************************************************************************
+ Section B - Manifest Constants
+*****************************************************************************/
+
+#define SCI_MINOR 0 // minor device number
+
+
+// IMPORTANT - if the device driver api is opened, it means the sci is being
+// used for direct hardware access, so other users (like termios) get ignored
+
+#define DRIVER_CLOSED 0 // the device driver api is closed
+#define DRIVER_OPENED 1 // the device driver api is opened
+
+
+// system clock definitions, i dont have documentation on this...
+
+#if 0 // Not needed, this is provided in mrm332.h
+#define XTAL 32768.0 // crystal frequency in Hz
+#define NUMB_W 0 // system clock parameters
+#define NUMB_X 1
+//efine NUMB_Y 0x38 // for 14.942 Mhz
+#define NUMB_Y 0x3F // for 16.777 Mhz
+
+#define SYS_CLOCK (XTAL * 4.0 * (NUMB_Y+1) * (1 << (2 * NUMB_W + NUMB_X)))
+
+#endif
+
+
+/*****************************************************************************
+ Section C - External Data
+*****************************************************************************/
+
+
+
+
+/*****************************************************************************
+ Section D - External Functions
+*****************************************************************************/
+
+void printf();
+void printk();
+
+#if 0 // Why are these here? They are defined in unistd.h
+
+unsigned16 open();
+unsigned16 close();
+unsigned16 read();
+unsigned16 write();
+unsigned16 ioctl();
+
+#endif
+
+
+
+/*****************************************************************************
+ Section E - Local Functions
+*****************************************************************************/
+
+void SCI_output_char(char c);
+
+rtems_isr SciIsr( rtems_vector_number vector ); // interrupt handler
+
+const rtems_termios_callbacks * SciGetTermiosHandlers( signed32 polled );
+
+rtems_device_driver SciInitialize (); // device driver api
+rtems_device_driver SciOpen (); // device driver api
+rtems_device_driver SciClose (); // device driver api
+rtems_device_driver SciRead (); // device driver api
+rtems_device_driver SciWrite (); // device driver api
+rtems_device_driver SciControl (); // device driver api
+
+signed32 SciInterruptOpen(); // termios api
+signed32 SciInterruptClose(); // termios api
+signed32 SciInterruptWrite(); // termios api
+
+signed32 SciSetAttributes(); // termios api
+
+signed32 SciPolledOpen(); // termios api
+signed32 SciPolledClose(); // termios api
+signed32 SciPolledRead(); // termios api
+signed32 SciPolledWrite(); // termios api
+
+static void SciSetBaud(unsigned32 rate); // hardware routine
+static void SciSetDataBits(unsigned16 bits); // hardware routine
+static void SciSetParity(unsigned16 parity); // hardware routine
+
+static void inline SciDisableAllInterrupts( void ); // hardware routine
+static void inline SciDisableTransmitInterrupts( void );// hardware routine
+static void inline SciDisableReceiveInterrupts( void ); // hardware routine
+
+static void inline SciEnableTransmitInterrupts( void ); // hardware routine
+static void inline SciEnableReceiveInterrupts( void ); // hardware routine
+
+static void inline SciDisableReceiver( void ); // hardware routine
+static void inline SciDisableTransmitter( void ); // hardware routine
+
+static void inline SciEnableReceiver( void ); // hardware routine
+static void inline SciEnableTransmitter( void ); // hardware routine
+
+void SciWriteCharWait ( unsigned8 ); // hardware routine
+void SciWriteCharNoWait( unsigned8 ); // hardware routine
+
+unsigned8 inline SciCharAvailable( void ); // hardware routine
+
+unsigned8 inline SciReadCharWait( void ); // hardware routine
+unsigned8 inline SciReadCharNoWait( void ); // hardware routine
+
+void SciSendBreak( void ); // test routine
+
+static signed8 SciRcvBufGetChar(); // circular rcv buf
+static void SciRcvBufPutChar( unsigned8 ); // circular rcv buf
+//atic void SciRcvBufFlush( void ); // circular rcv buf
+
+void SciUnitTest(); // test routine
+void SciPrintStats(); // test routine
+
+
+/*****************************************************************************
+ Section F - Local Variables
+*****************************************************************************/
+
+static struct rtems_termios_tty *SciTermioTty;
+
+
+static unsigned8 SciInited = 0; // has the driver been inited
+
+static unsigned8 SciOpened; // has the driver been opened
+
+static unsigned8 SciMajor; // major device number
+
+static unsigned16 SciBaud; // current value in baud register
+
+static unsigned32 SciBytesIn = 0; // bytes received
+static unsigned32 SciBytesOut = 0; // bytes transmitted
+
+static unsigned32 SciErrorsParity = 0; // error counter
+static unsigned32 SciErrorsNoise = 0; // error counter
+static unsigned32 SciErrorsFraming = 0; // error counter
+static unsigned32 SciErrorsOverrun = 0; // error counter
+
+#if defined(CONSOLE_SCI)
+
+// this is what rtems printk uses to do polling based output
+
+BSP_output_char_function_type BSP_output_char = SCI_output_char;
+BSP_polling_getchar_function_type BSP_poll_char = NULL;
+
+#endif
+
+
+// cvs id string so you can use the unix ident command on the object
+
+#ifdef ID_STRINGS
+static const char SciIdent[]="$Id$";
+#endif
+
+
+/*****************************************************************************
+ Section G - A circular buffer for rcv chars when the driver interface is used.
+*****************************************************************************/
+
+// it is trivial to wrap your buffer pointers when size is a power of two
+
+#define SCI_RCV_BUF_SIZE 256 // must be a power of 2 !!!
+
+// if someone opens the sci device using the device driver interface,
+// then the receive data interrupt handler will put characters in this buffer
+// instead of sending them up to the termios module for the console
+
+static unsigned8 SciRcvBuffer[SCI_RCV_BUF_SIZE];
+
+static unsigned8 SciRcvBufPutIndex = 0; // array index to put in next char
+
+static unsigned8 SciRcvBufGetIndex = 0; // array index to take out next char
+
+static unsigned8 SciRcvBufCount = 0; // how many bytes are in the buffer
+
+
+
+/*****************************************************************************
+ Section H - RTEMS termios callbacks for the interrupt version of the driver
+*****************************************************************************/
+
+static const rtems_termios_callbacks SciInterruptCallbacks =
+{
+ SciInterruptOpen, // first open
+ SciInterruptClose, // last close
+ NULL, // polled read (not required)
+ SciInterruptWrite, // write
+ SciSetAttributes, // set attributes
+ NULL, // stop remote xmit
+ NULL, // start remote xmit
+ TRUE // output uses interrupts
+};
+
+
+/*****************************************************************************
+ Section I - RTEMS termios callbacks for the polled version of the driver
+*****************************************************************************/
+
+static const rtems_termios_callbacks SciPolledCallbacks =
+{
+ SciPolledOpen, // first open
+ SciPolledClose, // last close
+ SciPolledRead, // polled read
+ SciPolledWrite, // write
+ SciSetAttributes, // set attributes
+ NULL, // stop remote xmit
+ NULL, // start remote xmit
+ FALSE // output uses interrupts
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SECTION 0
+// MISCELLANEOUS ROUTINES
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+/****************************************************************************
+* Func: SCI_output_char
+* Desc: used by rtems printk function to send a char to the uart
+* Inputs: the character to transmit
+* Outputs: none
+* Errors: none
+* Scope: public
+****************************************************************************/
+
+void SCI_output_char(char c)
+{
+// ( minor device number, pointer to the character, length )
+
+ SciPolledWrite( SCI_MINOR, &c, 1);
+
+ return;
+}
+
+
+/****************************************************************************
+* Func: SciGetTermiosHandlers
+* Desc: returns a pointer to the table of serial io functions
+* this is called from console_open with polled set to false
+* Inputs: flag indicating whether we want polled or interrupt driven io
+* Outputs: pointer to function table
+* Errors: none
+* Scope: public
+****************************************************************************/
+
+const rtems_termios_callbacks * SciGetTermiosHandlers( signed32 polled )
+{
+ if ( polled )
+ {
+ return &SciPolledCallbacks; // polling based
+ }
+ else
+ {
+ return &SciInterruptCallbacks; // interrupt driven
+ }
+}
+
+
+/****************************************************************************
+* Func: SciIsr
+* Desc: interrupt handler for serial communications interface
+* Inputs: vector number - unused
+* Outputs: none
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+rtems_isr SciIsr( rtems_vector_number vector )
+{
+ unsigned8 ch;
+
+
+ if ( (*SCSR) & SCI_ERROR_PARITY ) SciErrorsParity ++;
+ if ( (*SCSR) & SCI_ERROR_FRAMING ) SciErrorsFraming ++;
+ if ( (*SCSR) & SCI_ERROR_NOISE ) SciErrorsNoise ++;
+ if ( (*SCSR) & SCI_ERROR_OVERRUN ) SciErrorsOverrun ++;
+
+
+ // see if it was a transmit interrupt
+
+ if ( (*SCSR) & SCI_XMTR_AVAILABLE ) // data reg empty, xmt complete
+ {
+ SciDisableTransmitInterrupts();
+
+ // tell termios module that the charcter was sent
+ // he will call us later to transmit more if there are any
+
+ if (rtems_termios_dequeue_characters( SciTermioTty, 1 ))
+ {
+ // there are more bytes to transmit so enable TX interrupt
+
+ SciEnableTransmitInterrupts();
+ }
+ }
+
+ // see if it was a receive interrupt
+ // on the sci uart we just get one character per interrupt
+
+ while ( SciCharAvailable() ) // char in data register?
+ {
+ ch = SciReadCharNoWait(); // get the char from the uart
+
+ // IMPORTANT!!!
+ // either send it to the termios module or keep it locally
+
+ if ( SciOpened == DRIVER_OPENED ) // the driver is open
+ {
+ SciRcvBufPutChar(ch); // keep it locally
+ }
+ else // put in termios buffer
+ {
+ rtems_termios_enqueue_raw_characters( SciTermioTty, &ch, 1 );
+ }
+
+ *SCSR &= SCI_CLEAR_RX_INT; // clear the interrupt
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SECTION 1
+// ROUTINES TO MANIPULATE THE CIRCULAR BUFFER
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+/****************************************************************************
+* Func: SciRcvBufGetChar
+* Desc: read a character from the circular buffer
+* make sure there is data before you call this!
+* Inputs: none
+* Outputs: the character or -1
+* Errors: none
+* Scope: private
+****************************************************************************/
+
+static signed8 SciRcvBufGetChar()
+{
+ rtems_interrupt_level level;
+ unsigned8 ch;
+
+ if ( SciRcvBufCount == 0 )
+ {
+ rtems_fatal_error_occurred(0xDEAD); // check the count first!
+ }
+
+ rtems_interrupt_disable( level ); // disable interrupts
+
+ ch = SciRcvBuffer[SciRcvBufGetIndex]; // get next byte
+
+ SciRcvBufGetIndex++; // bump the index
+
+ SciRcvBufGetIndex &= SCI_RCV_BUF_SIZE - 1; // and wrap it
+
+ SciRcvBufCount--; // decrement counter
+
+ rtems_interrupt_enable( level ); // restore interrupts
+
+ return ch; // return the char
+}
+
+
+
+/****************************************************************************
+* Func: SciRcvBufPutChar
+* Desc: put a character into the rcv data circular buffer
+* Inputs: the character
+* Outputs: none
+* Errors: none
+* Scope: private
+****************************************************************************/
+
+static void SciRcvBufPutChar( unsigned8 ch )
+{
+ rtems_interrupt_level level;
+
+ if ( SciRcvBufCount == SCI_RCV_BUF_SIZE ) // is there room?
+ {
+ return; // no, throw it away
+ }
+
+ rtems_interrupt_disable( level ); // disable interrupts
+
+ SciRcvBuffer[SciRcvBufPutIndex] = ch; // put it in the buf
+
+ SciRcvBufPutIndex++; // bump the index
+
+ SciRcvBufPutIndex &= SCI_RCV_BUF_SIZE - 1; // and wrap it
+
+ SciRcvBufCount++; // increment counter
+
+ rtems_interrupt_enable( level ); // restore interrupts
+
+ return; // return
+}
+
+
+/****************************************************************************
+* Func: SciRcvBufFlush
+* Desc: completely reset and clear the rcv buffer
+* Inputs: none
+* Outputs: none
+* Errors: none
+* Scope: private
+****************************************************************************/
+
+#if 0 // prevents compiler warning
+static void SciRcvBufFlush( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_disable( level ); // disable interrupts
+
+ memset( SciRcvBuffer, 0, sizeof(SciRcvBuffer) );
+
+ SciRcvBufPutIndex = 0; // clear
+
+ SciRcvBufGetIndex = 0; // clear
+
+ SciRcvBufCount = 0; // clear
+
+ rtems_interrupt_enable( level ); // restore interrupts
+
+ return; // return
+}
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SECTION 2
+// INTERRUPT BASED ENTRY POINTS FOR THE TERMIOS MODULE
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+/****************************************************************************
+* Func: SciInterruptOpen
+* Desc: open routine for the interrupt based device driver
+* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. ??
+* called from rtems_termios_open which is called from console_open
+* Inputs: major - device number
+* minor - device number
+* args - points to terminal info
+* Outputs: success/fail
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+signed32 SciInterruptOpen(
+ signed32 major,
+ signed32 minor,
+ void *arg
+)
+{
+ rtems_libio_open_close_args_t * args = arg;
+ rtems_isr_entry old_vector;
+
+ if ( minor != SCI_MINOR ) // check minor device num
+ {
+ return -1;
+ }
+
+ if ( !args ) // must have args
+ {
+ return -1;
+ }
+
+ SciTermioTty = args->iop->data1; // save address of struct
+
+ SciDisableAllInterrupts(); // turn off sci interrupts
+
+ // THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE
+ // IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!!
+
+// SciSetBaud(115200); // set the baud rate
+// SciSetBaud( 57600); // set the baud rate
+// SciSetBaud( 38400); // set the baud rate
+// SciSetBaud( 19200); // set the baud rate
+ SciSetBaud( 9600); // set the baud rate
+
+ SciSetParity(SCI_PARITY_NONE); // set parity to none
+
+ SciSetDataBits(SCI_8_DATA_BITS); // set data bits to 8
+
+
+ // Install our interrupt handler into RTEMS, where does 66 come from?
+
+ rtems_interrupt_catch( SciIsr, 66, &old_vector );
+
+ *QIVR = 66;
+ *QIVR &= 0xf8;
+ *QILR |= 0x06 & 0x07;
+
+ SciEnableTransmitter(); // enable the transmitter
+
+ SciEnableReceiver(); // enable the receiver
+
+ SciEnableReceiveInterrupts(); // enable rcv interrupts
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciInterruptClose
+* Desc: close routine called by the termios module
+* Inputs: major - device number
+* minor - device number
+* args - unused
+* Outputs: success/fail
+* Errors: none
+* Scope: public - termio entry point
+****************************************************************************/
+
+signed32 SciInterruptClose(
+ signed32 major,
+ signed32 minor,
+ void *arg
+)
+{
+ SciDisableAllInterrupts();
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciInterruptWrite
+* Desc: writes data to the uart using transmit interrupts
+* Inputs: minor - device number
+* buf - points to the data
+* len - number of bytes to send
+* Outputs: success/fail
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+signed32 SciInterruptWrite(
+ signed32 minor,
+ const char *buf,
+ signed32 len
+)
+{
+ // We are using interrupt driven output so termios only sends us
+ // one character at a time. The sci does not have a fifo.
+
+ if ( !len ) // no data?
+ {
+ return 0; // return error
+ }
+
+ if ( minor != SCI_MINOR ) // check the minor dev num
+ {
+ return 0; // return error
+ }
+
+ if ( SciOpened == DRIVER_OPENED ) // is the driver api open?
+ {
+ return 1; // yep, throw this away
+ }
+
+ SciWriteCharNoWait(*buf); // try to send a char
+
+ *SCSR &= SCI_CLEAR_TDRE; // clear tx data reg empty flag
+
+ SciEnableTransmitInterrupts(); // enable the tx interrupt
+
+ return 1; // return success
+}
+
+
+/****************************************************************************
+* Func: SciSetAttributes
+* Desc: setup the uart based on the termios modules requests
+* Inputs: minor - device number
+* t - pointer to the termios info struct
+* Outputs: none
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+signed32 SciSetAttributes(
+ signed32 minor,
+ const struct termios *t
+)
+{
+ unsigned32 baud_requested;
+ unsigned32 sci_rate = 0;
+ unsigned16 sci_parity = 0;
+ unsigned16 sci_databits = 0;
+
+ if ( minor != SCI_MINOR ) // check the minor dev num
+ {
+ return -1; // return error
+ }
+
+ // if you look closely you will see this is the only thing we use
+ // set the baud rate
+
+ baud_requested = t->c_cflag & CBAUD; // baud rate
+
+ if (!baud_requested)
+ {
+ baud_requested = B9600; // default to 9600 baud
+ }
+
+ sci_rate = termios_baud_to_number( baud_requested );
+
+ // parity error detection
+
+ if (t->c_cflag & PARENB) // enable parity detection?
+ {
+ if (t->c_cflag & PARODD)
+ {
+ sci_parity = SCI_PARITY_ODD; // select odd parity
+ }
+ else
+ {
+ sci_parity = SCI_PARITY_EVEN; // select even parity
+ }
+ }
+ else
+ {
+ sci_parity = SCI_PARITY_NONE; // no parity, most common
+ }
+
+
+ // set the number of data bits, 8 is most common
+
+ if (t->c_cflag & CSIZE) // was it specified?
+ {
+ switch (t->c_cflag & CSIZE)
+ {
+ case CS8: sci_databits = SCI_8_DATA_BITS; break;
+ default : sci_databits = SCI_9_DATA_BITS; break;
+ }
+ }
+ else
+ {
+ sci_databits = SCI_8_DATA_BITS; // default to 8 data bits
+ }
+
+
+ // the number of stop bits; always 1 for SCI
+
+ if (t->c_cflag & CSTOPB)
+ {
+ // do nothing
+ }
+
+
+ // setup the hardware with these serial port parameters
+
+ SciSetBaud(sci_rate); // set the baud rate
+
+ SciSetParity(sci_parity); // set the parity type
+
+ SciSetDataBits(sci_databits); // set the data bits
+
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SECTION 3
+// POLLING BASED ENTRY POINTS FOR THE TERMIOS MODULE
+//
+/////////////////////////////////////////////////////////////////////////////
+
+/****************************************************************************
+* Func: SciPolledOpen
+* Desc: open routine for the polled i/o version of the driver
+* called from rtems_termios_open which is called from console_open
+* Inputs: major - device number
+* minor - device number
+* args - points to terminal info struct
+* Outputs: success/fail
+* Errors: none
+* Scope: public - termios entry point
+****************************************************************************/
+
+signed32 SciPolledOpen(
+ signed32 major,
+ signed32 minor,
+ void *arg
+)
+{
+ rtems_libio_open_close_args_t * args = arg;
+
+ if ( minor != SCI_MINOR ) // check minor device num
+ {
+ return -1;
+ }
+
+ if ( !args ) // must have args
+ {
+ return -1;
+ }
+
+ SciTermioTty = args->iop->data1; // Store tty pointer
+
+ SciDisableAllInterrupts(); // don't generate interrupts
+
+ // THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE
+ // IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!!
+
+// SciSetBaud(115200); // set the baud rate
+// SciSetBaud( 57600); // set the baud rate
+// SciSetBaud( 38400); // set the baud rate
+// SciSetBaud( 19200); // set the baud rate
+ SciSetBaud( 9600); // set the baud rate
+
+ SciSetParity(SCI_PARITY_NONE); // set no parity
+
+ SciSetDataBits(SCI_8_DATA_BITS); // set 8 data bits
+
+ SciEnableTransmitter(); // enable the xmitter
+
+ SciEnableReceiver(); // enable the rcvr
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciPolledClose
+* Desc: close routine for the device driver, same for both
+* Inputs: major - device number
+* minor - device number
+* args - unused
+* Outputs: success/fail
+* Errors: none
+* Scope: public termios API
+****************************************************************************/
+
+signed32 SciPolledClose(
+ signed32 major,
+ signed32 minor,
+ void *arg
+)
+{
+ SciDisableAllInterrupts();
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciPolledRead
+* Desc: polling based read routine for the uart
+* Inputs: minor - device number
+* Outputs: error or the character read
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+signed32 SciPolledRead(
+ signed32 minor
+)
+{
+ if ( minor != SCI_MINOR ) // check the minor dev num
+ {
+ return -1; // return error
+ }
+
+ if ( SciCharAvailable() ) // if a char is available
+ {
+ return SciReadCharNoWait(); // read the rx data register
+ }
+
+ return -1; // return error
+}
+
+
+/****************************************************************************
+* Func: SciPolledWrite
+* Desc: writes out characters in polled mode, waiting for the uart
+* check in console_open, but we only seem to use interrupt mode
+* Inputs: minor - device number
+* buf - points to the data
+* len - how many bytes
+* Outputs: error or number of bytes written
+* Errors: none
+* Scope: public termios API
+****************************************************************************/
+
+signed32 SciPolledWrite(
+ signed32 minor,
+ const char *buf,
+ signed32 len
+)
+{
+ signed32 written = 0;
+
+ if ( minor != SCI_MINOR ) // check minor device num
+ {
+ return -1;
+ }
+
+ if ( SciOpened == DRIVER_OPENED ) // is the driver api open?
+ {
+ return -1; // toss the data
+ }
+
+ // send each byte in the string out the port
+
+ while ( written < len )
+ {
+ SciWriteCharWait(*buf++); // send a byte
+
+ written++; // increment counter
+ }
+
+ return written; // return count
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SECTION 4
+// DEVICE DRIVER PUBLIC API ENTRY POINTS
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+/****************************************************************************
+* Func: SciInit
+* Desc: Initialize the lasers device driver and hardware
+* Inputs: major - the major device number which is assigned by rtems
+* minor - the minor device number which is undefined at this point
+* arg - ?????
+* Outputs: RTEMS_SUCCESSFUL
+* Errors: None.
+* Scope: public API
+****************************************************************************/
+
+rtems_device_driver SciInitialize (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_status_code status;
+
+//printk("%s\r\n", __FUNCTION__);
+
+
+ // register the SCI device name for termios console i/o
+ // this is done over in console.c which doesn't seem exactly right
+ // but there were problems doing it here...
+
+// status = rtems_io_register_name( "/dev/sci", major, 0 );
+
+// if (status != RTEMS_SUCCESSFUL)
+// rtems_fatal_error_occurred(status);
+
+
+ SciMajor = major; // save the rtems major number
+
+ SciOpened = DRIVER_CLOSED; // initial state is closed
+
+
+ // if you have an interrupt handler, install it here
+
+
+ SciInited = 1; // set the inited flag
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciOpen
+* Desc: device driver open routine
+* you must open a device before you can anything else
+* only one process can have the device opened at a time
+* you could look at the task id to restrict access if you want
+* Inputs: major - the major device number assigned by rtems
+* minor - the minor device number assigned by us
+* arg - ?????
+* Outputs: see below
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+rtems_device_driver SciOpen (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+//printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor);
+
+ if (SciInited == 0) // must be initialized first!
+ {
+ return RTEMS_NOT_CONFIGURED;
+ }
+
+ if (minor != SCI_MINOR)
+ {
+ return RTEMS_INVALID_NAME; // verify minor number
+ }
+
+ if (SciOpened == DRIVER_OPENED)
+ {
+ return RTEMS_RESOURCE_IN_USE; // already opened!
+ }
+
+ SciOpened = DRIVER_OPENED; // set the opened flag
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciClose
+* Desc: device driver close routine
+* the device must be opened before you can close it
+* the device must be closed before someone (else) can open it
+* Inputs: major - the major device number
+* minor - the minor device number
+* arg - ?????
+* Outputs: see below
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+rtems_device_driver SciClose (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+//printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor);
+
+ if (minor != SCI_MINOR)
+ {
+ return RTEMS_INVALID_NAME; // check the minor number
+ }
+
+ if (SciOpened != DRIVER_OPENED)
+ {
+ return RTEMS_INCORRECT_STATE; // must be opened first
+ }
+
+ SciOpened = DRIVER_CLOSED; // set the flag
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciRead
+* Desc: device driver read routine
+* this function is not meaningful for the laser devices
+* Inputs: major - the major device number
+* minor - the minor device number
+* arg - read/write arguments
+* Outputs: see below
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+rtems_device_driver SciRead (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ rtems_libio_rw_args_t *rw_args; // ptr to argument struct
+ unsigned8 *buffer;
+ unsigned16 length;
+
+ rw_args = (rtems_libio_rw_args_t *) arg; // arguments to read()
+
+
+ if (minor != SCI_MINOR)
+ {
+ return RTEMS_INVALID_NAME; // check the minor number
+ }
+
+ if (SciOpened == DRIVER_CLOSED)
+ {
+ return RTEMS_INCORRECT_STATE; // must be opened first
+ }
+
+ buffer = rw_args->buffer; // points to user's buffer
+
+ length = rw_args->count; // how many bytes they want
+
+// *buffer = SciReadCharWait(); // wait for a character
+
+ // if there isn't a character available, wait until one shows up
+ // or the timeout period expires, which ever happens first
+
+ if ( SciRcvBufCount == 0 ) // no chars
+ {
+ // wait for someone to wake me up...
+ //rtems_task_wake_after(SciReadTimeout);
+ }
+
+ if ( SciRcvBufCount ) // any characters locally?
+ {
+ *buffer = SciRcvBufGetChar(); // get the character
+
+ rw_args->bytes_moved = 1; // how many we actually read
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciWrite
+* Desc: device driver write routine
+* this function is not meaningful for the laser devices
+* Inputs: major - the major device number
+* minor - the minor device number
+* arg - read/write arguments
+* Outputs: see below
+* Errors: non3
+* Scope: public API
+****************************************************************************/
+
+rtems_device_driver SciWrite (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_libio_rw_args_t *rw_args; // ptr to argument struct
+ unsigned8 *buffer;
+ unsigned16 length;
+
+ rw_args = (rtems_libio_rw_args_t *) arg;
+
+ if (minor != SCI_MINOR)
+ {
+ return RTEMS_INVALID_NAME; // check the minor number
+ }
+
+ if (SciOpened == DRIVER_CLOSED)
+ {
+ return RTEMS_INCORRECT_STATE; // must be opened first
+ }
+
+ buffer = (unsigned8*)rw_args->buffer; // points to data
+
+ length = rw_args->count; // how many bytes
+
+ while (length--)
+ {
+ SciWriteCharWait(*buffer++); // send the bytes out
+ }
+
+ rw_args->bytes_moved = rw_args->count; // how many we wrote
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/****************************************************************************
+* Func: SciControl
+* Desc: device driver control routine
+* see below for an example of how to use the ioctl interface
+* Inputs: major - the major device number
+* minor - the minor device number
+* arg - io control args
+* Outputs: see below
+* Errors: none
+* Scope: public API
+****************************************************************************/
+
+rtems_device_driver SciControl (
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void * arg
+)
+{
+ rtems_libio_ioctl_args_t *args = arg; // rtems arg struct
+ unsigned16 command; // the cmd to execute
+ unsigned16 unused; // maybe later
+ unsigned16 *ptr; // ptr to user data
+
+//printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor);
+
+ // do some sanity checking
+
+ if (minor != SCI_MINOR)
+ {
+ return RTEMS_INVALID_NAME; // check the minor number
+ }
+
+ if (SciOpened == DRIVER_CLOSED)
+ {
+ return RTEMS_INCORRECT_STATE; // must be open first
+ }
+
+ if (args == 0)
+ {
+ return RTEMS_INVALID_ADDRESS; // must have args
+ }
+
+ args->ioctl_return = -1; // assume an error
+
+ command = args->command; // get the command
+ ptr = args->buffer; // this is an address
+ unused = *ptr; // brightness
+
+ if (command == SCI_SEND_BREAK) // process the command
+ {
+ SciSendBreak(); // send break char
+ }
+
+ args->ioctl_return = 0; // return status
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SECTION 5
+// HARDWARE LEVEL ROUTINES
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+/****************************************************************************
+* Func: SciSetBaud
+* Desc: setup the uart based on the termios modules requests
+* Inputs: baud rate
+* Outputs: none
+* Errors: none
+* Scope: private
+****************************************************************************/
+
+static void SciSetBaud(unsigned32 rate)
+{
+ unsigned16 value;
+ unsigned16 save_sccr1;
+
+// when you open the console you need to set the termio struct baud rate
+// it has a default value of 9600, when someone calls tcsetattr it reverts!
+
+
+ SciBaud = rate; // save the rate
+
+ // calculate the register value as a float and convert to an int
+ // set baud rate - you must define the system clock constant
+ // see efi332.h for an example
+
+ value = ( (unsigned16) ( SYS_CLOCK / rate / 32.0 + 0.5 ) & 0x1fff );
+
+ save_sccr1 = *SCCR1; // save register
+
+ // also turns off the xmtr and rcvr
+
+ *SCCR1 &= SCI_DISABLE_INT_ALL; // disable interrupts
+
+ *SCCR0 = value; // write the register
+
+ *SCCR1 = save_sccr1; // restore register
+
+ return;
+}
+
+
+/****************************************************************************
+* Func: SciSetParity
+* Desc: setup the uart based on the termios modules requests
+* Inputs: parity
+* Outputs: none
+* Errors: none
+* Scope: private
+****************************************************************************/
+
+static void SciSetParity(unsigned16 parity)
+{
+ unsigned16 value;
+
+ value = *SCCR1; // get the register
+
+ if (parity == SCI_PARITY_ODD)
+ {
+ value |= SCI_PARITY_ENABLE; // parity enabled
+ value |= SCI_PARITY_ODD; // parity odd
+ }
+
+ else if (parity == SCI_PARITY_EVEN)
+ {
+ value |= SCI_PARITY_ENABLE; // parity enabled
+ value &= ~SCI_PARITY_ODD; // parity even
+ }
+
+ else if (parity == SCI_PARITY_NONE)
+ {
+ value &= ~SCI_PARITY_ENABLE; // disabled, most common
+ }
+
+ /* else no changes */
+
+ *SCCR1 = value; // write the register
+
+ return;
+}
+
+
+/****************************************************************************
+* Func: SciSetDataBits
+* Desc: setup the uart based on the termios modules requests
+* Inputs: data bits
+* Outputs: none
+* Errors: none
+* Scope: private
+****************************************************************************/
+
+static void SciSetDataBits(unsigned16 bits)
+{
+ unsigned16 value;
+
+ value = *SCCR1; // get the register
+
+ /* note - the parity setting affects the number of data bits */
+
+ if (bits == SCI_9_DATA_BITS)
+ {
+ value |= SCI_9_DATA_BITS; // 9 data bits
+ }
+
+ else if (bits == SCI_8_DATA_BITS)
+ {
+ value &= SCI_8_DATA_BITS; // 8 data bits
+ }
+
+ /* else no changes */
+
+ *SCCR1 = value; // write the register
+
+ return;
+}
+
+
+/****************************************************************************
+* Func: SciDisableAllInterrupts
+* Func: SciEnableTransmitInterrupts
+* Func: SciEnableReceiveInterrupts
+* Desc: handles generation of interrupts by the sci module
+* Inputs: none
+* Outputs: none
+* Errors: none
+* Scope: private
+****************************************************************************/
+
+static void inline SciDisableAllInterrupts( void )
+{
+ // this also turns off the xmtr and rcvr
+
+ *SCCR1 &= SCI_DISABLE_INT_ALL;
+}
+
+static void inline SciEnableReceiveInterrupts( void )
+{
+ *SCCR1 |= SCI_ENABLE_INT_RX;
+}
+
+static void inline SciDisableReceiveInterrupts( void )
+{
+ *SCCR1 &= SCI_DISABLE_INT_RX;
+}
+
+static void inline SciEnableTransmitInterrupts( void )
+{
+ *SCCR1 |= SCI_ENABLE_INT_TX;
+}
+
+static void inline SciDisableTransmitInterrupts( void )
+{
+ *SCCR1 &= SCI_DISABLE_INT_TX;
+}
+
+
+/****************************************************************************
+* Func: SciEnableTransmitter, SciDisableTransmitter
+* Func: SciEnableReceiver, SciDisableReceiver
+* Desc: turns the transmitter and receiver on and off
+* Inputs: none
+* Outputs: none
+* Errors: none
+* Scope: private
+****************************************************************************/
+
+static void inline SciEnableTransmitter( void )
+{
+ *SCCR1 |= SCI_ENABLE_XMTR;
+}
+
+static void inline SciDisableTransmitter( void )
+{
+ *SCCR1 &= SCI_DISABLE_XMTR;
+}
+
+static void inline SciEnableReceiver( void )
+{
+ *SCCR1 |= SCI_ENABLE_RCVR;
+}
+
+static void inline SciDisableReceiver( void )
+{
+ *SCCR1 &= SCI_DISABLE_RCVR;
+}
+
+
+/****************************************************************************
+* Func: SciWriteCharWait
+* Desc: wait for room in the fifo and then put a char in
+* Inputs: a byte to send
+* Outputs: none
+* Errors: none
+* Scope: public
+****************************************************************************/
+
+void SciWriteCharWait(unsigned8 c)
+{
+ // poll the fifo, waiting for room for another character
+
+ while ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 )
+ {
+ /* Either we are writing to the fifo faster than
+ * the uart can clock bytes out onto the cable,
+ * or we are in flow control (actually no, we
+ * are ignoring flow control from the other end).
+ * In the first case, higher baud rates will help.
+ */
+ }
+
+ *SCDR = c; // send the charcter
+
+ SciBytesOut++; // increment the counter
+
+ return;
+}
+
+
+/****************************************************************************
+* Func: SciWriteCharNoWait
+* Desc: if no room in the fifo throw the char on the floor
+* Inputs: a byte to send
+* Outputs: none
+* Errors: none
+* Scope: public
+****************************************************************************/
+
+void SciWriteCharNoWait(unsigned8 c)
+{
+ if ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 )
+ {
+ return; // no room, throw it away
+ }
+
+ *SCDR = c; // put the char in the fifo
+
+ SciBytesOut++; // increment the counter
+
+ return;
+}
+
+
+/****************************************************************************
+* Func: SciReadCharWait
+* Desc: read a character, waiting for one to show up, if need be
+* Inputs: none
+* Outputs: a character
+* Errors: none
+* Scope: public
+****************************************************************************/
+
+unsigned8 inline SciReadCharWait( void )
+{
+ unsigned8 ch;
+
+ while ( SciCharAvailable() == 0 ) // anything there?
+ {
+ // do nothing
+ }
+
+ // if you have rcv ints enabled, then the isr will probably
+ // get the character before you will unless you turn off ints
+ // ie polling and ints don't mix that well
+
+ ch = *SCDR; // get the charcter
+
+ SciBytesIn++; // increment the counter
+
+ return ch; // return the char
+}
+
+
+/****************************************************************************
+* Func: SciReadCharNoWait
+* Desc: try to get a char but dont wait for one
+* Inputs: none
+* Outputs: a character or -1 if none
+* Errors: none
+* Scope: public
+****************************************************************************/
+
+unsigned8 inline SciReadCharNoWait( void )
+{
+ unsigned8 ch;
+
+ if ( SciCharAvailable() == 0 ) // anything there?
+ return -1;
+
+ ch = *SCDR; // get the character
+
+ SciBytesIn++; // increment the count
+
+ return ch; // return the char
+}
+
+
+
+/****************************************************************************
+* Func: SciCharAvailable
+* Desc: is there a receive character in the data register
+* Inputs: none
+* Outputs: false if no char available, else true
+* Errors: none
+* Scope: public
+****************************************************************************/
+
+unsigned8 inline SciCharAvailable( void )
+{
+ return ( *SCSR & SCI_RCVR_READY ); // char in data register?
+}
+
+
+/****************************************************************************
+* Func: SciSendBreak
+* Desc: send 1 or tow breaks (all zero bits)
+* Inputs: none
+* Outputs: none
+* Errors: none
+* Scope: public
+****************************************************************************/
+
+void SciSendBreak( void )
+{
+ // From the Motorola QSM reference manual -
+
+ // "if SBK is toggled by writing it first to a one and then immediately
+ // to a zero (in less than one serial frame interval), the transmitter
+ // sends only one or two break frames before reverting to mark (idle)
+ // or before commencing to send more data"
+
+ *SCCR1 |= SCI_SEND_BREAK; // set the bit
+
+ *SCCR1 &= ~SCI_SEND_BREAK; // clear the bit
+
+ return;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SECTION 6
+// TEST CODE
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+/****************************************************************************
+* Func: SciUnitTest
+* Desc: test the device driver
+* Inputs: nothing
+* Outputs: nothing
+* Scope: public
+****************************************************************************/
+
+#define O_RDWR LIBIO_FLAGS_READ_WRITE // dont like this but...
+
+void SciUnitTest()
+{
+ unsigned8 byte; // a character
+ unsigned16 fd; // file descriptor for device
+ unsigned16 result; // result of ioctl
+
+
+ fd = open("/dev/sci",O_RDWR); // open the device
+
+printk("SCI open fd=%d\r\n",fd);
+
+
+ result = write(fd, "abcd\r\n", 6); // send a string
+
+printk("SCI write result=%d\r\n",result);
+
+
+ result = read(fd, &byte, 1); // read a byte
+
+printk("SCI read result=%d,byte=%x\r\n",result,byte);
+
+ return;
+}
+
+
+/****************************************************************************
+* Func: SciPrintStats
+* Desc: print out some driver information
+* Inputs: nothing
+* Outputs: nothing
+* Scope: public
+****************************************************************************/
+
+void SciPrintStats ( void )
+{
+ printf("\r\n");
+
+ printf( "SYS_CLOCK is %2.6f Mhz\r\n\n", SYS_CLOCK / 1000000.0 );
+
+ printf( "Current baud rate is %d bps or %d cps\r\n\n", SciBaud, SciBaud / 10 );
+
+ printf( "SCI Uart chars in %8d\r\n", SciBytesIn );
+ printf( "SCI Uart chars out %8d\r\n", SciBytesOut );
+ printf( "SCI Uart framing errors %8d\r\n", SciErrorsFraming );
+ printf( "SCI Uart parity errors %8d\r\n", SciErrorsParity );
+ printf( "SCI Uart overrun errors %8d\r\n", SciErrorsOverrun );
+ printf( "SCI Uart noise errors %8d\r\n", SciErrorsNoise );
+
+ return;
+}
+
+
+
diff --git a/c/src/lib/libbsp/m68k/mrm332/console/sci.h b/c/src/lib/libbsp/m68k/mrm332/console/sci.h
new file mode 100644
index 0000000000..7f4ddfaf18
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mrm332/console/sci.h
@@ -0,0 +1,245 @@
+/****************************************************************************
+* File: sci.h
+*
+* Desc: This is the include file for the serial communications interface.
+*
+* Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS.
+*
+* $Id$
+****************************************************************************/
+
+
+#ifndef _sci_h_
+#define _sci_h_
+
+
+/*******************************************************************************
+ IOCTL commands for the sci driver.
+ I'm still working on these...
+*******************************************************************************/
+
+#define SCI_IOCTL_PARITY_NONE 0x00 // no parity bit after the data bits
+#define SCI_IOCTL_PARITY_ODD 0x01 // parity bit added after data bits
+#define SCI_IOCTL_PARITY_EVEN 0x02 // parity bit added after data bits
+#define SCI_IOCTL_PARITY_MARK 0x03 // parity bit is lo, -12 volts, logical 1
+#define SCI_IOCTL_PARITY_SPACE 0x04 // parity bit is hi, +12 volts, logical 0
+#define SCI_IOCTL_PARITY_FORCED_ON 0x03 // parity bit is forced hi or lo
+#define SCI_IOCTL_PARITY_FORCED_OFF 0x04 // parity bit is forced hi or lo
+
+#define SCI_IOCTL_BAUD_RATE 0x20 // set the baud rate, arg is baud
+
+#define SCI_IOCTL_DATA_BITS 0x30 // set the data bits, arg is # bits
+
+#define SCI_IOCTL_STOP_BITS_1 0x40 // 1 stop bit after char frame
+#define SCI_IOCTL_STOP_BITS_2 0x41 // 2 stop bit after char frame
+
+#define SCI_IOCTL_MODE_NORMAL 0x50 // normal operating mode
+#define SCI_IOCTL_MODE_LOOP 0x51 // internal loopback mode
+
+#define SCI_IOCTL_FLOW_NONE 0x60 // no flow control
+#define SCI_IOCTL_FLOW_RTS_CTS 0x61 // hardware flow control
+
+#define SCI_IOCTL_SEND_BREAK 0x70 // send an rs-232 break
+
+#define SCI_IOCTL_MODE_1200 0x80 // 1200,n,8,1 download mode
+#define SCI_IOCTL_MODE_9600 0x81 // 9600,n,8,1 download mode
+#define SCI_IOCTL_MODE_9_BIT 0x82 // 9600,forced,8,1 command mode
+
+
+
+/*******************************************************************************
+ SCI Registers
+*******************************************************************************/
+
+
+// SCI Control Register 0 (SCCR0) $FFFC08
+
+// 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1
+// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+// | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | +----- 0 baud rate divisor
+// | | | | | | | | | | | | | | +------- 1 baud rate divisor
+// | | | | | | | | | | | | | +--------- 2 baud rate divisor
+// | | | | | | | | | | | | +----------- 3 baud rate divisor
+// | | | | | | | | | | | |
+// | | | | | | | | | | | +--------------- 4 baud rate divisor
+// | | | | | | | | | | +----------------- 5 baud rate divisor
+// | | | | | | | | | +------------------- 6 baud rate divisor
+// | | | | | | | | +--------------------- 7 baud rate divisor
+// | | | | | | | |
+// | | | | | | | +------------------------- 8 baud rate divisor
+// | | | | | | +--------------------------- 9 baud rate divisor
+// | | | | | +----------------------------- 10 baud rate divisor
+// | | | | +------------------------------- 11 baud rate divisor
+// | | | |
+// | | | +----------------------------------- 12 baud rate divisor
+// | | +------------------------------------- 13 unused
+// | +--------------------------------------- 14 unused
+// +----------------------------------------- 15 unused
+
+// 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 1 0 0 reset value - (64k baud?)
+
+
+#define SCI_BAUD_57_6K 9
+#define SCI_BAUD_38_4K 14
+#define SCI_BAUD_19_2K 27
+#define SCI_BAUD_9600 55
+#define SCI_BAUD_4800 109
+#define SCI_BAUD_2400 218
+#define SCI_BAUD_1200 437
+
+
+
+// SCI Control Register 1 (SCCR1) $FFFC0A
+
+// 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1
+// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+// | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | +----- 0 send a break
+// | | | | | | | | | | | | | | +------- 1 rcvr wakeup mode
+// | | | | | | | | | | | | | +--------- 2 rcvr enable
+// | | | | | | | | | | | | +----------- 3 xmtr enable
+// | | | | | | | | | | | |
+// | | | | | | | | | | | +--------------- 4 idle line intr enable
+// | | | | | | | | | | +----------------- 5 rcvr intr enable
+// | | | | | | | | | +------------------- 6 xmit complete intr enable
+// | | | | | | | | +--------------------- 7 xmtr intr enable
+// | | | | | | | |
+// | | | | | | | +------------------------- 8 wakeup on address mark
+// | | | | | | +--------------------------- 9 mode 1=9 bits, 0=8 bits
+// | | | | | +----------------------------- 10 parity enable 1=on, 0=off
+// | | | | +------------------------------- 11 parity type 1=odd, 0=even
+// | | | |
+// | | | +----------------------------------- 12 idle line select
+// | | +------------------------------------- 13 wired-or mode
+// | +--------------------------------------- 14 loop mode
+// +----------------------------------------- 15 unused
+
+// 0 0 0 0 - 0 0 0 0 - 0 0 0 0 - 0 0 0 0 reset value
+
+#define SCI_SEND_BREAK 0x0001 // 0000-0000-0000-0001
+#define SCI_RCVR_WAKEUP 0x0002 // 0000-0000-0000-0010
+#define SCI_ENABLE_RCVR 0x0004 // 0000-0000-0000-0100
+#define SCI_ENABLE_XMTR 0x0008 // 0000-0000-0000-1000
+
+#define SCI_DISABLE_RCVR 0xFFFB // 1111-1111-1111-1011
+#define SCI_DISABLE_XMTR 0xFFF7 // 1111-1111-1111-0111
+
+#define SCI_ENABLE_INT_IDLE 0x0010 // 0000-0000-0001-0000
+#define SCI_ENABLE_INT_RX 0x0020 // 0000-0000-0010-0000
+#define SCI_ENABLE_INT_TX_DONE 0x0040 // 0000-0000-0100-0000
+#define SCI_ENABLE_INT_TX 0x0080 // 0000-0000-1000-0000
+
+#define SCI_DISABLE_INT_ALL 0xFF00 // 1111-1111-0000-0000 ???
+
+#define SCI_DISABLE_INT_RX 0xFFDF // 1111-1111-1101-1111
+#define SCI_CLEAR_RX_INT 0xFFBF // 1111-1111-1011-1111
+#define SCI_DISABLE_INT_TX 0xFF7F // 1111-1111-0111-1111
+#define SCI_CLEAR_TDRE 0xFEFF // 1111-1110-1111-1111
+
+#define SCI_RCVR_WAKE_ON_MARK 0x0100 // 0000-0001-0000-0000
+#define SCI_9_DATA_BITS 0x0200 // 0000-0010-0000-0000
+#define SCI_PARITY_ENABLE 0x0400 // 0000-0100-0000-0000
+#define SCI_PARITY_ODD 0x0800 // 0000-1000-0000-0000
+
+#define SCI_RCVR_WAKE_ON_IDLE 0xFEFF // 1111-1110-1111-1111
+#define SCI_8_DATA_BITS 0xFDFF // 1111-1101-1111-1111
+#define SCI_PARITY_DISABLE 0xFBFF // 1111-1011-1111-1111
+#define SCI_PARITY_EVEN 0xF7FF // 1111-0111-1111-1111
+
+#define SCI_PARITY_NONE 0xF3FF // 1111-0011-1111-1111
+
+#define SCI_IDLE_LINE_LONG 0x1000 // 0001-0000-0000-0000
+#define SCI_TXD_OPEN_DRAIN 0x2000 // 0010-0000-0000-0000
+#define SCI_LOOPBACK_MODE 0x4000 // 0100-0000-0000-0000
+#define SCI_SCCR1_UNUSED 0x8000 // 1000-0000-0000-0000
+
+
+// SCI Status Register (SCSR) $FFFC0C
+
+// 8 4 2 1 - 8 4 2 1 - 8 4 2 1 - 8 4 2 1
+// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+// | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | +----- 0 PF - parity error
+// | | | | | | | | | | | | | | +------- 1 FE - framing error
+// | | | | | | | | | | | | | +--------- 2 NF - noise flag
+// | | | | | | | | | | | | +----------- 3 OR - overrun flag
+// | | | | | | | | | | | |
+// | | | | | | | | | | | +--------------- 4 IDLE - idle line detected
+// | | | | | | | | | | +----------------- 5 RAF - rcvr active flag
+// | | | | | | | | | +------------------- 6 RDRF - rcv data reg full
+// | | | | | | | | +--------------------- 7 TC - xmt complete flag
+// | | | | | | | |
+// | | | | | | | +------------------------- 8 TDRE - xmt data reg empty
+// | | | | | | +--------------------------- 9 always zero
+// | | | | | +----------------------------- 10 always zero
+// | | | | +------------------------------- 11 always zero
+// | | | |
+// | | | +----------------------------------- 12 always zero
+// | | +------------------------------------- 13 always zero
+// | +--------------------------------------- 14 always zero
+// +----------------------------------------- 15 always zero
+
+// 0 0 0 0 - 0 0 0 1 - 1 0 0 0 - 0 0 0 0 reset value
+
+
+#define SCI_ERROR_PARITY 0x0001 // 0000-0000-0000-0001
+#define SCI_ERROR_FRAMING 0x0002 // 0000-0000-0000-0010
+#define SCI_ERROR_NOISE 0x0004 // 0000-0000-0000-0100
+#define SCI_ERROR_OVERRUN 0x0008 // 0000-0000-0000-1000
+
+#define SCI_IDLE_LINE 0x0010 // 0000-0000-0001-0000
+#define SCI_RCVR_ACTIVE 0x0020 // 0000-0000-0010-0000
+#define SCI_RCVR_READY 0x0040 // 0000-0000-0100-0000
+#define SCI_XMTR_IDLE 0x0080 // 0000-0000-1000-0000
+
+#define SCI_CLEAR_RX_INT 0xFFBF // 1111-1111-1011-1111
+
+#define SCI_XMTR_READY 0x0100 // 0000-0001-0000-0000
+
+#define SCI_CLEAR_TDRE 0xFEFF // 1111-1110-1111-1111
+
+#define SCI_XMTR_AVAILABLE 0x0180 // 0000-0001-1000-0000
+
+
+
+/*******************************************************************************
+ Function prototypes
+*******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// look at console_open to see how this is called
+
+const rtems_termios_callbacks * SciGetTermiosHandlers( signed32 polled );
+
+
+/* SCI interrupt */
+
+//rtems_isr SciIsr( rtems_vector_number vector );
+
+
+//signed32 SciOpenPolled ( signed32 major, signed32 minor, void *arg );
+//signed32 SciOpenInterrupt ( signed32 major, signed32 minor, void *arg );
+
+//signed32 SciClose ( signed32 major, signed32 minor, void *arg );
+
+//signed32 SciWritePolled ( signed32 minor, const char *buf, signed32 len );
+//signed32 SciWriteInterrupt( signed32 minor, const char *buf, signed32 len );
+
+//signed32 SciReadPolled ( signed32 minor );
+
+//signed32 SciSetAttributes ( signed32 minor, const struct termios *t );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // _sci_h_
+
+
diff --git a/c/src/lib/libbsp/m68k/mrm332/include/bsp.h b/c/src/lib/libbsp/m68k/mrm332/include/bsp.h
index c8c558dc3d..75e2ec4750 100644
--- a/c/src/lib/libbsp/m68k/mrm332/include/bsp.h
+++ b/c/src/lib/libbsp/m68k/mrm332/include/bsp.h
@@ -22,6 +22,7 @@ extern "C" {
#include <bspopts.h>
#include <rtems.h>
+#include <rtems/bspIo.h>
#include <clockdrv.h>
#include <console.h>
#include <iosupp.h>
@@ -35,6 +36,7 @@ extern "C" {
* - Interrupt stack space is not minimum if defined.
*/
+#define CONSOLE_SCI
/* #define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2 */
/* #define CONFIGURE_INTERRUPT_STACK_MEMORY (TBD * 1024) */
@@ -102,7 +104,7 @@ extern char _copy_data_from_rom[];
#define RAW_PUTS(str) \
{ register char *ptr = str; \
- while (*ptr) outbyte(*ptr++); \
+ while (*ptr) SCI_output_char(*ptr++); \
}
#define RAW_PUTI(n) { \
@@ -111,7 +113,7 @@ extern char _copy_data_from_rom[];
RAW_PUTS("0x"); \
for (i=28;i>=0;i -= 4) { \
j = (n>>i) & 0xf; \
- outbyte( (j>9 ? j-10+'a' : j+'0') ); \
+ SCI_output_char( (j>9 ? j-10+'a' : j+'0') ); \
} \
}
diff --git a/c/src/lib/libbsp/m68k/mrm332/include/mrm332.h b/c/src/lib/libbsp/m68k/mrm332/include/mrm332.h
index c0ef0a7d6c..c7cbbfa797 100644
--- a/c/src/lib/libbsp/m68k/mrm332/include/mrm332.h
+++ b/c/src/lib/libbsp/m68k/mrm332/include/mrm332.h
@@ -33,7 +33,7 @@
/* System Clock definitions */
#define XTAL 32768.0 /* crystal frequency in Hz */
-#if 0
+#if 1
/* Default MRM clock rate (8.388688 MHz) set by CPU32: */
#define MRM_W 0 /* system clock parameters */
#define MRM_X 0
@@ -47,7 +47,7 @@
#define MRM_Y 0x0f
#endif
-#if 1
+#if 0
/* 25.16582 MHz: */
#define MRM_W 1 /* system clock parameters */
#define MRM_X 1
@@ -60,6 +60,8 @@
/* macros/functions */
+#ifndef ASM
+
/*
* This prototype really should have the noreturn attribute but
* that causes a warning. Not sure how to fix that.
@@ -68,4 +70,6 @@
static void reboot(void);
__inline__ static void reboot() {asm("trap #15; .word 0x0063");}
+#endif /* ASM */
+
#endif /* _MRM_H_ */
diff --git a/c/src/lib/libbsp/m68k/mrm332/spurious/spinit.c b/c/src/lib/libbsp/m68k/mrm332/spurious/spinit.c
index c296e5888a..7af1654554 100644
--- a/c/src/lib/libbsp/m68k/mrm332/spurious/spinit.c
+++ b/c/src/lib/libbsp/m68k/mrm332/spurious/spinit.c
@@ -33,7 +33,7 @@ rtems_isr Spurious_Isr(
rtems_vector_number vector
)
{
- int sp = 0;
+ //int sp = 0;
const char * const VectDescrip[] = {
_Spurious_Error_[0], _Spurious_Error_[0], _Spurious_Error_[1],
_Spurious_Error_[2], _Spurious_Error_[3], _Spurious_Error_[4],
@@ -58,11 +58,11 @@ rtems_isr Spurious_Isr(
_Spurious_Error_[27], _Spurious_Error_[27], _Spurious_Error_[27],
_Spurious_Error_[27], _Spurious_Error_[28]};
- asm volatile ( "movea.l %%sp,%0 " : "=a" (sp) : "0" (sp) );
+ //asm volatile ( "movea.l %%sp,%0 " : "=a" (sp) : "0" (sp) );
_CPU_ISR_Set_level( 7 );
- _UART_flush();
-
+ //_UART_flush();
+#if 0
RAW_PUTS("\n\rRTEMS: Spurious interrupt: ");
RAW_PUTS((char *)VectDescrip[( (vector>64) ? 64 : vector )]);
RAW_PUTS("\n\rRTEMS: Vector: ");
@@ -70,7 +70,7 @@ rtems_isr Spurious_Isr(
RAW_PUTS(" sp: ");
RAW_PUTI(sp);
RAW_PUTS("\n\r");
-
+#endif
bsp_cleanup();
/* BDM SIGEMT */
diff --git a/c/src/lib/libbsp/m68k/mrm332/start/Makefile.am b/c/src/lib/libbsp/m68k/mrm332/start/Makefile.am
index e827e0d79e..86053b9e99 100644
--- a/c/src/lib/libbsp/m68k/mrm332/start/Makefile.am
+++ b/c/src/lib/libbsp/m68k/mrm332/start/Makefile.am
@@ -6,10 +6,10 @@ AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/start.o
-C_FILES = start.c
-C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
+S_FILES = start.S
+S_O_FILES = $(S_FILES:%.S=$(ARCH)/%.o)
-OBJS = $(C_O_FILES)
+OBJS = $(S_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
@@ -28,6 +28,6 @@ all-local: $(ARCH) $(OBJS) $(PGM) $(TMPINSTALL_FILES)
.PRECIOUS: $(PGM)
-EXTRA_DIST = start.c
+EXTRA_DIST = start.S
include $(top_srcdir)/../../../../../../automake/local.am
diff --git a/c/src/lib/libbsp/m68k/mrm332/start/start.S b/c/src/lib/libbsp/m68k/mrm332/start/start.S
new file mode 100644
index 0000000000..0aec261c6e
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mrm332/start/start.S
@@ -0,0 +1,151 @@
+/*
+ * $Id
+ */
+
+#include "mrm332.h"
+#include "asm.h"
+#include <sim.h>
+
+BEGIN_CODE
+
+ /* Put the header necessary for the modified CPU32bug to automatically
+ start up rtems: */
+#if 0
+.long 0xbeefbeef ;
+#endif
+.long 0 ;
+.long start ;
+
+.global start
+ start:
+
+ oriw #0x0700,sr
+ movel #end, d0
+ addl #_StackSize,d0
+ movel d0,sp
+ movel d0,a6
+
+
+ /* include in ram_init.S */
+ /*
+ * Initalize the SIM module.
+ * The stack pointer is not usable until the RAM chip select lines
+ * are configured. The following code must remain inline.
+ */
+
+ /* Module Configuration Register */
+ /* see section(s) 3.1.3-3.1.6 of the SIM Reference Manual */
+ lea SIMCR, a0
+ movew #FRZSW,d0
+ oriw #SAM(0,8,SHEN),d0
+ oriw #(MM*SIM_MM),d0
+ oriw #SAM(SIM_IARB,0,IARB),d0
+ movew d0, a0@
+
+ jsr start_c /* Jump to the C startup code */
+
+END_CODE
+
+#if 0
+
+ /* Synthesizer Control Register */
+ /* see section(s) 4.8 */
+ /* end include in ram_init.S */
+ *SYNCR = (unsigned short int)
+ ( SAM(MRM_W,15,VCO) | SAM(0x0,14,PRESCALE) | SAM(MRM_Y,8,COUNTER) );
+ while (! (*SYNCR & SLOCK)); /* protect from clock overshoot */
+ /* include in ram_init.S */
+ *SYNCR = (unsigned short int)
+ ( SAM(MRM_W,15,VCO) | SAM(MRM_X,14,PRESCALE) | SAM(MRM_Y,8,COUNTER) );
+
+ /* System Protection Control Register */
+ /* !!! can only write to once after reset !!! */
+ /* see section 3.8.4 of the SIM Reference Manual */
+ *SYPCR = (unsigned char)( HME | BME );
+
+ /* Periodic Interrupr Control Register */
+ /* see section 3.8.2 of the SIM Reference Manual */
+ *PICR = (unsigned short int)
+ ( SAM(0,8,PIRQL) | SAM(MRM_PIV,0,PIV) );
+ /* ^^^ zero disables interrupt, don't enable here or ram_init will
+ be wrong. It's enabled below. */
+
+ /* Periodic Interrupt Timer Register */
+ /* see section 3.8.3 of the SIM Reference Manual */
+ *PITR = (unsigned short int)( SAM(0x09,0,PITM) );
+ /* 1.098mS interrupt, assuming 32.768 KHz input clock */
+
+ /* Port C Data */
+ /* load values before enabled */
+ *PORTC = (unsigned char) 0x0;
+
+ /* Port E and F Data Register */
+ /* see section 9 of the SIM Reference Manual */
+ *PORTE0 = (unsigned char) 0;
+ *PORTF0 = (unsigned char) 0;
+
+ /* Port E and F Data Direction Register */
+ /* see section 9 of the SIM Reference Manual */
+ *DDRE = (unsigned char) 0xff;
+ *DDRF = (unsigned char) 0xfd;
+
+ /* Port E and F Pin Assignment Register */
+ /* see section 9 of the SIM Reference Manual */
+ *PEPAR = (unsigned char) 0;
+ *PFPAR = (unsigned char) 0;
+
+ /* end of SIM initalization code */
+ /* end include in ram_init.S */
+
+ /*
+ * Initialize RAM by copying the .data section out of ROM (if
+ * needed) and "zero-ing" the .bss section.
+ */
+ {
+ register char *src = _etext;
+ register char *dst = _copy_start;
+
+ if (_copy_data_from_rom)
+ /* ROM has data at end of text; copy it. */
+ while (dst < _edata)
+ *dst++ = *src++;
+
+ /* Zero bss */
+ for (dst = _clear_start; dst< end; dst++)
+ {
+ *dst = 0;
+ }
+ }
+
+ /*
+ * Initialize vector table.
+ */
+ {
+ m68k_isr_entry *monitors_vector_table;
+
+ m68k_get_vbr(monitors_vector_table);
+
+ M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */
+ M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */
+ M68Kvec[ 31 ] = monitors_vector_table[ 31 ]; /* level 7 interrupt */
+ M68Kvec[ 47 ] = monitors_vector_table[ 47 ]; /* system call vector */
+ M68Kvec[ 66 ] = monitors_vector_table[ 66 ]; /* user defined */
+
+ m68k_set_vbr(&M68Kvec);
+ }
+
+ /*
+ * Initalize the board.
+ */
+ Spurious_Initialize();
+ console_init();
+
+ /*
+ * Execute main with arguments argc and agrv.
+ */
+ boot_card(1,__argv);
+ reboot();
+
+}
+
+#endif
diff --git a/c/src/lib/libbsp/m68k/mrm332/start/start.c b/c/src/lib/libbsp/m68k/mrm332/start/start.c
deleted file mode 100644
index 7d95437180..0000000000
--- a/c/src/lib/libbsp/m68k/mrm332/start/start.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * $Id
- */
-
-#include <mrm332.h>
-#include <sim.h>
-#define __START_C__
-#include "bsp.h"
-
-m68k_isr_entry M68Kvec[256];
-m68k_isr_entry vectors[256];
-char * const __argv[]= {"main", ""};
-
-void boot_card(int argc, char * const argv[]);
-
-/*
- * This prototype really should have the noreturn attribute but
- * that causes a warning. Not sure how to fix that.
- */
-/* void dumby_start () __attribute__ ((noreturn)); */
-void dumby_start ();
-
-void dumby_start() {
-
- /* Put the header necessary for the modified CPU32bug to automatically
- start up rtems: */
- asm volatile ( ".long 0xbeefbeef ;
- .long 0 ;
- .long start");
-
- /* We need to by-pass the link instruction since the RAM chip-
- select pins are not yet configured. */
- asm volatile ( ".global start ;
- start:");
-
- /* disable interrupts, copy CPU32bug vectors, load stack pointer */
- asm volatile ( "oriw #0x0700, %sr;
- movel #end, %d0;
- addl #_StackSize,%d0;
- movel %d0,%sp;
- movel %d0,%a6"
- );
-
- /* include in ram_init.S */
- /*
- * Initalize the SIM module.
- * The stack pointer is not usable until the RAM chip select lines
- * are configured. The following code must remain inline.
- */
-
- /* Module Configuration Register */
- /* see section(s) 3.1.3-3.1.6 of the SIM Reference Manual */
- *SIMCR = (unsigned short int)
- (FRZSW | SAM(0,8,SHEN) | (MM*SIM_MM) | SAM(SIM_IARB,0,IARB));
-
- /* Synthesizer Control Register */
- /* see section(s) 4.8 */
- /* end include in ram_init.S */
- *SYNCR = (unsigned short int)
- ( SAM(MRM_W,15,VCO) | SAM(0x0,14,PRESCALE) | SAM(MRM_Y,8,COUNTER) );
- while (! (*SYNCR & SLOCK)); /* protect from clock overshoot */
- /* include in ram_init.S */
- *SYNCR = (unsigned short int)
- ( SAM(MRM_W,15,VCO) | SAM(MRM_X,14,PRESCALE) | SAM(MRM_Y,8,COUNTER) );
-
- /* System Protection Control Register */
- /* !!! can only write to once after reset !!! */
- /* see section 3.8.4 of the SIM Reference Manual */
- *SYPCR = (unsigned char)( HME | BME );
-
- /* Periodic Interrupr Control Register */
- /* see section 3.8.2 of the SIM Reference Manual */
- *PICR = (unsigned short int)
- ( SAM(0,8,PIRQL) | SAM(MRM_PIV,0,PIV) );
- /* ^^^ zero disables interrupt, don't enable here or ram_init will
- be wrong. It's enabled below. */
-
- /* Periodic Interrupt Timer Register */
- /* see section 3.8.3 of the SIM Reference Manual */
- *PITR = (unsigned short int)( SAM(0x09,0,PITM) );
- /* 1.098mS interrupt, assuming 32.768 KHz input clock */
-
- /* Port C Data */
- /* load values before enabled */
- *PORTC = (unsigned char) 0x0;
-
-#if 0
- /* Don't touch these on MRM, they are set up by CPU32bug at boot time. */
-
- /* Chip-Select Base Address Register */
- /* see section 7 of the SIM Reference Manual */
- *CSBARBT = (unsigned short int)
- (((0x000000 >> 8)&0xfff8) | BS_512K ); /* 512k bytes located at 0x0000 */
- *CSBAR0 = (unsigned short int)
- (((0x000000 >> 8)&0xfff8) | BS_1M ); /* 1M bytes located at 0x0000 */
- *CSBAR1 = (unsigned short int)
- (((0x080000 >> 8)&0xfff8) | BS_256K ); /* 256k bytes located at 0x80000 */
- *CSBAR2 = (unsigned short int)
- (((0x080000 >> 8)&0xfff8) | BS_256K ); /* 256k bytes located at 0x80000 */
- *CSBAR3 = (unsigned short int)
- (((0x0C0000 >> 8)&0xfff8) | BS_256K ); /* 256k bytes located at 0xC0000 */
- *CSBAR4 = (unsigned short int)
- (((0x0C0000 >> 8)&0xfff8) | BS_256K ); /* 256k bytes located at 0xC0000 */
- *CSBAR5 = (unsigned short int)
- (0xfff8 | BS_64K); /* AVEC interrupts */
-
-#if 0
-#ifdef EFI332_v040b
- *CSBAR6 = (unsigned short int)
- (((0x000000 >> 8)&0xfff8) | BS_512K ); /* 512k bytes located at 0x0000 */
- *CSBAR8 = (unsigned short int) /* PCMCIA IOCS */
- (((0x0c0000 >> 8)&0xfff8) | BS_64K ); /* 64k bytes located at 0xc0000 */
- *CSBAR9 = (unsigned short int) /* PCMCIA MEMCS */
- (((0x0D0000 >> 8)&0xfff8) | BS_64K ); /* 64k bytes located at 0xd0000 */
-#else /* EFI332_v040b */
- *CSBAR10 = (unsigned short int)
- (((0x000000 >> 8)&0xfff8) | BS_512K ); /* 512k bytes located at 0x0000 */
-#endif /* EFI332_v040b */
-#endif
-
- /* Chip-Select Options Registers */
- /* see section 7 of the SIM Reference Manual */
-#ifdef FLASHWRITE
- *CSORBT = (unsigned short int)
- ( BothBytes | ReadWrite | SyncAS | WaitStates_0 | UserSupSpace );
-#else /* FLASHWRITE */
- *CSORBT = (unsigned short int)
- ( BothBytes | ReadOnly | SyncAS | WaitStates_0 | UserSupSpace );
-#endif /* FLASHWRITE */
- *CSOR0 = (unsigned short int)
- ( BothBytes | ReadOnly | SyncAS | External | UserSupSpace );
- *CSOR1 = (unsigned short int)
- ( LowerByte | ReadWrite | SyncAS | FastTerm | UserSupSpace );
- *CSOR2 = (unsigned short int)
- ( UpperByte | ReadWrite | SyncAS | FastTerm | UserSupSpace );
- *CSOR3 = (unsigned short int)
- ( LowerByte | ReadWrite | SyncAS | FastTerm | UserSupSpace );
- *CSOR4 = (unsigned short int)
- ( UpperByte | ReadWrite | SyncAS | FastTerm | UserSupSpace );
- *CSOR5 = (unsigned short int)
- ( BothBytes | ReadWrite | SyncAS | CPUSpace | IPLevel_any | AVEC );
-
-#if 0
-#ifdef EFI332_v040b
- *CSOR6 = (unsigned short int)
- ( BothBytes | ReadOnly | SyncAS | External | UserSupSpace );
- *CSOR8 = (unsigned short int)
- ( BothBytes | ReadWrite | SyncAS | External | UserSupSpace );
- *CSOR9 = (unsigned short int)
- ( BothBytes | ReadWrite | SyncAS | External | UserSupSpace );
-#else /* EFI332_v040b */
- *CSOR10 = (unsigned short int)
- ( BothBytes | ReadOnly | SyncAS | External | UserSupSpace );
-#endif /* EFI332_v040b */
-#endif
-
- /* Chip Select Pin Assignment Register 0 */
- /* see section 7 of the SIM Reference Manual */
- *CSPAR0 = (unsigned short int)(
- SAM(DisOut,CS_5,0x3000) | /* AVEC (internally) */
- SAM(CS16bit,CS_4,0x0c00) | /* RAM UDS, bank2 */
- SAM(CS16bit,CS_3,0x0300) | /* RAM LDS, bank2 */
- SAM(CS16bit,CS_2,0x00c0)| /* RAM UDS, bank1 */
- SAM(CS16bit,CS_1,0x0030)| /* RAM LDS, bank1 */
- SAM(CS16bit,CS_0,0x000c)| /* W/!R */
- SAM(CS16bit,CSBOOT,0x0003) /* ROM CS */
- );
-
- /* Chip Select Pin Assignment Register 1 */
- /* see section 7 of the SIM Reference Manual */
-#ifdef EFI332_v040b
- *CSPAR1 = (unsigned short int)(
- SAM(DisOut,CS_10,0x300)| /* ECLK */
- SAM(CS16bit,CS_9,0x0c0) | /* PCMCIA MEMCS */
- SAM(CS16bit,CS_8,0x030) | /* PCMCIA IOCS */
- SAM(DisOut,CS_7,0x00c) | /* PC4 */
- SAM(CS16bit,CS_6,0x003) /* ROM !OE */
- );
-#else /* EFI332_v040b */
- *CSPAR1 = (unsigned short int)(
- SAM(CS16bit,CS_10,0x300)| /* ROM !OE */
- SAM(DisOut,CS_9,0x0c0) | /* PC6 */
- SAM(DisOut,CS_8,0x030) | /* PC5 */
- SAM(DisOut,CS_7,0x00c) | /* PC4 */
- SAM(DisOut,CS_6,0x003) /* PC3 */
- );
-#endif /* EFI332_v040b */
-
-#endif /* Don't touch on MRM */
-
- /* Port E and F Data Register */
- /* see section 9 of the SIM Reference Manual */
- *PORTE0 = (unsigned char) 0;
- *PORTF0 = (unsigned char) 0;
-
- /* Port E and F Data Direction Register */
- /* see section 9 of the SIM Reference Manual */
- *DDRE = (unsigned char) 0xff;
- *DDRF = (unsigned char) 0xfd;
-
- /* Port E and F Pin Assignment Register */
- /* see section 9 of the SIM Reference Manual */
- *PEPAR = (unsigned char) 0;
- *PFPAR = (unsigned char) 0;
-
- /* end of SIM initalization code */
- /* end include in ram_init.S */
-
- /*
- * Initialize RAM by copying the .data section out of ROM (if
- * needed) and "zero-ing" the .bss section.
- */
- {
- register char *src = _etext;
- register char *dst = _copy_start;
-
- if (_copy_data_from_rom)
- /* ROM has data at end of text; copy it. */
- while (dst < _edata)
- *dst++ = *src++;
-
- /* Zero bss */
- for (dst = _clear_start; dst< end; dst++)
- {
- *dst = 0;
- }
- }
-
- /*
- * Initialize vector table.
- */
- {
- m68k_isr_entry *monitors_vector_table;
-
- m68k_get_vbr(monitors_vector_table);
-
- M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */
- M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */
- M68Kvec[ 31 ] = monitors_vector_table[ 31 ]; /* level 7 interrupt */
- M68Kvec[ 47 ] = monitors_vector_table[ 47 ]; /* system call vector */
- M68Kvec[ 66 ] = monitors_vector_table[ 66 ]; /* user defined */
-
- m68k_set_vbr(&M68Kvec);
- }
-
- /*
- * Initalize the board.
- */
- Spurious_Initialize();
- console_init();
-
- /*
- * Execute main with arguments argc and agrv.
- */
- boot_card(1,__argv);
- reboot();
-
-}
-
diff --git a/c/src/lib/libbsp/m68k/mrm332/startup/Makefile.am b/c/src/lib/libbsp/m68k/mrm332/startup/Makefile.am
index d8fa5fd721..61e3b8bffa 100644
--- a/c/src/lib/libbsp/m68k/mrm332/startup/Makefile.am
+++ b/c/src/lib/libbsp/m68k/mrm332/startup/Makefile.am
@@ -8,7 +8,7 @@ VPATH = @srcdir@:@srcdir@/../../shared:@srcdir@/../../../shared
PGM = $(ARCH)/startup.rel
-C_FILES = bsplibc.c bsppost.c bspstart.c bspclean.c bootcard.c \
+C_FILES = start_c.c bsplibc.c bsppost.c bspstart.c bspclean.c bootcard.c \
m68kpretaskinghook.c main.c sbrk.c setvec.c gnatinstallhandler.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
diff --git a/c/src/lib/libbsp/m68k/mrm332/startup/bspclean.c b/c/src/lib/libbsp/m68k/mrm332/startup/bspclean.c
index c8d5656d3a..2146a2fa1d 100644
--- a/c/src/lib/libbsp/m68k/mrm332/startup/bspclean.c
+++ b/c/src/lib/libbsp/m68k/mrm332/startup/bspclean.c
@@ -23,5 +23,5 @@ void bsp_cleanup(void)
{
/* interrupt driven stdio must be flushed */
_CPU_ISR_Set_level( 7 );
- _UART_flush();
+ //_UART_flush();
}
diff --git a/c/src/lib/libbsp/m68k/mrm332/startup/linkcmds b/c/src/lib/libbsp/m68k/mrm332/startup/linkcmds
index 830f3a6572..2ef71edd72 100644
--- a/c/src/lib/libbsp/m68k/mrm332/startup/linkcmds
+++ b/c/src/lib/libbsp/m68k/mrm332/startup/linkcmds
@@ -34,10 +34,10 @@ __DYNAMIC = 0;
* Declare some sizes.
*/
_RamBase = DEFINED(_RamBase) ? _RamBase : 0x03000;
-_RamSize = DEFINED(_RamSize) ? _RamSize : 0x80000;
+_RamSize = DEFINED(_RamSize) ? _RamSize : 0x7d000;
_RamEnd = _RamBase + _RamSize;
_HeapSize = DEFINED(_HeapSize) ? _HeapSize : 0x10000;
-_StackSize = DEFINED(_StackSize) ? _StackSize : 0x1000;
+_StackSize = DEFINED(_StackSize) ? _StackSize : 0x2000;
MEMORY
{
diff --git a/c/src/lib/libbsp/m68k/mrm332/startup/start_c.c b/c/src/lib/libbsp/m68k/mrm332/startup/start_c.c
new file mode 100644
index 0000000000..1086130ae8
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/mrm332/startup/start_c.c
@@ -0,0 +1,124 @@
+/*
+ * $Id
+ */
+
+#include <mrm332.h>
+#include <sim.h>
+#define __START_C__
+#include "bsp.h"
+
+m68k_isr_entry M68Kvec[256];
+m68k_isr_entry vectors[256];
+char * const __argv[]= {"main", ""};
+
+void boot_card(int argc, char * const argv[]);
+
+/*
+ * This prototype really should have the noreturn attribute but
+ * that causes a warning. Not sure how to fix that.
+ */
+/* void dumby_start () __attribute__ ((noreturn)); */
+void start_c ();
+
+void start_c() {
+
+ /* Synthesizer Control Register */
+ /* see section(s) 4.8 */
+ /* end include in ram_init.S */
+ *SYNCR = (unsigned short int)
+ ( SAM(MRM_W,15,VCO) | SAM(0x0,14,PRESCALE) | SAM(MRM_Y,8,COUNTER) );
+ while (! (*SYNCR & SLOCK)); /* protect from clock overshoot */
+ /* include in ram_init.S */
+ *SYNCR = (unsigned short int)
+ ( SAM(MRM_W,15,VCO) | SAM(MRM_X,14,PRESCALE) | SAM(MRM_Y,8,COUNTER) );
+
+ /* System Protection Control Register */
+ /* !!! can only write to once after reset !!! */
+ /* see section 3.8.4 of the SIM Reference Manual */
+ *SYPCR = (unsigned char)( HME | BME );
+
+ /* Periodic Interrupr Control Register */
+ /* see section 3.8.2 of the SIM Reference Manual */
+ *PICR = (unsigned short int)
+ ( SAM(0,8,PIRQL) | SAM(MRM_PIV,0,PIV) );
+ /* ^^^ zero disables interrupt, don't enable here or ram_init will
+ be wrong. It's enabled below. */
+
+ /* Periodic Interrupt Timer Register */
+ /* see section 3.8.3 of the SIM Reference Manual */
+ *PITR = (unsigned short int)( SAM(0x09,0,PITM) );
+ /* 1.098mS interrupt, assuming 32.768 KHz input clock */
+
+ /* Port C Data */
+ /* load values before enabled */
+ *PORTC = (unsigned char) 0x0;
+
+ /* Port E and F Data Register */
+ /* see section 9 of the SIM Reference Manual */
+ *PORTE0 = (unsigned char) 0;
+ *PORTF0 = (unsigned char) 0;
+
+ /* Port E and F Data Direction Register */
+ /* see section 9 of the SIM Reference Manual */
+ *DDRE = (unsigned char) 0xff;
+ *DDRF = (unsigned char) 0xfd;
+
+ /* Port E and F Pin Assignment Register */
+ /* see section 9 of the SIM Reference Manual */
+ *PEPAR = (unsigned char) 0;
+ *PFPAR = (unsigned char) 0;
+
+ /* end of SIM initalization code */
+ /* end include in ram_init.S */
+
+ /*
+ * Initialize RAM by copying the .data section out of ROM (if
+ * needed) and "zero-ing" the .bss section.
+ */
+ {
+ register char *src = _etext;
+ register char *dst = _copy_start;
+
+ if (_copy_data_from_rom)
+ /* ROM has data at end of text; copy it. */
+ while (dst < _edata)
+ *dst++ = *src++;
+
+ /* Zero bss */
+ for (dst = _clear_start; dst< end; dst++)
+ {
+ *dst = 0;
+ }
+ }
+
+ /*
+ * Initialize vector table.
+ */
+ {
+ m68k_isr_entry *monitors_vector_table;
+
+ m68k_get_vbr(monitors_vector_table);
+
+ M68Kvec[ 4 ] = monitors_vector_table[ 4 ]; /* breakpoints vector */
+ M68Kvec[ 9 ] = monitors_vector_table[ 9 ]; /* trace vector */
+ M68Kvec[ 31 ] = monitors_vector_table[ 31 ]; /* level 7 interrupt */
+ M68Kvec[ 47 ] = monitors_vector_table[ 47 ]; /* system call vector */
+ M68Kvec[ 66 ] = monitors_vector_table[ 66 ]; /* user defined */
+
+ m68k_set_vbr(&M68Kvec);
+ }
+
+ /*
+ * Initalize the board.
+ */
+ Spurious_Initialize();
+ //console_init();
+
+ /*
+ * Execute main with arguments argc and agrv.
+ */
+ boot_card(1,__argv);
+ reboot();
+
+}
+