summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2013-04-04 19:20:46 +0400
committerkx <kx@radix.pro>2013-04-04 19:20:46 +0400
commit974aed1fbb8d08561058ddda88a534df8eba8cc1 (patch)
tree55b3699d253ace7f66f4bd386178e8c6403a814b
downloadIRAM-loader-master.tar.xz
Initial commitHEAD0.0.1master
-rw-r--r--.gitignore0
-rw-r--r--Makefile18
-rw-r--r--doc/building.txt11
-rw-r--r--drivers/tty/tty-linux.c453
-rw-r--r--drivers/tty/tty-win32api.c373
-rw-r--r--drivers/tty/tty.c159
-rw-r--r--drivers/tty/tty.h54
-rw-r--r--include/byteorder/__tx_big_endian.h44
-rw-r--r--include/byteorder/__tx_bswap.h74
-rw-r--r--include/byteorder/__tx_little_endian.h45
-rw-r--r--math/crc32/crc32.c81
-rw-r--r--math/crc32/crc32.h39
-rw-r--r--src/Makefile62
-rw-r--r--src/defs.h58
-rw-r--r--src/main.c596
15 files changed, 2067 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.gitignore
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..88e0fc0
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,18 @@
+
+SUBDIRS := src
+
+all-recursive clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ local_target="$$target"; \
+ (cd $$subdir && $(MAKE) $$fnord $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; test -z "$$fail"
+
+all: all-recursive
+
+clean: clean-recursive
+
+.PHONY: all-recursive clean-recursive all clean
diff --git a/doc/building.txt b/doc/building.txt
new file mode 100644
index 0000000..401ddbd
--- /dev/null
+++ b/doc/building.txt
@@ -0,0 +1,11 @@
+
+Non secure:
+==========
+SECURE=0 INFINITY=1 DEBUG=0 make all
+SECURE=0 INFINITY=1 DEBUG=0 make clean
+
+Secure:
+======
+SECURE=1 INFINITY=1 DEBUG=0 make all
+SECURE=1 INFINITY=1 DEBUG=0 make clean
+
diff --git a/drivers/tty/tty-linux.c b/drivers/tty/tty-linux.c
new file mode 100644
index 0000000..125d8a0
--- /dev/null
+++ b/drivers/tty/tty-linux.c
@@ -0,0 +1,453 @@
+
+/***************************************************************
+ Linux, Cygwin Contents:
+ ***************************************************************/
+#include <pthread.h>
+
+unsigned char data_bits_9;
+
+struct termios serial_port;
+unsigned char *dev_tty = "/dev/ttyS0";
+struct sigaction saio; /* definition of signal action */
+static volatile
+sig_atomic_t caught_sigio = 0; /* FALSE while no signal reseived */
+static volatile
+sig_atomic_t stop = 0;
+pthread_t thread_rx;
+
+int fd;
+
+static void tty_handler( status )
+ int status;
+{
+ caught_sigio = 1;
+}
+
+
+static void *tty_rx_process( arg )
+ void *arg;
+{
+ unsigned char data[64] = { 0 };
+ int ret, rc = -1;
+
+#ifdef DEBUG_TTY_RXD
+ unsigned char flag = 0;
+
+ fprintf( stdout, "Reading tty process is started...\n" );
+#endif
+
+ while( !stop )
+ {
+ usleep( 1000 );
+ if( caught_sigio )
+ {
+ int i = 0;
+
+ rc = read( fd, data, 64 );
+
+ while( rc > 0 )
+ {
+ emit_ring_rx_char( data[i] );
+
+#ifdef DEBUG_TTY_RXD
+ if( flag == 0 )
+ {
+ fprintf( stdout, "TTY: rx [%02X", data[i] );
+ fflush( stdout );
+ }
+ else
+ {
+ fprintf( stdout, " %02X", data[i] );
+ fflush( stdout );
+ }
+ flag = 1;
+#endif
+ ++i;
+ --rc;
+ }
+
+#ifdef DEBUG_TTY_RXD
+ if( flag )
+ {
+ fprintf( stdout, "]\n" );
+ fflush( stdout );
+ }
+ else
+ {
+ if( errno != EAGAIN )
+ {
+ fprintf( stderr, "TTY: rx ERROR=%d (%s).\n", errno, strerror(errno) );
+ fflush( stderr );
+ }
+ }
+#endif
+ caught_sigio = 0;
+ }
+ }
+ return( NULL );
+}
+
+static int start_rx_process()
+{
+ int retcode;
+ void *retval;
+
+ retcode = pthread_create( &thread_rx, NULL, tty_rx_process, NULL );
+#ifdef DEBUG_TTY_RXD
+ if( retcode != 0 )
+ fprintf( stderr, "Cannot start TTY reading process: ERROR: %d.\n", retcode );
+#endif
+
+ return( retcode );
+}
+
+static int stop_rx_process()
+{
+ int retcode;
+ void *retval;
+
+ stop = 1;
+
+ retcode = pthread_join( thread_rx, &retval );
+#ifdef DEBUG_TTY_RXD
+ if( retcode != 0 )
+ fprintf( stderr, "joining a TTY reading process failed: ERROR: %d\n", retcode );
+#endif
+
+ return( 0 );
+}
+
+
+void tty_uninit()
+{
+ (void)stop_rx_process();
+
+ close( fd );
+ fd = 0;
+}
+
+int tty_init( baudrate, parity, data_bits, stop_bits )
+ unsigned long baudrate;
+ enum parity parity;
+ unsigned char data_bits;
+ enum stop_bits stop_bits;
+{
+ speed_t speed;
+ int rc;
+
+ do_ring_rx( 2, NULL, 0 );
+
+ if( fd )
+ {
+ tty_uninit();
+ }
+
+#if defined( __CYGWIN__ )
+ if( (fd = open( dev_tty, O_RDWR | O_BINARY | O_NONBLOCK | O_SYNC | O_NDELAY | O_NOCTTY )) <= 0 )
+#else
+ if( (fd = open( dev_tty, O_RDWR | O_NONBLOCK | O_SYNC | O_NDELAY | O_NOCTTY )) <= 0 )
+#endif
+ {
+#ifdef DEBUG_TTY_OPEN
+ fprintf( stderr, "TTY : Open port %s: ERROR=%d (%s).\n", dev_tty, errno, strerror(errno) );
+ fflush( stderr );
+#endif
+ return( -1 );
+ }
+
+#ifdef DEBUG_TTY_OPEN
+ fprintf( stdout, "TTY: Open port %s: OK\n", dev_tty );
+ fflush( stdout );
+#endif
+
+
+ /* install the signal handler before making the device asynchronous */
+ saio.sa_handler = tty_handler;
+ sigemptyset( &saio.sa_mask );
+ saio.sa_flags = 0;
+#if !defined( __CYGWIN__ )
+ saio.sa_restorer = NULL;
+#endif
+ sigaction( SIGIO, &saio, NULL );
+
+
+ /* allow the process to receive SIGIO */
+ fcntl( fd, F_SETOWN, getpid() );
+ /*
+ Make the file descriptor asynchronous (the manual page says only
+ O_APPEND and O_NONBLOCK, will work with F_SETFL...)
+ */
+#if !defined( __CYGWIN__ )
+ fcntl( fd, F_SETFL, FASYNC );
+#endif
+
+ data_bits_9 = (data_bits == 8) ? 1 : 0;
+
+ tcflush( fd, TCIOFLUSH );
+ tcgetattr( fd, &serial_port );
+
+ serial_port.c_iflag = 0; /* input modes */
+ serial_port.c_oflag = 0; /* output modes */
+ serial_port.c_cflag = CREAD | CLOCAL; /* control modes */
+ serial_port.c_lflag = 0; /* local modes */
+
+ /* DTR UP for Kreatel adaptor */
+ {
+ int status;
+ ioctl( fd, TIOCMGET, &status );
+ status |= TIOCM_DTR;
+ ioctl( fd, TIOCMSET, &status );
+ }
+
+#if 0
+ /* Dropping DTR with the TIOCMSET ioctl */
+ {
+ int status;
+ ioctl( fd, TIOCMGET, &status );
+ status &= ~TIOCM_DTR;
+ ioctl( fd, TIOCMSET, &status );
+ }
+#endif
+
+ if( stop_bits == _TWO )
+ serial_port.c_cflag |= CSTOPB;
+ else
+ serial_port.c_cflag &= ~CSTOPB;
+
+ switch( parity )
+ {
+ case _N:
+ break;
+ case _E:
+ serial_port.c_iflag |= INPCK;
+ serial_port.c_cflag |= PARENB;
+ break;
+ case _O:
+ serial_port.c_iflag |= INPCK;
+ serial_port.c_cflag |= PARENB;
+ serial_port.c_cflag |= PARODD;
+ break;
+ }
+
+ switch( data_bits )
+ {
+ case 7:
+ serial_port.c_cflag |= CS7;
+ break;
+ case 8:
+ serial_port.c_cflag |= CS8;
+ break;
+ case 9:
+ serial_port.c_cflag |= CS8;
+ serial_port.c_cflag |= PARENB;
+ serial_port.c_cflag &= ~(CSTOPB);
+ break;
+ }
+
+ switch( baudrate )
+ {
+ case 0: speed = B0; break;
+ case 50: speed = B50; break;
+ case 75: speed = B75; break;
+ case 110: speed = B110; break;
+ case 134: speed = B134; break;
+ case 150: speed = B150; break;
+ case 200: speed = B200; break;
+ case 300: speed = B300; break;
+ case 600: speed = B600; break;
+ case 1200: speed = B1200; break;
+ case 1800: speed = B1800; break;
+ case 2400: speed = B2400; break;
+ case 4800: speed = B4800; break;
+ case 9600: speed = B9600; break;
+ case 19200: speed = B19200; break;
+ case 38400: speed = B38400; break;
+ case 57600: speed = B57600; break;
+ case 115200: speed = B115200; break;
+ case 230400: speed = B230400; break;
+
+#if !defined( __CYGWIN__ )
+ case 460800: speed = B460800; break;
+ case 500000: speed = B500000; break;
+ case 576000: speed = B576000; break;
+ case 921600: speed = B921600; break;
+ case 1000000: speed = B1000000; break;
+ case 1152000: speed = B1152000; break;
+ case 1500000: speed = B1500000; break;
+ case 2000000: speed = B2000000; break;
+ case 2500000: speed = B2500000; break;
+ case 3000000: speed = B3000000; break;
+ case 3500000: speed = B3500000; break;
+ case 4000000: speed = B4000000; break;
+#endif
+ default: speed = B115200; break;
+ }
+
+ serial_port.c_cflag |= speed;
+ cfsetospeed( &serial_port, speed );
+ cfsetispeed( &serial_port, speed );
+
+ serial_port.c_cc[VMIN] = 0;
+ serial_port.c_cc[VTIME] = 50; /* tenths of seconds */
+
+ tcflush( fd, TCIFLUSH );
+ if( (rc = tcsetattr( fd, TCSANOW, &serial_port )) == -1 )
+ {
+ close( fd );
+ fd = 0;
+ return( -1 );
+ }
+
+ rc = start_rx_process();
+ if( rc != 0 )
+ {
+ close( fd );
+ fd = 0;
+ return( -1 );
+ }
+
+ return( fd );
+}
+
+int tty_read( buf, len )
+ unsigned char *buf;
+ int len;
+{
+ return( do_ring_rx( 0, buf, len ) );
+}
+
+void tty_ring_clear()
+{
+ (void)do_ring_rx( 2, NULL, 0 );
+}
+
+/* bool */
+int tty_write( buf, len )
+ unsigned char *buf;
+ int len;
+{
+#ifdef DEBUG_TTY_TXD
+ int i;
+
+ for( i = 0; i < len; ++i )
+ {
+ if( i == 0 )
+ {
+ fprintf( stdout, "TTY: tx [%02X", buf[i] );
+ fflush( stdout );
+ }
+ else
+ fprintf( stdout, " %02X", buf[i] );
+ fflush( stdout );
+ }
+#endif
+
+ if( fd != 0 )
+ {
+ int part = 64, full = len;
+
+ /********************************************
+ Delay transmiting by byte to byte writing.
+ ********************************************/
+ while( full > part )
+ {
+ if( write( fd, buf, part ) != part ) goto wr_error;
+ buf += part;
+ full -= part;
+ /* wait until all data will be trasmited */
+ tcdrain( fd );
+ usleep( 1 );
+ }
+
+ if( write( fd, buf, full ) != full ) goto wr_error;
+ /* wait until all data will be trasmited */
+ tcdrain( fd );
+
+#ifdef DEBUG_TTY_TXD
+ fprintf( stdout, "] end of transmiting : OK.\n" );
+ fflush( stdout );
+#endif
+ return( len ); /* TRUE */
+ }
+
+wr_error:
+#ifdef DEBUG_TTY_TXD
+ fprintf( stdout, "] end of transmiting : ERROR.\n" );
+ fflush( stdout );
+#endif
+
+ return( 0 ); /* FALSE */
+}
+
+/* bool */
+int tty_putc( c )
+ unsigned char c;
+{
+ int k;
+ unsigned char tmp = 0, nine = 0, i = 0;
+
+ /* only if use 9 bit mode */
+ if( data_bits_9 )
+ {
+ /* wait until all data will be trasmited */
+ tcdrain( fd );
+ tmp = c;
+
+ /* make some pause to do more space between bytes */
+ for( k = 0; k < 10000; ++k )
+ {
+ if( i ) i ^= 1;
+ }
+
+ /* calculate own parity to control 9 bit */
+ for( i = 0; i < 8; i++ )
+ {
+ nine ^= (tmp & 0x01);
+ tmp = tmp >> 1;
+ }
+
+ /* set 9 bit to "0" */
+ if( !nine )
+ serial_port.c_cflag &= ~(PARODD);
+ else
+ serial_port.c_cflag |= PARODD;
+
+ /* apply changes to port settings */
+ if( tcsetattr( fd, TCSADRAIN, &serial_port ) == -1 )
+ return( 0 ); /* FALSE */
+ }
+
+ if( fd != 0 && write( fd, &c, 1 ) == 1 )
+ {
+#ifdef DEBUG_TTY_TXD
+ fprintf( stdout, "TTY: tx [%02X] OK.\n", c );
+ fflush( stdout );
+#endif
+ return( 1 ); /* TRUE */
+ }
+
+#ifdef DEBUG_TTY_TXD
+ fprintf( stderr, "TTY: tx [%02X]: ERROR=%d (%s).\n", c, errno, strerror(errno) );
+ fflush( stderr );
+#endif
+
+ return( 0 ); /* FALSE */
+}
+
+/* bool */
+int tty_getc( c )
+ unsigned char *c;
+{
+ int rc;
+
+ rc = do_ring_rx( 0, c, 1 );
+ if( rc > 0 ) return( 1 ); /* TRUE */
+
+ return( 0 );
+}
+
+
+void tty_int()
+{
+ /* empty */
+}
diff --git a/drivers/tty/tty-win32api.c b/drivers/tty/tty-win32api.c
new file mode 100644
index 0000000..7d6727e
--- /dev/null
+++ b/drivers/tty/tty-win32api.c
@@ -0,0 +1,373 @@
+
+/***************************************************************
+ Win32API Contents:
+ ***************************************************************/
+
+COMMTIMEOUTS cto;
+DCB dcb;
+
+unsigned char *dev_tty = "\\\\.\\com1";
+
+HANDLE fd = NULL;
+
+static void tty_handler( status )
+ int status;
+{
+ unsigned long len = 0;
+ unsigned char data, flag = 0;
+
+ if( fd == 0 ) return;
+
+ while( ReadFile( fd, &data, 1, &len, NULL ) && len )
+ {
+ emit_ring_rx_char( data );
+
+#ifdef DEBUG_TTY_RXD
+ if( flag == 0 )
+ {
+ fprintf( stdout, "TTY: rx [%02X", data );
+ fflush( stdout );
+ }
+ else
+ {
+ fprintf( stdout, " %02X", data );
+ fflush( stdout );
+ }
+ flag = 1;
+#endif
+
+ }
+
+#ifdef DEBUG_TTY_RXD
+ if( flag )
+ {
+ fprintf( stdout, "]\n" );
+ fflush( stdout );
+ }
+#endif
+}
+
+
+void tty_uninit()
+{
+ if( fd )
+ {
+ PurgeComm( fd, PURGE_TXABORT | PURGE_RXABORT |
+ PURGE_TXCLEAR | PURGE_RXCLEAR );
+ CloseHandle( fd );
+ }
+ fd = NULL;
+}
+
+int tty_init( baudrate, parity, data_bits, stop_bits )
+ unsigned long baudrate;
+ enum parity parity;
+ unsigned char data_bits;
+ enum stop_bits stop_bits;
+{
+ unsigned long speed;
+ int rc;
+
+ do_ring_rx( 2, NULL, 0 );
+
+ if( fd )
+ {
+ tty_uninit();
+ }
+
+ fd = CreateFile( dev_tty,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL );
+
+ if( fd == INVALID_HANDLE_VALUE )
+ {
+#ifdef DEBUG_TTY_OPEN
+ if( GetLastError() == ERROR_FILE_NOT_FOUND )
+ {
+ fprintf( stderr, "TTY : Open port %s: ERROR: Port not found.\n", dev_tty );
+ }
+ fprintf( stderr, "TTY : Open port %s: CreateFile(): ERROR=%d.\n", dev_tty, GetLastError() );
+ fflush( stderr );
+#endif
+ fd = NULL;
+ return( -1 );
+ }
+
+#ifdef DEBUG_TTY_OPEN
+ fprintf( stdout, "TTY: Open port %s: OK.\n", dev_tty );
+ fflush( stdout );
+#endif
+
+
+ if( !SetupComm( fd, RING_RX_BUF_LEN, RING_RX_BUF_LEN ) )
+ {
+#ifdef DEBUG_TTY_OPEN
+ fprintf( stderr, "TTY: Port %s: SetupComm(): ERROR=%d.\n", dev_tty, GetLastError() );
+ fflush( stderr );
+#endif
+ CloseHandle( fd );
+ fd = NULL;
+ return( -1 );
+ }
+
+ memset( &dcb, 0, sizeof( dcb ) );
+
+ dcb.DCBlength = sizeof( dcb );
+ if( !GetCommState( fd, &dcb ) )
+ {
+#ifdef DEBUG_TTY_OPEN
+ fprintf( stderr, "TTY: Port %s: GetCommState(): ERROR=%d.\n", dev_tty, GetLastError() );
+ fflush( stderr );
+#endif
+ CloseHandle( fd );
+ fd = NULL;
+ return( -1 );
+ }
+
+ switch( baudrate )
+ {
+ case 110: speed = CBR_110; break;
+ case 300: speed = CBR_300; break;
+ case 600: speed = CBR_600; break;
+ case 1200: speed = CBR_1200; break;
+ case 2400: speed = CBR_2400; break;
+ case 4800: speed = CBR_4800; break;
+ case 9600: speed = CBR_9600; break;
+ case 14400: speed = CBR_14400; break;
+ case 19200: speed = CBR_19200; break;
+ case 38400: speed = CBR_38400; break;
+ case 57600: speed = CBR_57600; break;
+ case 115200: speed = CBR_115200; break;
+ case 128000: speed = CBR_128000; break;
+ case 256000: speed = CBR_256000; break;
+
+ default: speed = CBR_115200; break;
+ }
+
+ switch( parity )
+ {
+ case _N:
+ dcb.Parity = NOPARITY;
+ break;
+ case _E:
+ dcb.Parity = EVENPARITY;
+ break;
+ case _O:
+ dcb.Parity = ODDPARITY;
+ break;
+ }
+
+ if( stop_bits == _TWO )
+ dcb.StopBits = TWOSTOPBITS;
+ else
+ dcb.StopBits = ONESTOPBIT;
+
+ switch( data_bits )
+ {
+ case 5:
+ dcb.ByteSize = 5;
+ dcb.StopBits = ONESTOPBIT; /* _TWO is invalid for this size */
+ break;
+ case 6:
+ dcb.ByteSize = 6;
+ break;
+ case 7:
+ dcb.ByteSize = 7;
+ break;
+ case 8:
+ dcb.ByteSize = 8;
+ break;
+ default:
+ dcb.ByteSize = 8;
+ break;
+ }
+
+ dcb.DCBlength = sizeof( dcb );
+ dcb.BaudRate = speed;
+
+ dcb.fBinary = TRUE;
+ dcb.EofChar = 0;
+ dcb.fNull = FALSE;
+
+ dcb.fErrorChar = FALSE;
+ dcb.ErrorChar = 0;
+
+ dcb.fTXContinueOnXoff = TRUE;
+ dcb.fOutX = FALSE;
+ dcb.fInX = FALSE;
+
+ dcb.XonChar = 0x11;
+ dcb.XoffChar = 0x13;
+
+ dcb.fOutxDsrFlow = FALSE;
+
+ dcb.fRtsControl = RTS_CONTROL_ENABLE;
+ dcb.fOutxCtsFlow = FALSE;
+
+ dcb.fDtrControl = DTR_CONTROL_ENABLE;
+
+ dcb.fDsrSensitivity = FALSE;
+
+ dcb.fAbortOnError = TRUE;
+
+
+ if( !SetCommState( fd, &dcb ) )
+ {
+#ifdef DEBUG_TTY_OPEN
+ fprintf( stderr, "TTY : Port %s: SetCommState(): ERROR=%d.\n", dev_tty, GetLastError() );
+ fflush( stderr );
+#endif
+
+ CloseHandle( fd );
+ fd = NULL;
+ return( -1 );
+ }
+
+
+
+ memset( &cto, 0, sizeof(cto) );
+
+ cto.ReadIntervalTimeout = 10; /* we need 500 ms for DaVinci loader */
+ cto.ReadTotalTimeoutConstant = 0;
+ cto.ReadTotalTimeoutMultiplier = 10;
+
+ cto.WriteTotalTimeoutConstant = 0;
+ cto.WriteTotalTimeoutMultiplier = 0;
+
+ if( !SetCommTimeouts( fd, &cto ) )
+ {
+#ifdef DEBUG_TTY_OPEN
+ fprintf( stderr, "TTY : Port %s: SetCommTimeouts(): ERROR=%d.\n", dev_tty, GetLastError() );
+ fflush( stderr );
+#endif
+ CloseHandle( fd );
+ fd = NULL;
+ return( -1 );
+ }
+
+ FlushFileBuffers( fd );
+
+ PurgeComm( fd, PURGE_TXABORT | PURGE_RXABORT |
+ PURGE_TXCLEAR | PURGE_RXCLEAR );
+
+ return( 1 );
+}
+
+int tty_read( buf, len )
+ unsigned char *buf;
+ int len;
+{
+ return( do_ring_rx( 0, buf, len ) );
+}
+
+/* bool */
+int tty_write( buf, len )
+ unsigned char *buf;
+ int len;
+{
+#ifdef DEBUG_TTY_TXD
+ int i;
+
+ for( i = 0; i < len; ++i )
+ {
+ if( i == 0 )
+ {
+ fprintf( stdout, "TTY: tx [%02X", buf[i] );
+ fflush( stdout );
+ }
+ else
+ fprintf( stdout, " %02X", buf[i] );
+ fflush( stdout );
+ }
+#endif
+
+ if( fd != 0 )
+ {
+ unsigned long written;
+ int part = 64, full = len;
+
+ /********************************************
+ Delay transmiting by byte to byte writing.
+ ********************************************/
+ while( full > part )
+ {
+
+ if( !WriteFile( fd, buf, part, &written, NULL ) ) goto wr_error;
+ if( written != (unsigned)part ) goto wr_error;
+
+ buf += part;
+ full -= part;
+ /* wait until all data will be trasmited */
+ FlushFileBuffers( fd );
+ Sleep( 1 );
+ }
+
+
+ if( !WriteFile( fd, buf, full, &written, NULL ) ) goto wr_error;
+ if( written != (unsigned)full ) goto wr_error;
+
+ /* wait until all data will be trasmited */
+ FlushFileBuffers( fd );
+ Sleep( 1 );
+
+
+#ifdef DEBUG_TTY_TXD
+ fprintf( stdout, "] end of transmiting : OK.\n" );
+ fflush( stdout );
+#endif
+ return( len ); /* TRUE */
+ }
+
+wr_error:
+#ifdef DEBUG_TTY_TXD
+ fprintf( stdout, "] end of transmiting : ERROR.\n" );
+ fflush( stdout );
+#endif
+
+ return( 0 ); /* FALSE */
+}
+
+/* bool */
+int tty_putc( c )
+ unsigned char c;
+{
+ unsigned long written;
+
+ if( fd != 0 && WriteFile( fd, &c, 1, &written, NULL ) )
+ {
+#ifdef DEBUG_TTY_TXD
+ fprintf( stdout, "TTY: tx [%02X] OK.\n", c );
+ fflush( stdout );
+#endif
+ return( 1 ); /* TRUE */
+ }
+
+#ifdef DEBUG_TTY_TXD
+ fprintf( stderr, "TTY: tx [%02X]: ERROR=%d.\n", c, GetLastError() );
+ fflush( stderr );
+#endif
+
+ return( 0 ); /* FALSE */
+}
+
+/* bool */
+int tty_getc( c )
+ unsigned char *c;
+{
+ int rc;
+
+ rc = do_ring_rx( 0, c, 1 );
+ if( rc > 0 ) return( 1 ); /* TRUE */
+
+ return( 0 );
+}
+
+
+void tty_int()
+{
+ tty_handler( 0 );
+}
diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c
new file mode 100644
index 0000000..d381f6c
--- /dev/null
+++ b/drivers/tty/tty.c
@@ -0,0 +1,159 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#if defined( __MINGW32__ )
+
+#include <windows.h>
+
+#else /* LINUX / __CYGWIN__ */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+
+#endif /* __MINGW32__ */
+
+#if defined(DEBUG_TTY_OPEN) || defined(DEBUG_TTY_TXD) || defined(DEBUG_TTY_RXD)
+#include <errno.h>
+#include <string.h>
+#endif
+
+#include <defs.h>
+
+#include <tty.h>
+
+
+#define RING_RX_BUF_LEN 1024 /* This must be a power of two */
+#define RING_RX_BUF_MASK (RING_RX_BUF_LEN-1)
+
+static unsigned char ring_rx_buf[RING_RX_BUF_LEN];
+#define RING_RX_BUF(idx) (ring_rx_buf[(idx) & RING_RX_BUF_MASK])
+
+static unsigned short ring_rx_start = 0; /* Index into ring_rx_buf[]: next char to be read by this program */
+static unsigned short ring_rx_end = 0; /* Index into ring_rx_buf[]: next char to be reseive by the port */
+static unsigned short ringged_rx_chars = 0; /* Number of valid chars in the ring_rx_buf[] */
+
+/*
+ type:
+ 0 - read from the ring_rx_buf[], if ring_rx_buf[] is empty after reading
+ reset indexes: ring_rx_start = ring_rx_end = 0;
+ 1 - read from the ring_rx_buf[] without cleaning ring_rx_start, ring_rx_end
+ indexes;
+ 2 - clear ring_rx_buf[];
+ 3 - return number of unread characters in the ring_rx_buf[].
+ */
+int do_ring_rx( type, buf, len )
+ int type;
+ unsigned char *buf;
+ int len;
+{
+ int do_clear = 0;
+ int i, error = 0;
+ unsigned char c;
+
+ switch( type )
+ {
+ case 0: /* Read and clean indexes if the ring_buf[] is empty */
+ do_clear = 1;
+ /* FALL THRU */
+ case 1: /* Read without reset indexes */
+ error = -1; /* EINVAL */
+ if( !buf || len < 0 ) goto out;
+ error = 0;
+ if( !len ) goto out;
+
+ /*************************************************
+ Is there are character? (ring_start - ring_end)
+ *************************************************/
+ if( !(ring_rx_start - ring_rx_end) ) goto out;
+
+ i = 0;
+/* pthread_mutex_lock( (pthread_mutex_t *)&mu ); */
+ while( (ring_rx_start != ring_rx_end) && i < len )
+ {
+ c = RING_RX_BUF( ring_rx_start );
+ ring_rx_start++;
+ ringged_rx_chars--;
+
+/* pthread_mutex_unlock( (pthread_mutex_t *)&mu ); */
+ *buf = c; /* put to user space( c => buf ); */
+ buf++;
+ i++;
+/* pthread_mutex_lock( (pthread_mutex_t *)&mu ); */
+ }
+/* pthread_mutex_unlock( (pthread_mutex_t *)&mu ); */
+ error = i;
+ if( do_clear )
+ {
+ if( !ringged_rx_chars )
+ {
+/* pthread_mutex_lock( (pthread_mutex_t *)&mu ); */
+ ring_rx_start = ring_rx_end = 0;
+/* pthread_mutex_unlock( (pthread_mutex_t *)&mu ); */
+ }
+ }
+ break;
+
+ case 2: /* Clear ring_buf[] */
+/* pthread_mutex_lock( (pthread_mutex_t *)&mu ); */
+ ring_rx_start = ring_rx_end = 0;
+ ringged_rx_chars = 0;
+/* pthread_mutex_unlock( (pthread_mutex_t *)&mu ); */
+ break;
+
+ case 3: /* Number of chars in the ring_buf[] */
+/* pthread_mutex_lock( (pthread_mutex_t *)&mu ); */
+ error = ring_rx_end - ring_rx_start;
+/* pthread_mutex_unlock( (pthread_mutex_t *)&mu ); */
+ break;
+
+ default:
+ error = -1; /* EINVAL */
+ break;
+ }
+
+out:
+ return( error );
+}
+
+
+static void emit_ring_rx_char( c )
+ unsigned char c;
+{
+#ifdef DEBUG_TTY_RXD
+ unsigned char lost = RING_RX_BUF( ring_rx_end );
+#endif
+
+ RING_RX_BUF( ring_rx_end ) = c;
+
+ ring_rx_end++;
+ if( ring_rx_end - ring_rx_start > RING_RX_BUF_LEN )
+ {
+#ifdef DEBUG_TTY_RXD
+ fprintf( stderr, "TTY: rx_buf overflow: lost the '%c' char.\n", lost );
+ fflush( stderr );
+#endif
+ ring_rx_start = ring_rx_end - RING_RX_BUF_LEN;
+ }
+ if( ringged_rx_chars < RING_RX_BUF_LEN ) ringged_rx_chars++;
+}
+
+
+/***************************************************************
+ BODY:
+ ***************************************************************/
+
+#if __MINGW32__ == 1
+
+#include "tty-win32api.c"
+
+#else /* LINUX / __CYGWIN__ */
+
+#include "tty-linux.c"
+
+#endif /* __MINGW32__ */
diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h
new file mode 100644
index 0000000..0436fb5
--- /dev/null
+++ b/drivers/tty/tty.h
@@ -0,0 +1,54 @@
+
+#ifndef TTY_H
+#define TTY_H
+
+typedef enum parity
+{
+ _N, /* no */
+ _E, /* even */
+ _O /* odd */
+} PARITY;
+
+typedef enum stop_bits
+{
+ _ONE = 1,
+ _TWO = 2
+} STOP_BITS;
+
+
+extern unsigned char *dev_tty;
+
+#if defined( __cplusplus )
+extern "C" {
+#endif
+
+extern void tty_uninit __PROTO(( void ));
+
+extern int tty_init __PROTO(( unsigned long baudrate,
+ enum parity parity,
+ unsigned char data_bits,
+ enum stop_bits stop_bits ));
+
+#if !defined( __MINGW32__ ) && !defined( __CYGWIN__ )
+extern void tty_ring_clear __PROTO(( void ));
+#endif
+
+extern int tty_read __PROTO(( unsigned char *buf, int len ));
+
+/* bool */
+extern int tty_write __PROTO(( unsigned char *buf, int len ));
+
+/* bool */
+extern int tty_putc __PROTO(( unsigned char c ));
+
+/* bool */
+extern int tty_getc __PROTO(( unsigned char *c ));
+
+extern void tty_int __PROTO(( void ));
+
+
+#if defined( __cplusplus )
+} /* ... extern "C" */
+#endif
+
+#endif /* TTY_H */
diff --git a/include/byteorder/__tx_big_endian.h b/include/byteorder/__tx_big_endian.h
new file mode 100644
index 0000000..1ba59e4
--- /dev/null
+++ b/include/byteorder/__tx_big_endian.h
@@ -0,0 +1,44 @@
+
+#ifndef __TX_BIG_ENDIAN_H
+#define __TX_BIG_ENDIAN_H
+
+#ifndef __TX_BIG_ENDIAN
+#define __TX_BIG_ENDIAN 4321
+#endif
+
+#include <byteorder/__tx_bswap.h>
+
+#ifdef __GNUC__
+#define __tx_cpu_to_le64(x) ((unsigned long long int)__swab64((x)))
+#define __tx_le64_to_cpu(x) __swab64((unsigned long long int)(x))
+#endif
+
+#ifdef _LP64
+#define __tx_cpu_to_le32(x) ((unsigned int )__swab32((x)))
+#define __tx_le32_to_cpu(x) __swab32((unsigned int )(x))
+#else
+#define __tx_cpu_to_le32(x) ((unsigned long int )__swab32((x)))
+#define __tx_le32_to_cpu(x) __swab32((unsigned long int )(x))
+#endif
+#define __tx_cpu_to_le16(x) ((unsigned short int )__swab16((x)))
+#define __tx_le16_to_cpu(x) __swab16((unsigned short int )(x))
+
+
+
+#ifdef __GNUC__
+#define __tx_cpu_to_be64(x) ((unsigned long long int)(x))
+#define __tx_be64_to_cpu(x) ((unsigned long long int)(x))
+#endif
+
+#ifdef _LP64
+#define __tx_cpu_to_be32(x) ((unsigned int )(x))
+#define __tx_be32_to_cpu(x) ((unsigned int )(x))
+#else
+#define __tx_cpu_to_be32(x) ((unsigned long int )(x))
+#define __tx_be32_to_cpu(x) ((unsigned long int )(x))
+#endif
+#define __tx_cpu_to_be16(x) ((unsigned short int )(x))
+#define __tx_be16_to_cpu(x) ((unsigned short int )(x))
+
+
+#endif /* __TX_BIG_ENDIAN_H */
diff --git a/include/byteorder/__tx_bswap.h b/include/byteorder/__tx_bswap.h
new file mode 100644
index 0000000..80d00e5
--- /dev/null
+++ b/include/byteorder/__tx_bswap.h
@@ -0,0 +1,74 @@
+
+#ifndef __TX_BSWAP_H
+#define __TX_BSWAP_H
+
+/***************************************************************
+ Swap bytes in 16 bit value.
+ ***************************************************************/
+#ifdef __GNUC__
+#define __tx_bswap_16( x ) \
+ (__extension__ \
+ ({ unsigned short int __bsx = (x); \
+ ((((__bsx) >> 8) & 0xffU) | (((__bsx) & 0xffU) << 8)); }))
+#else
+static __inline unsigned short int
+__tx_bswap_16( unsigned short int __bsx )
+{
+ return( (((__bsx) >> 8) & 0xffU) | (((__bsx) & 0xffU) << 8) );
+}
+#endif
+
+/***************************************************************
+ Swap bytes in 32 bit value.
+ ***************************************************************/
+#ifdef _LP64
+#ifdef __GNUC__
+#define __tx_bswap_32( x ) \
+ (__extension__ \
+ ({ unsigned int __bsx = (x); \
+ ((((__bsx) & 0xff000000UL) >> 24) | (((__bsx) & 0x00ff0000UL) >> 8) | \
+ (((__bsx) & 0x0000ff00UL) << 8) | (((__bsx) & 0x000000ffUL) << 24)); }))
+#else
+static __inline unsigned int
+__tx_bswap_32( unsigned int __bsx )
+{
+ return( (((__bsx) & 0xff000000UL) >> 24) | (((__bsx) & 0x00ff0000UL) >> 8) |
+ (((__bsx) & 0x0000ff00UL) << 8) | (((__bsx) & 0x000000ffUL) << 24) );
+}
+#endif
+#else
+#ifdef __GNUC__
+#define __tx_bswap_32( x ) \
+ (__extension__ \
+ ({ unsigned long int __bsx = (x); \
+ ((((__bsx) & 0xff000000UL) >> 24) | (((__bsx) & 0x00ff0000UL) >> 8) | \
+ (((__bsx) & 0x0000ff00UL) << 8) | (((__bsx) & 0x000000ffUL) << 24)); }))
+#else
+static __inline unsigned long int
+__tx_bswap_32( unsigned long int __bsx )
+{
+ return( (((__bsx) & 0xff000000UL) >> 24) | (((__bsx) & 0x00ff0000UL) >> 8) |
+ (((__bsx) & 0x0000ff00UL) << 8) | (((__bsx) & 0x000000ffUL) << 24) );
+}
+#endif
+#endif
+
+/***************************************************************
+ Swap bytes in 64 bit value.
+ ***************************************************************/
+#ifdef __GNUC__
+#define __tx_bswap_64( x ) \
+ (__extension__ \
+ ({ unsigned long long int __bsx = (x); \
+ ((((__bsx) & 0x00000000000000ffULL) << 56) | \
+ (((__bsx) & 0x000000000000ff00ULL) << 40) | \
+ (((__bsx) & 0x0000000000ff0000ULL) << 24) | \
+ (((__bsx) & 0x00000000ff000000ULL) << 8) | \
+ (((__bsx) & 0x000000ff00000000ULL) >> 8) | \
+ (((__bsx) & 0x0000ff0000000000ULL) >> 24) | \
+ (((__bsx) & 0x00ff000000000000ULL) >> 40) | \
+ (((__bsx) & 0xff00000000000000ULL) >> 56)); }))
+#endif
+
+
+#endif /* __TX_BSWAP_H */
diff --git a/include/byteorder/__tx_little_endian.h b/include/byteorder/__tx_little_endian.h
new file mode 100644
index 0000000..270dff0
--- /dev/null
+++ b/include/byteorder/__tx_little_endian.h
@@ -0,0 +1,45 @@
+
+#ifndef __TX_LITTLE_ENDIAN_H
+#define __TX_LITTLE_ENDIAN_H
+
+#ifndef __TX_LITTLE_ENDIAN
+#define __TX_LITTLE_ENDIAN 1234
+#endif
+
+#include <byteorder/__tx_bswap.h>
+
+
+#ifdef __GNUC__
+#define __tx_cpu_to_le64(x) ((unsigned long long int)(x))
+#define __tx_le64_to_cpu(x) ((unsigned long long int)(x))
+#endif
+
+#ifdef _LP64
+#define __tx_cpu_to_le32(x) ((unsigned int )(x))
+#define __tx_le32_to_cpu(x) ((unsigned int )(x))
+#else
+#define __tx_cpu_to_le32(x) ((unsigned long int )(x))
+#define __tx_le32_to_cpu(x) ((unsigned long int )(x))
+#endif
+#define __tx_cpu_to_le16(x) ((unsigned short int )(x))
+#define __tx_le16_to_cpu(x) ((unsigned short int )(x))
+
+
+
+#ifdef __GNUC__
+#define __tx_cpu_to_be64(x) ((unsigned long long int)__tx_bswap_64((x)))
+#define __tx_be64_to_cpu(x) __tx_bswap_64((unsigned long long int)(x))
+#endif
+
+#ifdef _LP64
+#define __tx_cpu_to_be32(x) ((unsigned int )__tx_bswap_32((x)))
+#define __tx_be32_to_cpu(x) __tx_bswap_32((unsigned int )(x))
+#else
+#define __tx_cpu_to_be32(x) ((unsigned long int )__tx_bswap_32((x)))
+#define __tx_be32_to_cpu(x) __tx_bswap_32((unsigned long int )(x))
+#endif
+#define __tx_cpu_to_be16(x) ((unsigned short int )__tx_bswap_16((x)))
+#define __tx_be16_to_cpu(x) __tx_bswap_16((unsigned short int )(x))
+
+
+#endif /* __TX_LITTLE_ENDIAN_H */
diff --git a/math/crc32/crc32.c b/math/crc32/crc32.c
new file mode 100644
index 0000000..c61d4bc
--- /dev/null
+++ b/math/crc32/crc32.c
@@ -0,0 +1,81 @@
+
+#include <defs.h>
+
+#include <crc32.h>
+
+#define BITS_PER_SHIFT 8
+
+#define CRC32_TABLE_SIZE 256
+
+uint32_t crc32_table[CRC32_TABLE_SIZE] = { 0 };
+
+
+static uint32_t reflect_num( val, num )
+ uint32_t val;
+ int num;
+{
+ uint32_t out = 0x0;
+ int i;
+
+ for( i = 1; i < (num + 1); ++i )
+ {
+ if( (val & 0x1) != 0x0 )
+ {
+ out |= (uint32_t)(0x1 << (num - i));
+ }
+ val >>= 1;
+ }
+ return( out );
+}
+
+void build_crc32_table()
+{
+ uint32_t crc;
+ uint32_t i;
+ int j;
+
+ for( i = 0; i < CRC32_TABLE_SIZE; ++i )
+ {
+ crc = reflect_num( i, BITS_PER_SHIFT ) << (32 - BITS_PER_SHIFT);
+ for( j = 0; j < BITS_PER_SHIFT; ++j )
+ {
+ if( (crc & 0x80000000) != 0x00000000 )
+ {
+ crc = (crc << 1) ^ CRC32_POLY;
+ }
+ else
+ {
+ crc = (crc << 1);
+ }
+ crc32_table[i] = reflect_num( crc, 32 );
+ }
+ }
+}
+
+
+int
+get_crc32( crc, buf, len )
+ uint32_t *crc;
+ uint8_t *buf;
+ int len;
+{
+ uint32_t cr = CRC32_INIT;
+ uint32_t mask = CRC32_TABLE_SIZE - 1;
+ int i, error = -1; /* EINVAL */
+
+ if( !crc || !buf || len < 0 ) goto out;
+ error = 0; /* len == 0 or check == FALSE */
+ if( !len ) goto out;
+
+ for( i = 0; i < len; ++i )
+ {
+ cr = (cr >> BITS_PER_SHIFT) ^ crc32_table[ (cr & mask) ^ buf[i] ];
+ }
+ cr ^= CRC32_FINAL;
+
+ *crc = cr;
+ error = 1;
+
+out:
+ return( error );
+}
diff --git a/math/crc32/crc32.h b/math/crc32/crc32.h
new file mode 100644
index 0000000..f46ba8f
--- /dev/null
+++ b/math/crc32/crc32.h
@@ -0,0 +1,39 @@
+
+#ifndef CRC32_H
+#define CRC32_H
+
+
+#if defined( __cplusplus )
+extern "C" {
+#endif
+
+#define CRC32_POLY 0x04C11DB7
+#define CRC32_INIT 0xFFFFFFFF
+#define CRC32_FINAL 0xFFFFFFFF
+
+
+#define CRC32_TABLE_SIZE 256
+extern uint32_t crc32_table[];
+
+extern void
+build_crc32_table __PROTO(( void ));
+
+/***************************************************************
+ CRC-32-IEEE 802.3:
+ =================
+ Polynomial: x^32 + x^26 + x^23 + x^22 +
+ x^16 + x^12 + x^11 + x^10 +
+ x^8 + x^7 + x^5 + x^4 +
+ x^2 +x + 1 (0x04C11DB7) or 0xEDB88320
+ (0xDB710641)
+ Initial value: 0xFFFFFFFF
+ ***************************************************************/
+extern int
+get_crc32 __PROTO(( uint32_t *crc, uint8_t *buf, int len ));
+
+
+#if defined( __cplusplus )
+} /* ... extern "C" */
+#endif
+
+#endif /* CRC32_H */
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..eccfb70
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,62 @@
+
+CC = gcc
+CFLAGS += -g -I.
+
+ifeq ($(SECURE),1)
+CFLAGS += -D__SECURE__=1
+else
+CFLAGS += -D__SECURE__=0
+endif
+
+ifeq ($(INFINITY),1)
+CFLAGS += -D__INFINITY__=1
+else
+CFLAGS += -D__INFINITY__=0
+endif
+
+ifeq ($(DEBUG),1)
+CFLAGS += -D__DEBUG__=1 -DDEBUG_TTY_RXD -DDEBUG_TTY_TXD -DDEBUG_TTY_OPEN
+endif
+
+LDFLAGS =
+
+LIBS = -lpthread
+
+INCLUDES = -I. -I.. \
+ -I../include \
+ -I../drivers/tty \
+ -I../math/crc32
+
+VPATH = ../drivers \
+ ../drivers/tty \
+ ../math/crc32
+
+
+SOURCES = tty.c crc32.c
+
+OBJECTS = tty.o crc32.o
+
+
+ifeq ($(SECURE),1)
+MAIN_PROG = ../sIRAM-loader
+else
+MAIN_PROG = ../IRAM-loader
+endif
+
+MAIN_SOURCES = main.c
+MAIN_OBJECTS = main.o
+
+
+.SUFFIXES:
+.SUFFIXES: .o .c
+%.o : %.c
+ $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
+
+
+all: $(MAIN_PROG)
+
+$(MAIN_PROG): $(OBJECTS) $(MAIN_OBJECTS)
+ $(CC) $(LDFLAGS) $(OBJECTS) $(MAIN_OBJECTS) -o $@ $(LIBS)
+
+clean:
+ rm -f *.o $(MAIN_PROG)$(EXEEXT)
diff --git a/src/defs.h b/src/defs.h
new file mode 100644
index 0000000..ea530c5
--- /dev/null
+++ b/src/defs.h
@@ -0,0 +1,58 @@
+
+
+#ifndef _DEFS_H_
+#define _DEFS_H_
+
+#include <inttypes.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#define TRUE 1
+#define FALSE 0
+
+#if !defined( __MINGW32__ )
+#define DIR_SEPARATOR '/'
+#else
+#define DIR_SEPARATOR '\\'
+#endif
+
+/* Minimum and maximum macros */
+#undef __min
+#undef __max
+
+#define __min(X, Y) \
+ ({ typeof (X) x_ = (X); typeof (Y) y_ = (Y); (x_ < y_) ? x_ : y_; })
+
+#define __max(X, Y) \
+ ({ typeof (X) x_ = (X); typeof (Y) y_ = (Y); (x_ > y_) ? x_ : y_; })
+
+
+/*
+ PROTOTYPES (identifier: __tx_PROTO) .
+ ***************************************************************/
+#ifndef __PROTO
+# if defined( __cplusplus ) || (defined( __STDC__ ) && __STDC__)
+# define __PROTO( args ) args
+# else /* Not C++ or ANSI C. GCC: */
+# define __PROTO( args ) ()
+# endif /* GCC. */
+#endif /* Not __tx_PROTO. */
+
+
+#ifndef HOST_WORDS_BIG_ENDIAN
+#define HOST_WORDS_BIG_ENDIAN 0
+#endif
+
+#ifndef HOST_BITS_PER_BYTE
+#define HOST_BITS_PER_BYTE 8
+#endif
+
+#ifndef HOST_BITS_PER_MACHINE_REGISTER
+#define HOST_BITS_PER_MACHINE_REGISTER 32
+#endif
+
+
+#endif /* _DEFS_H_ */
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..21d1588
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,596 @@
+
+/**************************************************************
+ **************************************************************/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <signal.h>
+
+#if !defined( __MINGW32__ )
+#include <termios.h>
+#include <sys/ioctl.h>
+#endif
+
+#if !defined( __MINGW32__ ) && !defined( __CYGWIN__ )
+#include <sys/stat.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <defs.h>
+
+#include <crc32.h>
+#include <tty.h>
+
+#if HOST_WORDS_BIG_ENDIAN == 1
+#include <byteorder/__tx_big_endian.h>
+#else
+#include <byteorder/__tx_little_endian.h>
+#endif
+
+#if __SECURE__ == 1
+#define SIZE_OF_PKH 272
+#define SIZE_OF_MODULE 14064 /* 13920 without info-header(16) & signature(128) */
+#else
+#define SIZE_OF_PKH 0
+#define SIZE_OF_MODULE 14336
+#endif /* __SECURE__ */
+
+
+#if __DEBUG__ == 1
+static void
+print_crc32_table( p, len )
+ uint32_t *p;
+ int len;
+{
+ fprintf( stdout, "\nCRC32 table:\n" );
+ fprintf( stdout, "===========\n" );
+
+ fprintf( stdout, "[%08X", (unsigned int)*p );
+ fflush( stdout );
+
+ ++p;
+ --len;
+
+ while( len )
+ {
+ if( (len % 8) == 0 )
+ {
+ fprintf( stdout, "\n" );
+ fflush( stdout );
+ }
+
+ fprintf( stdout, " %08X", (unsigned int)*p );
+ fflush( stdout );
+
+ ++p;
+ --len;
+ }
+ fprintf( stdout, "]\n" );
+ fflush( stdout );
+}
+#endif /* __DEBUG__ */
+
+static int
+DaVinci_read( buf, len )
+ uint8_t *buf;
+ int len;
+{
+ int error = -1; /* EIVAL */
+
+ if( !buf || len < 0 ) goto out;
+ error = 0;
+ if( !len ) goto out;
+
+#if defined( __MINGW32__ ) || defined( __CYGWIN__ )
+ tty_int();
+#endif
+ error = tty_read( buf, len );
+ while( error < len )
+ {
+ buf += error;
+ len -= error;
+#if defined( __MINGW32__ ) || defined( __CYGWIN__ )
+ tty_int();
+#endif
+ error = tty_read( buf, len );
+ }
+
+out:
+ return( error );
+}
+
+
+static char *progname;
+
+/***************************************************************
+ Function: usage()
+
+ Description: print usage message
+
+ Returns:
+
+ Notes:
+
+ ***************************************************************/
+static void usage()
+{
+ printf( "Usage: %s [OPTIONS] <module>\n", progname );
+ printf( "Load signed boot module into DaVinci over UART interface.\n" );
+ printf( "\t-t,--tty=DEVICE\tserial port name (default /dev/ttyS0);\n" );
+ printf( "\t-e,--entry=ADDRESS\tmodule code entry point, hex number (default 0100);\n" );
+#if __SECURE__ == 1
+ printf( "\t-p,--pkheader=FILENAME\tmodule Public Key Header file name;\n" );
+#endif /* __SECURE__ */
+ printf( "\t-h,--help\t\tprint this message.\n" );
+ exit( 1 );
+}
+
+static char *tty = NULL;
+static char *entry = "0100";
+#if __SECURE__ == 1
+static char *pkh_fname = NULL;
+#endif /* __SECURE__ */
+static char *module_fname = NULL;
+
+static void
+getargs( argc, argv )
+ int argc;
+ char *argv[];
+{
+ int option = 0;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ { "tty", 1, 0, 't' },
+ { "entry", 1, 0, 'e' },
+#if __SECURE__ == 1
+ { "pkheader", 1, 0, 'p' },
+#endif /* __SECURE__ */
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+ };
+
+#if __SECURE__ == 1
+ while( (option = getopt_long( argc, argv, "t:e:p:h", long_options, &option_index )) != -1 )
+#else
+ while( (option = getopt_long( argc, argv, "t:e:h", long_options, &option_index )) != -1 )
+#endif /* __SECURE__ */
+ {
+ switch( option )
+ {
+ case 't':
+ tty = optarg;
+ break;
+ case 'e':
+ entry = optarg;
+ break;
+#if __SECURE__ == 1
+ case 'p':
+ pkh_fname = optarg;
+ break;
+#endif /* __SECURE__ */
+ case 'h':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if( optind < argc )
+ {
+ module_fname = argv[optind++];
+ }
+ else
+ {
+ usage();
+ }
+}
+
+
+int main( argc, argv )
+ int argc;
+ char *argv[];
+{
+ int fd, fsize, msize;
+ struct stat st;
+ uint32_t crc = 0;
+ int error = -1;
+ unsigned char buf[SIZE_OF_PKH + SIZE_OF_MODULE] = { 0 };
+ unsigned char rx_buf[256];
+ unsigned char tx_buf[256];
+ int i;
+
+ progname = rindex( argv[0], DIR_SEPARATOR ) + 1;
+
+ getargs( argc, argv );
+#if __DEBUG__ == 1
+ printf( "tty : '%s'\n", tty );
+ printf( "entry : '%s'\n", entry );
+#if __SECURE__ == 1
+ printf( "pkh_fname : '%s'\n", pkh_fname );
+#endif /* __SECURE__ */
+ printf( "module_fname: '%s'\n", module_fname );
+#endif
+
+ if( strlen( entry ) != 4 ) usage();
+
+ /************************************************************
+ Set serial port:
+ ===============
+ ************************************************************/
+ if( tty )
+ {
+ dev_tty = tty;
+ }
+ else
+ {
+#if !defined( __CYGWIN__ ) && !defined( __MINGW32__ )
+ dev_tty = "/dev/ttyS0";
+#else
+#if __MINGW32__ == 1
+ dev_tty = "\\\\.\\com1";
+#else
+ dev_tty = "/dev/ttyS0"; /* or "/dev/com1" */
+#endif
+#endif
+ }
+
+#define __SPEED 115200
+ if( (fd = tty_init( __SPEED, _N, 8, 1 ) ) < 0 )
+ {
+#if __DEBUG__ == 1
+ fprintf( stderr, "open output device '%s': ERROR = '%s'\n",
+ dev_tty, strerror( errno ) );
+#endif
+ exit( 1 );
+ }
+
+
+#if __SECURE__ == 1
+ /************************************************************
+ Read PKH file:
+ =============
+ ************************************************************/
+ if( !pkh_fname && *pkh_fname )
+ {
+ fprintf( stderr, "ERROR: no input PKH file\n" );
+ tty_uninit();
+ exit( 1 );
+ }
+
+ error = stat( pkh_fname, &st );
+ if( error == -1 )
+ {
+ fprintf( stderr, "ERROR: %s: %s;\n", pkh_fname, strerror( errno ) );
+ tty_uninit();
+ exit( 1 );
+ }
+ fsize = st.st_size;
+ if( fsize != SIZE_OF_PKH )
+ {
+ fprintf( stderr, "ERROR: %s: invalid size of file;\n", pkh_fname );
+ tty_uninit();
+ exit( 1 );
+ }
+
+ /* open PKH file */
+#if __MINGW32__ == 1
+ if( (fd = open( pkh_fname, O_BINARY | O_RDONLY, 0644 )) == -1 )
+#else
+ if( (fd = open( pkh_fname, O_RDONLY, 0644 )) == -1 )
+#endif
+ {
+ fprintf( stderr, "ERROR: %s: %s;\n", pkh_fname, strerror( errno ) );
+ tty_uninit();
+ exit( 1 );
+ }
+
+ if( read( fd, buf, SIZE_OF_PKH ) < SIZE_OF_PKH )
+ {
+ fprintf( stderr, "ERROR: %s: %s;\n", pkh_fname, strerror( errno ) );
+ tty_uninit();
+ exit( 1 );
+ }
+#endif /* __SECURE__ */
+
+
+ /************************************************************
+ Read Boot Module file:
+ ==============================
+ ************************************************************/
+ if( !module_fname && *module_fname )
+ {
+ fprintf( stderr, "ERROR: no input BOOT MODULE file\n" );
+ tty_uninit();
+ exit( 1 );
+ }
+
+ error = stat( module_fname, &st );
+ if( error == -1 )
+ {
+ fprintf( stderr, "ERROR: %s: %s;\n", module_fname, strerror( errno ) );
+ tty_uninit();
+ exit( 1 );
+ }
+ fsize = st.st_size;
+ if( fsize > SIZE_OF_MODULE || (fsize % 16) != 0 )
+ {
+ fprintf( stderr, "ERROR: %s: invalid size of file;\n", module_fname );
+ tty_uninit();
+ exit( 1 );
+ }
+
+ /* open BOOT MODULE file */
+#if __MINGW32__ == 1
+ if( (fd = open( module_fname, O_BINARY | O_RDONLY, 0644 )) == -1 )
+#else
+ if( (fd = open( module_fname, O_RDONLY, 0644 )) == -1 )
+#endif
+ {
+ fprintf( stderr, "ERROR: %s: %s;\n", module_fname, strerror( errno ) );
+ tty_uninit();
+ exit( 1 );
+ }
+
+#if __SECURE__ == 1
+ if( read( fd, &buf[SIZE_OF_PKH], fsize ) < fsize )
+#else
+ if( read( fd, &buf[0], fsize ) < fsize )
+#endif /* __SECURE__ */
+ {
+ fprintf( stderr, "ERROR: %s: %s;\n", module_fname, strerror( errno ) );
+ tty_uninit();
+ exit( 1 );
+ }
+
+ /* BOOT MODULE size */
+#if __SECURE__ == 1
+ msize = SIZE_OF_PKH + fsize;
+#else
+ msize = fsize;
+#endif /* __SECURE__ */
+
+
+ /************************************************************
+ Build CRC32 table:
+ =================
+ ************************************************************/
+ build_crc32_table();
+#if __DEBUG__ == 1
+ print_crc32_table( &crc32_table[0], CRC32_TABLE_SIZE );
+#endif
+
+#if __DEBUG__ == 1
+ {
+ uint8_t test[] = "123456789";
+ uint32_t crc = 0;
+ int ret = -1;
+
+ ret = get_crc32( &crc, test, 9 );
+
+ printf( "check crc32: %08X: '%s'\n\n", (unsigned int)crc, test );
+
+ }
+#endif
+
+ error = get_crc32( &crc, buf, msize );
+ if( error < 1 )
+ {
+ fprintf( stderr, "ERROR: cannot get CRC32;\n" );
+ tty_uninit();
+ exit( 1 );
+ }
+ crc = ~crc;
+
+#if __DEBUG__ == 1
+ fprintf( stdout, "crc32: %08X;\n\n", (unsigned int)crc );
+#endif
+
+
+boot:
+
+#if __SECURE__ == 1
+ fprintf( stdout, "\nWaiting for SBOOTME from DaVinci...\n" );
+#else
+ fprintf( stdout, "\nWaiting for BOOTME from DaVinci...\n" );
+#endif /* __SECURE__ */
+
+ error = DaVinci_read( rx_buf, 8 );
+ if( error <= 0 )
+ {
+ tty_uninit();
+ exit( 1 );
+ }
+#if __DEBUG__ == 1
+ printf( "read from DaVinci: len: %d: '%s';\n", error, rx_buf );
+#endif
+
+#if __SECURE__ == 1
+ if( !strncmp( "SBOOTME\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "SBOOTME command received. Returning ACK and Header...\n" );
+ }
+#else
+ if( !strncmp( " BOOTME\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "BOOTME command received. Returning ACK and Header...\n" );
+ }
+#endif /* __SECURE__ */
+ else
+ {
+ goto boot;
+ }
+
+ tty_write( " ACK\0", 8 );
+ sprintf( tx_buf, "%08X", (unsigned int)crc );
+ tty_write( tx_buf, 8 );
+ sprintf( tx_buf, "%04X", msize );
+ tty_write( tx_buf, 4 );
+ tty_write( entry, 4 );
+ tty_write( "0000", 4 );
+
+ fprintf( stdout, "\nWaiting for BEGIN from DaVinci...\n" );
+
+ /* Clear RING buffer after BOOTME BOOTME BOOTME... */
+ tty_ring_clear();
+
+ /************************************************************
+ Waiting for ' BEGIN\0':
+ =======================
+ ************************************************************/
+ error = DaVinci_read( rx_buf, 8 );
+ if( error <= 0 )
+ {
+ tty_uninit();
+ exit( 1 );
+ }
+#if __DEBUG__ == 1
+ printf( "read from DaVinci: len: %d: '%s';\n", error, rx_buf );
+#endif
+
+ if( !strncmp( " BEGIN\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "BEGIN command received. Sending CRC table...\n" );
+ }
+ else if( !strncmp( " BADCNT\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "BADCNT received. Application is too big.\n" );
+#if __INFINITY__ == 1
+ goto boot;
+#else
+ error = 1;
+ goto out;
+#endif /* __INFINITY__ */
+ }
+ else if( !strncmp( "BADADDR\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "BADADDR received. Entry point outside [0x0100...0x3800] interval.\n" );
+#if __INFINITY__ == 1
+ goto boot;
+#else
+ error = 1;
+ goto out;
+#endif /* __INFINITY__ */
+ }
+ else if( !strncmp( " BADDSP\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "BADDSP received. DSP is not active.\n" );
+#if __INFINITY__ == 1
+ goto boot;
+#else
+ error = 1;
+ goto out;
+#endif /* __INFINITY__ */
+ }
+ else
+ {
+ goto boot;
+ }
+
+ for( i = 0; i < CRC32_TABLE_SIZE; ++i )
+ {
+ sprintf( tx_buf, "%08X", (unsigned int)crc32_table[i] );
+ tty_write( tx_buf, 8 );
+ }
+
+ fprintf( stdout, "\nCRC table sent. Waiting for DONE from DaVinci...\n" );
+
+
+ /************************************************************
+ Waiting for ' DONE\0':
+ =======================
+ ************************************************************/
+ error = DaVinci_read( rx_buf, 8 );
+ if( error <= 0 )
+ {
+ tty_uninit();
+ exit( 1 );
+ }
+#if __DEBUG__ == 1
+ printf( "read from DaVinci: len: %d: '%s';\n", error, rx_buf );
+#endif
+
+ if( !strncmp( " DONE\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "DONE received. Sending BOOT MODULE file...\n" );
+ }
+ else if( !strncmp( "CORRUPT\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "CORRUPT received. Checksum8 is bad.\n" );
+#if __INFINITY__ == 1
+ goto boot;
+#else
+ error = 1;
+ goto out;
+#endif /* __INFINITY__ */
+ }
+ else
+ {
+ goto boot;
+ }
+
+ /************************************************************
+ Send the contents of PKH and BOOT MODULE files:
+ ==============================================
+ ************************************************************/
+
+ {
+ uint32_t *p = (uint32_t *)&buf[0];
+ for( i = 0; i < msize / sizeof( uint32_t ); ++i )
+ {
+ sprintf( tx_buf, "%08X", (unsigned int)*p++ );
+ tty_write( tx_buf, 8 );
+ }
+ }
+
+ fprintf( stdout, "\nBOOT MODULE CONTENTS sent. Waiting for DONE from DaVinci...\n" );
+
+ /************************************************************
+ Waiting for ' DONE\0':
+ =======================
+ ************************************************************/
+ error = DaVinci_read( rx_buf, 8 );
+ if( error <= 0 )
+ {
+ tty_uninit();
+ exit( 1 );
+ }
+#if __DEBUG__ == 1
+ printf( "read from DaVinci: len: %d: '%s';\n", error, rx_buf );
+#endif
+
+ if( !strncmp( " DONE\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "DONE received. Application file was accepted.\n" );
+ }
+ else if( !strncmp( "CORRUPT\0", rx_buf, 8 ) )
+ {
+ fprintf( stdout, "CORRUPT received. Bad CRC32 or Application Verification didn't pass.\n" );
+#if __INFINITY__ == 1
+ goto boot;
+#else
+ error = 1;
+ goto out;
+#endif /* __INFINITY__ */
+ }
+ else
+ {
+ goto boot;
+ }
+
+ fprintf( stdout, "Application transmitted successfuly.\n" );
+ error = 0;
+
+#if __INFINITY__ == 0
+out:
+#endif
+ tty_uninit();
+
+ return( error );
+}