From bb3fcfcbce90887e50110be3106d85b932b16daa Mon Sep 17 00:00:00 2001 From: Bill Cowan Date: Sat, 17 Jul 2010 16:35:33 -0400 Subject: [PATCH] Add bwio --- include/bwio.h | 39 +++++++++ include/ts7200.h | 84 ++++++++++++++++++ src/Makefile | 33 +++++++ src/bwio.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/Makefile | 31 +++++++ test/iotest.c | 21 +++++ test/iotest.h | 1 + test/iotest.map | 100 ++++++++++++++++++++++ test/orex.ld | 34 ++++++++ 9 files changed, 600 insertions(+) create mode 100644 include/bwio.h create mode 100644 include/ts7200.h create mode 100644 src/Makefile create mode 100644 src/bwio.c create mode 100644 test/Makefile create mode 100644 test/iotest.c create mode 100644 test/iotest.h create mode 100644 test/iotest.map create mode 100644 test/orex.ld diff --git a/include/bwio.h b/include/bwio.h new file mode 100644 index 0000000..8319f86 --- /dev/null +++ b/include/bwio.h @@ -0,0 +1,39 @@ +/* + * bwio.h + */ + +typedef char *va_list; + +#define __va_argsiz(t) \ + (((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) + +#define va_start(ap, pN) ((ap) = ((va_list) __builtin_next_arg(pN))) + +#define va_end(ap) ((void)0) + +#define va_arg(ap, t) \ + (((ap) = (ap) + __va_argsiz(t)), *((t*) (void*) ((ap) - __va_argsiz(t)))) + +#define COM1 0 +#define COM2 1 + +#define ON 1 +#define OFF 0 + +int bwsetfifo( int channel, int state ); + +int bwsetspeed( int channel, int speed ); + +int bwputc( int channel, char c ); + +int bwgetc( int channel ); + +int bwputx( int channel, char c ); + +int bwputstr( int channel, char *str ); + +int bwputr( int channel, unsigned int reg ); + +void bwputw( int channel, int n, char fc, char *bf ); + +void bwprintf( int channel, char *format, ... ); diff --git a/include/ts7200.h b/include/ts7200.h new file mode 100644 index 0000000..50890ad --- /dev/null +++ b/include/ts7200.h @@ -0,0 +1,84 @@ +/* + * ts7200.h - definitions describing the ts7200 peripheral registers + * + * Specific to the TS-7200 ARM evaluation board + * + */ + +#define TIMER1_BASE 0x80810000 +#define TIMER2_BASE 0x80810020 +#define TIMER3_BASE 0x80810080 + +#define LDR_OFFSET 0x00000000 // 16/32 bits, RW +#define VAL_OFFSET 0x00000004 // 16/32 bits, RO +#define CRTL_OFFSET 0x00000008 // 3 bits, RW + #define ENABLE_MASK 0x00000080 + #define MODE_MASK 0x00000040 + #define CLKSEL_MASK 0x00000008 +#define CLR_OFFSET 0x0000000c // no data, WO + + +#define LED_ADDRESS 0x80840020 + #define LED_NONE 0x0 + #define LED_GREEN 0x1 + #define LED_RED 0x2 + #define LED_BOTH 0x3 + +#define COM1 0 +#define COM2 1 + +#define IRDA_BASE 0x808b0000 +#define UART1_BASE 0x808c0000 +#define UART2_BASE 0x808d0000 + +// All the below registers for UART1 +// First nine registers (up to Ox28) for UART 2 + +#define UART_DATA_OFFSET 0x0 // low 8 bits + #define DATA_MASK 0xff +#define UART_RSR_OFFSET 0x4 // low 4 bits + #define FE_MASK 0x1 + #define PE_MASK 0x2 + #define BE_MASK 0x4 + #define OE_MASK 0x8 +#define UART_LCRH_OFFSET 0x8 // low 7 bits + #define BRK_MASK 0x1 + #define PEN_MASK 0x2 // parity enable + #define EPS_MASK 0x4 // even parity + #define STP2_MASK 0x8 // 2 stop bits + #define FEN_MASK 0x10 // fifo + #define WLEN_MASK 0x60 // word length +#define UART_LCRM_OFFSET 0xc // low 8 bits + #define BRDH_MASK 0xff // MSB of baud rate divisor +#define UART_LCRL_OFFSET 0x10 // low 8 bits + #define BRDL_MASK 0xff // LSB of baud rate divisor +#define UART_CTLR_OFFSET 0x14 // low 8 bits + #define UARTEN_MASK 0x1 + #define MSIEN_MASK 0x8 // modem status int + #define RIEN_MASK 0x10 // receive int + #define TIEN_MASK 0x20 // transmit int + #define RTIEN_MASK 0x40 // receive timeout int + #define LBEN_MASK 0x80 // loopback +#define UART_FLAG_OFFSET 0x18 // low 8 bits + #define CTS_MASK 0x1 + #define DCD_MASK 0x2 + #define DSR_MASK 0x4 + #define TXBUSY_MASK 0x8 + #define RXFE_MASK 0x10 // Receive buffer empty + #define TXFF_MASK 0x20 // Transmit buffer full + #define RXFF_MASK 0x40 // Receive buffer full + #define TXFE_MASK 0x80 // Transmit buffer empty +#define UART_INTR_OFFSET 0x1c +#define UART_DMAR_OFFSET 0x28 + +// Specific to UART1 + +#define UART_MDMCTL_OFFSET 0x100 +#define UART_MDMSTS_OFFSET 0x104 +#define UART_HDLCCTL_OFFSET 0x20c +#define UART_HDLCAMV_OFFSET 0x210 +#define UART_HDLCAM_OFFSET 0x214 +#define UART_HDLCRIB_OFFSET 0x218 +#define UART_HDLCSTS_OFFSET 0x21c + + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..2ba126a --- /dev/null +++ b/src/Makefile @@ -0,0 +1,33 @@ +# +# Makefile for busy-wait IO library +# +XCC = gcc +AS = as +AR = ar +CFLAGS = -c -fPIC -Wall -I. -I../include -mcpu=arm920t -msoft-float +# -g: include hooks for gdb +# -c: only compile +# -mcpu=arm920t: generate code for the 920t architecture +# -fpic: emit position-independent code +# -Wall: report all warnings +# -msoft-float: use software for floating point + +ASFLAGS = -mcpu=arm920t -mapcs-32 +# -mapcs-32: always create a complete stack frame + +ARFLAGS = rcs + +all: bwio.a + +bwio.s: bwio.c + $(XCC) -S $(CFLAGS) bwio.c + +bwio.o: bwio.s + $(AS) $(ASFLAGS) -o bwio.o bwio.s + +bwio.a: bwio.o + $(AR) $(ARFLAGS) $@ bwio.o + + +clean: + -rm -f *.s *.a *.o diff --git a/src/bwio.c b/src/bwio.c new file mode 100644 index 0000000..5bccaf1 --- /dev/null +++ b/src/bwio.c @@ -0,0 +1,257 @@ +/* + * bwio.c - busy-wait I/O routines for diagnosis + * + * Specific to the TS-7200 ARM evaluation board + * + */ + +#include +#include + +/* + * The UARTs are initialized by RedBoot to the following state + * 115,200 bps + * 8 bits + * no parity + * fifos enabled + */ +int bwsetfifo( int channel, int state ) { + int *line, buf; + switch( channel ) { + case COM1: + line = (int *)( UART1_BASE + UART_LCRH_OFFSET ); + break; + case COM2: + line = (int *)( UART2_BASE + UART_LCRH_OFFSET ); + break; + default: + return -1; + break; + } + buf = *line; + buf = state ? buf | FEN_MASK : buf & ~FEN_MASK; + *line = buf; + return 0; +} + +int bwsetspeed( int channel, int speed ) { + int *high, *low; + switch( channel ) { + case COM1: + high = (int *)( UART1_BASE + UART_LCRM_OFFSET ); + low = (int *)( UART1_BASE + UART_LCRL_OFFSET ); + break; + case COM2: + high = (int *)( UART2_BASE + UART_LCRM_OFFSET ); + low = (int *)( UART2_BASE + UART_LCRL_OFFSET ); + break; + default: + return -1; + break; + } + switch( speed ) { + case 115200: + *high = 0x0; + *low = 0x3; + return 0; + case 2400: + *high = 0x0; + *low = 0x90; + return 0; + default: + return -1; + } +} + +int bwputc( int channel, char c ) { + int *flags, *data; + switch( channel ) { + case COM1: + flags = (int *)( UART1_BASE + UART_FLAG_OFFSET ); + data = (int *)( UART1_BASE + UART_DATA_OFFSET ); + break; + case COM2: + flags = (int *)( UART2_BASE + UART_FLAG_OFFSET ); + data = (int *)( UART2_BASE + UART_DATA_OFFSET ); + break; + default: + return -1; + break; + } + while( ( *flags & TXFF_MASK ) ) ; + *data = c; + return 0; +} + +char c2x( char ch ) { + if ( (ch <= 9) ) return '0' + ch; + return 'a' + ch - 10; +} + +int bwputx( int channel, char c ) { + char chh, chl; + + chh = c2x( c / 16 ); + chl = c2x( c % 16 ); + bwputc( channel, chh ); + return bwputc( channel, chl ); +} + +int bwputr( int channel, unsigned int reg ) { + int byte; + char *ch = (char *) ® + + for( byte = 3; byte >= 0; byte-- ) bwputx( channel, ch[byte] ); + return bwputc( channel, ' ' ); +} + +int bwputstr( int channel, char *str ) { + while( *str ) { + if( bwputc( channel, *str ) < 0 ) return -1; + str++; + } + return 0; +} + +void bwputw( int channel, int n, char fc, char *bf ) { + char ch; + char *p = bf; + + while( *p++ && n > 0 ) n--; + while( n-- > 0 ) bwputc( channel, fc ); + while( ( ch = *bf++ ) ) bwputc( channel, ch ); +} + +int bwgetc( int channel ) { + int *flags, *data; + unsigned char c; + + switch( channel ) { + case COM1: + flags = (int *)( UART1_BASE + UART_FLAG_OFFSET ); + data = (int *)( UART1_BASE + UART_DATA_OFFSET ); + break; + case COM2: + flags = (int *)( UART2_BASE + UART_FLAG_OFFSET ); + data = (int *)( UART2_BASE + UART_DATA_OFFSET ); + break; + default: + return -1; + break; + } + while ( !( *flags & RXFF_MASK ) ) ; + c = *data; + return c; +} + +int bwa2d( char ch ) { + if( ch >= '0' && ch <= '9' ) return ch - '0'; + if( ch >= 'a' && ch <= 'f' ) return ch - 'a' + 10; + if( ch >= 'A' && ch <= 'F' ) return ch - 'A' + 10; + return -1; +} + +char bwa2i( char ch, char **src, int base, int *nump ) { + int num, digit; + char *p; + + p = *src; num = 0; + while( ( digit = bwa2d( ch ) ) >= 0 ) { + if ( digit > base ) break; + num = num*base + digit; + ch = *p++; + } + *src = p; *nump = num; + return ch; +} + +void bwui2a( unsigned int num, unsigned int base, char *bf ) { + int n = 0; + int dgt; + unsigned int d = 1; + + while( (num / d) >= base ) d *= base; + while( d != 0 ) { + dgt = num / d; + num %= d; + d /= base; + if( n || dgt > 0 || d == 0 ) { + *bf++ = dgt + ( dgt < 10 ? '0' : 'a' - 10 ); + ++n; + } + } + *bf = 0; +} + +void bwi2a( int num, char *bf ) { + if( num < 0 ) { + num = -num; + *bf++ = '-'; + } + bwui2a( num, 10, bf ); +} + +void bwformat ( int channel, char *fmt, va_list va ) { + char bf[12]; + char ch, lz; + int w; + + + while ( ( ch = *(fmt++) ) ) { + if ( ch != '%' ) + bwputc( channel, ch ); + else { + lz = 0; w = 0; + ch = *(fmt++); + switch ( ch ) { + case '0': + lz = 1; ch = *(fmt++); + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ch = bwa2i( ch, &fmt, 10, &w ); + break; + } + switch( ch ) { + case 0: return; + case 'c': + bwputc( channel, va_arg( va, char ) ); + break; + case 's': + bwputw( channel, w, 0, va_arg( va, char* ) ); + break; + case 'u': + bwui2a( va_arg( va, unsigned int ), 10, bf ); + bwputw( channel, w, lz, bf ); + break; + case 'd': + bwi2a( va_arg( va, int ), bf ); + bwputw( channel, w, lz, bf ); + break; + case 'x': + bwui2a( va_arg( va, unsigned int ), 16, bf ); + bwputw( channel, w, lz, bf ); + break; + case '%': + bwputc( channel, ch ); + break; + } + } + } +} + +void bwprintf( int channel, char *fmt, ... ) { + va_list va; + + va_start(va,fmt); + bwformat( channel, fmt, va ); + va_end(va); +} + diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..b58aa81 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,31 @@ +# +# Makefile for busy-wait IO tests +# +XCC = gcc +AS = as +LD = ld +CFLAGS = -c -fPIC -Wall -I. -I../include -mcpu=arm920t -msoft-float +# -g: include hooks for gdb +# -c: only compile +# -mcpu=arm920t: generate code for the 920t architecture +# -fpic: emit position-independent code +# -Wall: report all warnings + +ASFLAGS = -mcpu=arm920t -mapcs-32 +# -mapcs: always generate a complete stack frame + +LDFLAGS = -init main -Map iotest.map -N -T orex.ld -L/u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2 -L../lib + +all: iotest.s iotest.elf + +iotest.s: iotest.c iotest.h + $(XCC) -S $(CFLAGS) iotest.c + +iotest.o: iotest.s + $(AS) $(ASFLAGS) -o iotest.o iotest.s + +iotest.elf: iotest.o + $(LD) $(LDFLAGS) -o $@ iotest.o -lbwio -lgcc + +clean: + -rm -f iotest.elf *.s *.o iotest.map diff --git a/test/iotest.c b/test/iotest.c new file mode 100644 index 0000000..0137435 --- /dev/null +++ b/test/iotest.c @@ -0,0 +1,21 @@ + /* + * iotest.c + */ + +#include +#include + +int main( int argc, char* argv[] ) { + char str[] = "Hello\n\r"; + bwsetfifo( COM2, OFF ); + bwputstr( COM2, str ); + bwputw( COM2, 10, '*', str ); + bwprintf( COM2, "Hello world.\n\r" ); + bwprintf( COM2, "%s world%u.\n\r", "Well, hello", 23 ); + bwprintf( COM2, "%d worlds for %u person.\n\r", -23, 1 ); + bwprintf( COM2, "%x worlds for %d people.\n\r", -23, 723 ); + str[0] = bwgetc( COM2 ); + bwprintf( COM2, "%s", str ); + return 0; +} + diff --git a/test/iotest.h b/test/iotest.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/iotest.h @@ -0,0 +1 @@ + diff --git a/test/iotest.map b/test/iotest.map new file mode 100644 index 0000000..96e3932 --- /dev/null +++ b/test/iotest.map @@ -0,0 +1,100 @@ +Archive member included because of file (symbol) + +../lib/libbwio.a(bwio.o) iotest.o (bwsetfifo) +/u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_udivsi3.o) + ../lib/libbwio.a(bwio.o) (__udivsi3) +/u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_umodsi3.o) + ../lib/libbwio.a(bwio.o) (__umodsi3) +/u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_dvmd_tls.o) + /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_udivsi3.o) (__div0) + +Memory Configuration + +Name Origin Length Attributes +ram 0x0000000000000000 0x0000000002000000 +rom 0x0000000060000000 0x0000000000800000 +*default* 0x0000000000000000 0xffffffffffffffff + +Linker script and memory map + + +data 0x0000000000000000 0x0 + 0x0000000000000000 _DataStart = . + *(.data) + 0x0000000000000000 _DataEnd = . + +bss 0x0000000000000000 0x0 + 0x0000000000000000 _BssStart = . + *(.bss) + 0x0000000000000000 _BssEnd = . + +text 0x0000000000000000 0xfe4 + *(.text) + .text 0x0000000000000000 0x134 iotest.o + 0x0000000000000000 main + .text 0x0000000000000134 0xc54 ../lib/libbwio.a(bwio.o) + 0x00000000000004ac bwputr + 0x0000000000000a18 bwi2a + 0x0000000000000134 bwsetfifo + 0x0000000000000308 bwputc + 0x0000000000000768 bwa2d + 0x00000000000001fc bwsetspeed + 0x00000000000003cc c2x + 0x0000000000000810 bwa2i + 0x00000000000006b0 bwgetc + 0x00000000000008d4 bwui2a + 0x0000000000000a7c bwformat + 0x00000000000005a8 bwputw + 0x0000000000000d50 bwprintf + 0x000000000000042c bwputx + 0x000000000000052c bwputstr + .text 0x0000000000000d88 0x110 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_udivsi3.o) + 0x0000000000000d88 __udivsi3 + 0x0000000000000e80 __aeabi_uidivmod + .text 0x0000000000000e98 0xcc /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_umodsi3.o) + 0x0000000000000e98 __umodsi3 + .text 0x0000000000000f64 0x4 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_dvmd_tls.o) + 0x0000000000000f64 __aeabi_ldiv0 + 0x0000000000000f64 __div0 + 0x0000000000000f64 __aeabi_idiv0 + *(.got) + *(.got.plt) + .got.plt 0x0000000000000f68 0xc iotest.o + 0x0000000000000f68 _GLOBAL_OFFSET_TABLE_ + *(.rodata) + .rodata 0x0000000000000f74 0x70 iotest.o + *(.glue_7) + *(.glue_7t) + +.rel.dyn +LOAD iotest.o +LOAD ../lib/libbwio.a +LOAD /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a +OUTPUT(iotest.elf elf32-littlearm) + +.comment 0x0000000000000000 0x24 + .comment 0x0000000000000000 0x12 iotest.o + .comment 0x0000000000000012 0x12 ../lib/libbwio.a(bwio.o) + +.debug_line 0x0000000000000000 0x14f + .debug_line 0x0000000000000000 0x86 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_udivsi3.o) + .debug_line 0x0000000000000086 0x6f /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_umodsi3.o) + .debug_line 0x00000000000000f5 0x5a /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_dvmd_tls.o) + +.debug_info 0x0000000000000000 0x153 + .debug_info 0x0000000000000000 0x71 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_udivsi3.o) + .debug_info 0x0000000000000071 0x71 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_umodsi3.o) + .debug_info 0x00000000000000e2 0x71 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_dvmd_tls.o) + +.debug_abbrev 0x0000000000000000 0x3c + .debug_abbrev 0x0000000000000000 0x14 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_udivsi3.o) + .debug_abbrev 0x0000000000000014 0x14 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_umodsi3.o) + .debug_abbrev 0x0000000000000028 0x14 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_dvmd_tls.o) + +.debug_aranges 0x0000000000000000 0x60 + .debug_aranges + 0x0000000000000000 0x20 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_udivsi3.o) + .debug_aranges + 0x0000000000000020 0x20 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_umodsi3.o) + .debug_aranges + 0x0000000000000040 0x20 /u/wbcowan/gnuarm-4.0.2/lib/gcc/arm-elf/4.0.2/libgcc.a(_dvmd_tls.o) diff --git a/test/orex.ld b/test/orex.ld new file mode 100644 index 0000000..127dd3e --- /dev/null +++ b/test/orex.ld @@ -0,0 +1,34 @@ +ENTRY (main) + +MEMORY +{ +ram : ORIGIN = 0x00000000, LENGTH = 32M +rom : ORIGIN = 0x60000000, LENGTH = 8M +} + +SECTIONS +{ +data : /* Initialized data. */ +{ +_DataStart = . ; +*(.data) +_DataEnd = . ; +} >ram + +bss : /* Uninitialized data. */ +{ +_BssStart = . ; +*(.bss) +_BssEnd = . ; +} >ram + +text : /* The actual instructions. */ +{ +*(.text) +*(.got) +*(.got.plt) +*(.rodata) +*(.glue_7) +*(.glue_7t) +} >ram +} -- 2.11.0