# HG changeset patch # User Michael Spacefalcon # Date 1367393975 0 # Node ID 40f607bb0a2cf9845e31dcdb6453bc45dc720250 # Parent e2e80a09338e4e3a032ab9fa04a3abb298780e8b target-utils refactored diff -r e2e80a09338e -r 40f607bb0a2c .hgignore --- a/.hgignore Wed May 01 03:41:42 2013 +0000 +++ b/.hgignore Wed May 01 07:39:35 2013 +0000 @@ -7,9 +7,11 @@ ^loadtools/fc-sertool -^toolchain/binutils-2.21.1/ +^target-utils/.*/crt0\.S$ + +^toolchain/binutils-2\.21\.1/ ^toolchain/binutils-build/ -^toolchain/gcc-4.5.4/ +^toolchain/gcc-4\.5\.4/ ^toolchain/gcc-build/ -^toolchain/newlib-2.0.0/ +^toolchain/newlib-2\.0\.0/ ^toolchain/newlib-build/ diff -r e2e80a09338e -r 40f607bb0a2c loadagent/Makefile --- a/loadagent/Makefile Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -CC= arm-elf-gcc -CFLAGS= -Os -fno-builtin -LD= arm-elf-ld -OBJCOPY=arm-elf-objcopy - -OBJS= crt0.o main.o serio.o serwait.o -PRINTF= libprintf/libprintf.a - -TC_LIBS=`${CC} -print-file-name=libc.a` \ - `${CC} -print-file-name=libgcc.a` - -all: loadagent.bin loadagent.srec - -loadagent.elf: ${OBJS} ${PRINTF} loadagent.lds - ${LD} -N -T loadagent.lds -o $@ ${OBJS} ${PRINTF} \ - --start-group ${TC_LIBS} --end-group - -loadagent.bin: loadagent.elf - ${OBJCOPY} -O binary $< $@ - -loadagent.srec: loadagent.elf - ${OBJCOPY} -O srec --srec-forceS3 --srec-len=30 $< $@ - -${PRINTF}: FRC - cd libprintf; make ${MFLAGS} - -clean: - rm -f *.o *errs *core *.elf *.bin *.srec - cd libprintf; make clean - -FRC: diff -r e2e80a09338e -r 40f607bb0a2c loadagent/crt0.S --- a/loadagent/crt0.S Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -#include "halt.h" - - .text - .code 32 - .global _entry -_entry: - ldr sp, =stack_bottom -@ zero bss - ldr r0, =__bss_start - ldr r2, =__bss_end - sub r1, r2, r0 - bl bzero -@ C code entry - bl main - mov r0, #HALTCODE_MAINEXITED - .global _exit -_exit: nop -1: nop - b 1b diff -r e2e80a09338e -r 40f607bb0a2c loadagent/halt.h --- a/loadagent/halt.h Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -/* - * In some error cases in our loadagent code we have no better course - * of action available than to halt in a tight loop. We define _exit() - * to do the latter. We have defined some codes for the argument value - * that goes into R0; if you manage to hook up JTAG and get it to work, - * you might be able to see what went wrong. - */ - -#define HALTCODE_MAINEXITED 0x40 -#define HALTCODE_INVALIDUART 0x41 diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/Makefile --- a/loadagent/libnosys/Makefile Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -CC= arm-elf-gcc -CFLAGS= -Os -mcpu=arm7tdmi -marm -mno-thumb-interwork -AR= arm-elf-ar -RANLIB= arm-elf-ranlib - -OBJS= close.o fstat.o getpid.o isatty.o kill.o lseek.o open.o read.o sbrk.o \ - stat.o unlink.o write.o - -all: libnosys.a - -libnosys.a: ${OBJS} - ${AR} cru $@ ${OBJS} - ${RANLIB} $@ - -clean: - rm -f *.[oa] *errs diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/close.c --- a/loadagent/libnosys/close.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* close.c -- close a file descriptor. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include "glue.h" - -/* - * close -- We don't need to do anything, but pretend we did. - */ -int -_DEFUN (_close ,(fd), - int fd) -{ - return (0); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/fstat.c --- a/loadagent/libnosys/fstat.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* fstat.c -- get status of a file. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include -#include "glue.h" - -/* - * fstat -- Since we have no file system, we just return an error. - */ -int -_DEFUN (_fstat, (fd, buf), - int fd _AND - struct stat *buf) -{ - buf->st_mode = S_IFCHR; /* Always pretend to be a tty */ - buf->st_blksize = 0; - - return (0); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/getpid.c --- a/loadagent/libnosys/getpid.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* getpid.c -- get the current process id. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include "glue.h" - -/* - * getpid -- only one process, so just return 1. - */ -int -_DEFUN (_getpid, (), - ) -{ - return __MYPID; -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/glue.h --- a/loadagent/libnosys/glue.h Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* glue.h -- common definitions for "glue" fucntions. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include <_ansi.h> - -#ifndef NULL -# define NULL 0 -#endif - -#ifdef __NO_UNDERSCORE__ -# define _end end -# define _exit exit -#endif - -extern char _end[]; /* _end is set in the linker command file */ - -/* only one prcess support, as this is OS dependant */ -#define __MYPID 1 - - diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/isatty.c --- a/loadagent/libnosys/isatty.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* isatty.c -- chek the terminal device. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include "glue.h" - -/* - * isatty -- returns 1 if connected to a terminal device, - * returns 0 if not. Since we're hooked up to a - * serial port, we'll say yes _AND return a 1. - */ -int -_DEFUN (_isatty, (fd), - int fd) -{ - return (1); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/kill.c --- a/loadagent/libnosys/kill.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* kill.c -- remove a process. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include "glue.h" - -/* - * kill -- go out via exit... - */ -int -_DEFUN (_kill, (pid, sig), - int pid _AND - int sig) -{ - if(pid == __MYPID) - _exit(sig); - return 0; -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/lseek.c --- a/loadagent/libnosys/lseek.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* lseek.c -- move read/write pointer. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include -#include -#include "glue.h" - -/* - * lseek -- Since a serial port is non-seekable, we return an error. - */ -off_t -_DEFUN (_lseek, (fd, offset, whence), - int fd _AND - off_t offset _AND - int whence) -{ - errno = ESPIPE; - return ((off_t)-1); -} - diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/open.c --- a/loadagent/libnosys/open.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* open.c -- open a file. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include -#include "glue.h" - -/* - * open -- open a file descriptor. We don't have a filesystem, so - * we return an error. - */ -int -_DEFUN (_open, (buf, flags, mode), - const char *buf _AND - int flags _AND - int mode) -{ - errno = EIO; - return (-1); -} - diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/read.c --- a/loadagent/libnosys/read.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* read.c -- read bytes from a input device. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include "glue.h" - -/* - * read -- read bytes from the serial port. Ignore fd, since - * we only have stdin. - * - * In the present version changed to always return EOF indication. - */ -int -_DEFUN (_read, (fd, buf, nbytes), - int fd _AND - char *buf _AND - int nbytes) -{ - return (0); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/sbrk.c --- a/loadagent/libnosys/sbrk.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* sbrk.c -- allocate memory dynamically. - * - * Copyright (c) 1995,1996 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include -#include "glue.h" - -/* just in case, most boards have at least some memory */ -#ifndef RAMSIZE -# define RAMSIZE (caddr_t)0x100000 -#endif - -char *heap_ptr; - -/* - * sbrk -- changes heap size size. Get nbytes more - * RAM. We just increment a pointer in what's - * left of memory on the board. - */ -char * -_sbrk (nbytes) - int nbytes; -{ - char *base; - - if (!heap_ptr) - heap_ptr = (char *)&_end; - base = heap_ptr; - heap_ptr += nbytes; - - return base; -/* FIXME: We really want to make sure we don't run out of RAM, but this - * isn't very portable. - */ -#if 0 - if ((RAMSIZE - heap_ptr - nbytes) >= 0) { - base = heap_ptr; - heap_ptr += nbytes; - return (base); - } else { - errno = ENOMEM; - return ((char *)-1); - } -#endif -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/stat.c --- a/loadagent/libnosys/stat.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* stat.c -- Get the status of a file. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include -#include -#include "glue.h" - -/* - * stat -- Since we have no file system, we just return an error. - */ -int -_DEFUN (_stat, (path, buf), - const char *path _AND - struct stat *buf) -{ - errno = EIO; - return (-1); -} - diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/unlink.c --- a/loadagent/libnosys/unlink.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* unlink.c -- remove a file. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include -#include "glue.h" - -/* - * unlink -- since we have no file system, - * we just return an error. - */ -int -_DEFUN (_unlink, (path), - char * path) -{ - errno = EIO; - return (-1); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libnosys/write.c --- a/loadagent/libnosys/write.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* write.c -- write bytes to an output device. - * - * Copyright (c) 1995 Cygnus Support - * - * The authors hereby grant permission to use, copy, modify, distribute, - * and license this software and its documentation for any purpose, provided - * that existing copyright notices are retained in all copies and that this - * notice is included verbatim in any distributions. No written agreement, - * license, or royalty fee is required for any of the authorized uses. - * Modifications to this software may be copyrighted by their authors - * and need not follow the licensing terms described here, provided that - * the new terms are clearly indicated on the first page of each file where - * they apply. - */ -#include "glue.h" - -extern int _EXFUN (serial_out, (char x)); - -/* - * write -- write bytes to the serial port. Ignore fd, since - * stdout and stderr are the same. Since we have no filesystem, - * open will only return an error. - */ -int -_DEFUN (_write, (fd, buf, nbytes), - int fd _AND - char *buf _AND - int nbytes) -{ - int i; - - for (i = 0; i < nbytes; i++) { - if (*(buf + i) == '\n') { - serial_out ('\r'); - } - serial_out (*(buf + i)); - } - return (nbytes); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/Makefile --- a/loadagent/libprintf/Makefile Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -CC= arm-elf-gcc -CFLAGS= -Os -fno-builtin -AR= arm-elf-ar -RANLIB= arm-elf-ranlib - -OBJS= doprnt.o printf.o putchar.o puts.o sprintf.o sprintf_putchar.o \ - vprintf.o vsprintf.o - -all: libprintf.a - -libprintf.a: ${OBJS} - ${AR} cru $@ ${OBJS} - ${RANLIB} $@ - -clean: - rm -f *.[oa] *errs diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/README --- a/loadagent/libprintf/README Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -The present libprintf is a very light printf implementation that is well-suited -for simple bare-metal programs like loadagent; in the present case it overrides -the much heavier printf implementation in newlib. Programs like the present -loadagent only need printf in order to scribble on the serial console port, -and the most sensible implementation is to have the "character output" function -from the guts of printf point directly to the physical UART output routine, or -a trivial wrapper that turns \n into \r\n. In contrast, newlib's version would -pull in the complete FILE table infrastructure and malloc etc - maybe OK for -more complex embedded programs that use those facilities for other things under -a bona fide RTOS, but it would be disgusting to pull that stuff in for a -minimal program like ours. - -The present printf implementation has been used earlier by the same author -(Michael Spacefalcon) in the StarMON family of PowerPC bootloaders, and in my -MC68x302-based SDSL CPE devices (Hack-o-Rocket and OSDCU). diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/doprnt.c --- a/loadagent/libprintf/doprnt.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,300 +0,0 @@ -/* the guts of printf - this implementation came from 4.3BSD-Tahoe */ - -#include -#include -#include - -#define PUTC(ch) ((*outfunc)((ch), outfunc_param)) - -#define ARG() \ - _ulong = flags&LONGINT ? va_arg(argp, long) : va_arg(argp, int); - -#define BUF 256 - -#define todigit(c) ((c) - '0') -#define tochar(n) ((n) + '0') - -/* have to deal with the negative buffer count kludge */ -#define NEGATIVE_COUNT_KLUDGE - -#define LONGINT 0x01 /* long integer */ -#define LONGDBL 0x02 /* long double; unimplemented */ -#define SHORTINT 0x04 /* short integer */ -#define ALT 0x08 /* alternate form */ -#define LADJUST 0x10 /* left adjustment */ -#define ZEROPAD 0x20 /* zero (as opposed to blank) pad */ -#define HEXPREFIX 0x40 /* add 0x or 0X prefix */ - -_doprnt(fmt0, argp, outfunc, outfunc_param) - u_char *fmt0; - va_list argp; - void (*outfunc)(); - void *outfunc_param; -{ - register u_char *fmt; /* format string */ - register int ch; /* character from fmt */ - register int cnt; /* return value accumulator */ - register int n; /* random handy integer */ - register char *t; /* buffer pointer */ - u_long _ulong; /* integer arguments %[diouxX] */ - int base; /* base for [diouxX] conversion */ - int dprec; /* decimal precision in [diouxX] */ - int fieldsz; /* field size expanded by sign, etc */ - int flags; /* flags as above */ - int prec; /* precision from format (%.3d), or -1 */ - int realsz; /* field size expanded by decimal precision */ - int size; /* size of converted field or string */ - int width; /* width from format (%8d), or 0 */ - char sign; /* sign prefix (' ', '+', '-', or \0) */ - char softsign; /* temporary negative sign for floats */ - char *digs; /* digits for [diouxX] conversion */ - char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ - - fmt = fmt0; - digs = "0123456789abcdef"; - for (cnt = 0;; ++fmt) { - for (; (ch = *fmt) && ch != '%'; ++cnt, ++fmt) - PUTC(ch); - if (!ch) - return (cnt); - - flags = 0; dprec = 0; width = 0; - prec = -1; - sign = '\0'; - -rflag: switch (*++fmt) { - case ' ': - /* - * ``If the space and + flags both appear, the space - * flag will be ignored.'' - * -- ANSI X3J11 - */ - if (!sign) - sign = ' '; - goto rflag; - case '#': - flags |= ALT; - goto rflag; - case '*': - /* - * ``A negative field width argument is taken as a - * - flag followed by a positive field width.'' - * -- ANSI X3J11 - * They don't exclude field widths read from args. - */ - if ((width = va_arg(argp, int)) >= 0) - goto rflag; - width = -width; - /* FALLTHROUGH */ - case '-': - flags |= LADJUST; - goto rflag; - case '+': - sign = '+'; - goto rflag; - case '.': - if (*++fmt == '*') - n = va_arg(argp, int); - else { - n = 0; - while (isascii(*fmt) && isdigit(*fmt)) - n = 10 * n + todigit(*fmt++); - --fmt; - } - prec = n < 0 ? -1 : n; - goto rflag; - case '0': - /* - * ``Note that 0 is taken as a flag, not as the - * beginning of a field width.'' - * -- ANSI X3J11 - */ - flags |= ZEROPAD; - goto rflag; - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = 0; - do { - n = 10 * n + todigit(*fmt); - } while (isascii(*++fmt) && isdigit(*fmt)); - width = n; - --fmt; - goto rflag; - case 'L': - flags |= LONGDBL; - goto rflag; - case 'h': - flags |= SHORTINT; - goto rflag; - case 'l': - flags |= LONGINT; - goto rflag; - case 'c': - *(t = buf) = va_arg(argp, int); - size = 1; - sign = '\0'; - goto pforw; - case 'D': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'd': - case 'i': - ARG(); - if ((long)_ulong < 0) { - _ulong = -_ulong; - sign = '-'; - } - base = 10; - goto number; - case 'n': - if (flags & LONGINT) - *va_arg(argp, long *) = cnt; - else if (flags & SHORTINT) - *va_arg(argp, short *) = cnt; - else - *va_arg(argp, int *) = cnt; - break; - case 'O': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'o': - ARG(); - base = 8; - goto nosign; - case 'p': - /* - * ``The argument shall be a pointer to void. The - * value of the pointer is converted to a sequence - * of printable characters, in an implementation- - * defined manner.'' - * -- ANSI X3J11 - */ - /* NOSTRICT */ - _ulong = (u_long)va_arg(argp, void *); - base = 16; - goto nosign; - case 's': - if (!(t = va_arg(argp, char *))) - t = "(null)"; - if (prec >= 0) { - /* - * can't use strlen; can only look for the - * NUL in the first `prec' characters, and - * strlen() will go further. - */ - char *p; - - for (p = t, size = 0; size < prec; p++, size++) - if (*p == '\0') - break; - } else - size = strlen(t); - sign = '\0'; - goto pforw; - case 'U': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'u': - ARG(); - base = 10; - goto nosign; - case 'X': - digs = "0123456789ABCDEF"; - /* FALLTHROUGH */ - case 'x': - ARG(); - base = 16; - /* leading 0x/X only if non-zero */ - if (flags & ALT && _ulong != 0) - flags |= HEXPREFIX; - - /* unsigned conversions */ -nosign: sign = '\0'; - /* - * ``... diouXx conversions ... if a precision is - * specified, the 0 flag will be ignored.'' - * -- ANSI X3J11 - */ -number: if ((dprec = prec) >= 0) - flags &= ~ZEROPAD; - - /* - * ``The result of converting a zero value with an - * explicit precision of zero is no characters.'' - * -- ANSI X3J11 - */ - t = buf + BUF; - if (_ulong != 0 || prec != 0) { - do { - *--t = digs[_ulong % base]; - _ulong /= base; - } while (_ulong); - digs = "0123456789abcdef"; - if (flags & ALT && base == 8 && *t != '0') - *--t = '0'; /* octal leading 0 */ - } - size = buf + BUF - t; - -pforw: - /* - * All reasonable formats wind up here. At this point, - * `t' points to a string which (if not flags&LADJUST) - * should be padded out to `width' places. If - * flags&ZEROPAD, it should first be prefixed by any - * sign or other prefix; otherwise, it should be blank - * padded before the prefix is emitted. After any - * left-hand padding and prefixing, emit zeroes - * required by a decimal [diouxX] precision, then print - * the string proper, then emit zeroes required by any - * leftover floating precision; finally, if LADJUST, - * pad with blanks. - */ - - /* - * compute actual size, so we know how much to pad - * fieldsz excludes decimal prec; realsz includes it - */ - fieldsz = size; - if (sign) - fieldsz++; - if (flags & HEXPREFIX) - fieldsz += 2; - realsz = dprec > fieldsz ? dprec : fieldsz; - - /* right-adjusting blank padding */ - if ((flags & (LADJUST|ZEROPAD)) == 0 && width) - for (n = realsz; n < width; n++) - PUTC(' '); - /* prefix */ - if (sign) - PUTC(sign); - if (flags & HEXPREFIX) { - PUTC('0'); - PUTC((char)*fmt); - } - /* right-adjusting zero padding */ - if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) - for (n = realsz; n < width; n++) - PUTC('0'); - /* leading zeroes from decimal precision */ - for (n = fieldsz; n < dprec; n++) - PUTC('0'); - - for (n = size; --n >= 0; ) - PUTC(*t++); - /* left-adjusting padding (always blank) */ - if (flags & LADJUST) - for (n = realsz; n < width; n++) - PUTC(' '); - /* finally, adjust cnt */ - cnt += width > realsz ? width : realsz; - break; - case '\0': /* "%?" prints ?, unless ? is NULL */ - return (cnt); - default: - PUTC((char)*fmt); - cnt++; - } - } - /* NOTREACHED */ -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/printf.c --- a/loadagent/libprintf/printf.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -#include - -extern void putchar(); - -int -printf(char *fmt, ...) -{ - va_list ap; - int len; - - va_start(ap, fmt); - len = _doprnt(fmt, ap, &putchar); - va_end(ap); - return(len); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/putchar.c --- a/loadagent/libprintf/putchar.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -extern void serial_out(); - -void -putchar(ch) -{ - if (ch == '\n') - serial_out('\r'); - serial_out(ch); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/puts.c --- a/loadagent/libprintf/puts.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -void -puts(s) - char *s; -{ - int c; - - while (c = *s++) - putchar(c); - putchar('\n'); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/sprintf.c --- a/loadagent/libprintf/sprintf.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -#include - -extern void _sprintf_putchar(); - -int -sprintf(char *strdest, char *fmt, ...) -{ - va_list ap; - char *strptr; - int len; - - strptr = strdest; - va_start(ap, fmt); - len = _doprnt(fmt, ap, &_sprintf_putchar, &strptr); - va_end(ap); - *strptr = '\0'; - return(len); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/sprintf_putchar.c --- a/loadagent/libprintf/sprintf_putchar.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -void -_sprintf_putchar(ch, pp) - int ch; - char **pp; -{ - **pp = ch; - (*pp)++; -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/vprintf.c --- a/loadagent/libprintf/vprintf.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -#include - -extern void putchar(); - -int -vprintf(fmt, ap) - char *fmt; - va_list ap; -{ - return(_doprnt(fmt, ap, &putchar)); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/libprintf/vsprintf.c --- a/loadagent/libprintf/vsprintf.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -#include - -extern void _sprintf_putchar(); - -int -vsprintf(str, fmt, ap) - va_list ap; - char *str, *fmt; -{ - char *strptr; - int len; - - strptr = str; - len = _doprnt(fmt, ap, &_sprintf_putchar, &strptr); - *strptr = '\0'; - return(len); -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/loadagent.lds --- a/loadagent/loadagent.lds Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH(arm) -ENTRY(_entry) -SECTIONS -{ - /* code */ - . = 0x800750; - .text : { - /* regular code */ - *(.text*) - /* gcc voodoo */ - *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) - . = ALIGN(4); - } - - /* read-only data */ - . = ALIGN(4); - .rodata : { - *(.rodata*) - } - - /* initialized data */ - . = ALIGN(4); - .data : { - *(.data) - } - PROVIDE(edata = .); - - /* uninitialized data */ - .bss (NOLOAD) : { - . = ALIGN(4); - __bss_start = .; - *(.bss) - } - . = ALIGN(4); - __bss_end = .; - /* end of image */ - _end = .; - PROVIDE(end = .); -} - -/* a few absolute definitions */ -rom_vars = 0x800518; -stack_bottom = 0x83FFFC; diff -r e2e80a09338e -r 40f607bb0a2c loadagent/main.c --- a/loadagent/main.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * FreeCalypso loadagent main() function lives here - */ - -#include "types.h" -#include "romvars.h" -#include "ns16550.h" -#include "halt.h" - -#include - -extern struct boot_rom_vars rom_vars; - -struct ns16550_regs *uart_base; -char *uart_name; - -uart_select_init() -{ - switch (rom_vars.uart_id) { - case 0: - uart_base = (struct ns16550_regs *) 0xFFFF5800; - uart_name = "MODEM"; - break; - case 1: - uart_base = (struct ns16550_regs *) 0xFFFF5000; - uart_name = "IrDA"; - break; - default: - _exit(HALTCODE_INVALIDUART); - } -} - -main() -{ - uart_select_init(); - printf("FreeCalypso loadagent running\n"); - printf("Loaded via UART %d (%s) at baud rate #%d\n", rom_vars.uart_id, - uart_name, rom_vars.baud_rate_code); - printf("TCXO clock input autodetected to be %d MHz\n", - rom_vars.clktcxo_13mhz ? 13 : 26); - /* interactive command mode to be implemented */ - while (1) - ; -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/ns16550.h --- a/loadagent/ns16550.h Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -#ifndef __NS16550_H -#define __NS16550_H - -/* NS16550 registers */ -#define NS16550_RBR 0 -#define NS16550_THR 0 -#define NS16550_IER 1 -#define NS16550_IIR 2 -#define NS16550_FCR 2 -#define NS16550_LCR 3 -#define NS16550_MCR 4 -#define NS16550_LSR 5 -#define NS16550_MSR 6 -#define NS16550_SCR 7 -#define NS16550_DLL 0 -#define NS16550_DLM 1 - -#ifndef __ASSEMBLER__ -#include "types.h" - -struct ns16550_regs { - u8 datareg; - u8 ier; - u8 iir_fcr; - u8 lcr; - u8 mcr; - u8 lsr; - u8 msr; - u8 scr; -}; -#endif - -/* IER bits */ -#define NS16550_IER_EDSSI 0x08 -#define NS16550_IER_ELSI 0x04 -#define NS16550_IER_ETBEI 0x02 -#define NS16550_IER_ERBFI 0x01 - -/* IIR bits */ -#define NS16550_IIR_FIFOEN 0xC0 -#define NS16550_IIR_INTID 0x0E -#define NS16550_IIR_INT_RLS 0x06 -#define NS16550_IIR_INT_RDA 0x04 -#define NS16550_IIR_INT_CTO 0x0C -#define NS16550_IIR_INT_THRE 0x02 -#define NS16550_IIR_INT_MODEM 0x00 -#define NS16550_IIR_INTPEND 0x01 - -/* FCR bits */ - -#define NS16550_FCR_RXTR 0xC0 -#define NS16550_FCR_RXTR_1 0x00 -#define NS16550_FCR_RXTR_4 0x40 -#define NS16550_FCR_RXTR_8 0x80 -#define NS16550_FCR_RXTR_14 0xC0 -#define NS16550_FCR_DMAMODE 0x08 -#define NS16550_FCR_TXRST 0x04 -#define NS16550_FCR_RXRST 0x02 -#define NS16550_FCR_FIFOEN 0x01 - -/* LCR bits */ -#define NS16550_LCR_DLAB 0x80 -#define NS16550_LCR_BREAK 0x40 -#define NS16550_LCR_STICK 0x20 -#define NS16550_LCR_EPS 0x10 -#define NS16550_LCR_PEN 0x08 -#define NS16550_LCR_STB 0x04 -#define NS16550_LCR_WLS 0x03 -#define NS16550_LCR_WLS_5 0x00 -#define NS16550_LCR_WLS_6 0x01 -#define NS16550_LCR_WLS_7 0x02 -#define NS16550_LCR_WLS_8 0x03 - -/* MCR bits */ -#define NS16550_MCR_LOOP 0x10 -#define NS16550_MCR_OUT2 0x08 -#define NS16550_MCR_OUT1 0x04 -#define NS16550_MCR_RTS 0x02 -#define NS16550_MCR_DTR 0x01 - -/* LSR bits */ -#define NS16550_LSR_ERR 0x80 -#define NS16550_LSR_TEMP 0x40 -#define NS16550_LSR_THRE 0x20 -#define NS16550_LSR_BI 0x10 -#define NS16550_LSR_FE 0x08 -#define NS16550_LSR_PE 0x04 -#define NS16550_LSR_OE 0x02 -#define NS16550_LSR_DR 0x01 - -/* MSR bits */ -#define NS16550_MSR_DCD 0x80 -#define NS16550_MSR_RI 0x40 -#define NS16550_MSR_DSR 0x20 -#define NS16550_MSR_CTS 0x10 -#define NS16550_MSR_DDCD 0x08 -#define NS16550_MSR_TERI 0x04 -#define NS16550_MSR_DDSR 0x02 -#define NS16550_MSR_DCTS 0x01 - -#endif /* __NS16550_H */ diff -r e2e80a09338e -r 40f607bb0a2c loadagent/romvars.h --- a/loadagent/romvars.h Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Our loadagent will always be loaded into Calypso targets by the on-chip - * boot ROM operating in the UART download mode. The lowest IRAM address - * at which we can load our code is 0x800750; somewhat lower at 0x800518 - * the boot ROM downloader has a few variables which may have been intended - * to be private to the boot ROM, but which are useful to us. For example, - * by looking at these variables, we can see which of the two UARTs was - * used to feed our code to the boot ROM, and use the same UART for - * subsequent communication - without building multiple versions of our - * loadagent or resorting to other ugliness. - * - * This header file defines the layout of the IRAM structure in question, - * based on the disassembly of the boot ROM. - */ - -#ifndef __ROMVARS_H -#define __ROMVARS_H - -#include "types.h" - -struct boot_rom_vars { - u8 baud_rate_code; - u8 pad1[3]; - u32 uart_timeout; - u8 uart_id; - u8 pll_config; - u16 cs_ws_config; - u8 clktcxo_13mhz; - u8 rhea_cntl; - u16 chksum_cmd; - u16 chksum_accum; - u16 pad2; - u32 branch_addr; -}; - -#endif /* include guard */ diff -r e2e80a09338e -r 40f607bb0a2c loadagent/serio.S --- a/loadagent/serio.S Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -#include "ns16550.h" - -@ this module implements the elementary serial I/O operations - - .text - .code 32 - .global serial_out -serial_out: - ldr r1, =uart_base - ldr r2, [r1] -1: ldrb r3, [r2, #NS16550_LSR] - tst r3, #NS16550_LSR_THRE - beq 1b - strb r0, [r2, #NS16550_THR] - bx lr - - .global serial_in_poll -serial_in_poll: - ldr r1, =uart_base - ldr r2, [r1] - ldrb r3, [r2, #NS16550_LSR] - tst r3, #NS16550_LSR_DR - mvneq r0, #1 - bxeq lr - ldrb r0, [r2, #NS16550_RBR] - bx lr diff -r e2e80a09338e -r 40f607bb0a2c loadagent/serwait.c --- a/loadagent/serwait.c Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -/* this C module is a wrapper around serio.S */ -/* we implement serial_in_wait() as a C wrapper around serial_in_poll() */ - -extern int serial_in_poll(); - -int serial_in_wait() -{ - register int c; - - do - c = serial_in_poll(); - while (c < 0); - return c; -} diff -r e2e80a09338e -r 40f607bb0a2c loadagent/types.h --- a/loadagent/types.h Wed May 01 03:41:42 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -/* - * I personally like the u8/u16/u32 types, but I don't see them - * being defined in any of the headers provided by newlib. - * So we'll define them ourselves. - */ - -#ifndef __OUR_OWN_TYPES_H -#define __OUR_OWN_TYPES_H - -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; - -typedef signed char s8; -typedef signed short s16; -typedef signed int s32; - -#endif /* include guard */ diff -r e2e80a09338e -r 40f607bb0a2c target-utils/env/crt0.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/env/crt0.S Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,19 @@ +#include "halt.h" + + .text + .code 32 + .global _entry +_entry: + ldr sp, =stack_bottom +@ zero bss + ldr r0, =__bss_start + ldr r2, =__bss_end + sub r1, r2, r0 + bl bzero +@ C code entry + bl main + mov r0, #HALTCODE_MAINEXITED + .global _exit +_exit: nop +1: nop + b 1b diff -r e2e80a09338e -r 40f607bb0a2c target-utils/env/iram.lds --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/env/iram.lds Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,54 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_entry) +SECTIONS +{ + /* code */ + . = 0x800750; + .text : { + /* regular code */ + *(.text*) + /* gcc voodoo */ + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) + . = ALIGN(4); + } + + /* read-only data */ + . = ALIGN(4); + .rodata : { + *(.rodata*) + } + + /* initialized data */ + . = ALIGN(4); + .data : { + *(.data) + } + PROVIDE(edata = .); + + /* uninitialized data */ + .bss (NOLOAD) : { + . = ALIGN(4); + __bss_start = .; + *(.bss) + } + . = ALIGN(4); + __bss_end = .; + /* end of image */ + _end = .; + PROVIDE(end = .); +} + +/* a few absolute definitions */ +rom_vars = 0x800518; +/* stack_bottom = 0x83FFFC; */ + +/* + * stack_bottom will be set via the --defsym option to ld. + * Some programs have minimal IRAM requirements, so it would make more + * sense to set stack_bottom to 0x83FFFC, don't use the upper half of + * IRAM for anything, and make that program portable to Calypso Lite + * devices. But for some other programs we might have some use for + * the larger IRAM of our full Calypso devices, in which case we would + * want to set stack_bottom to 0x87FFFC instead. + */ diff -r e2e80a09338e -r 40f607bb0a2c target-utils/helloapp/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/helloapp/Makefile Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,30 @@ +CC= arm-elf-gcc +CFLAGS= -Os -fno-builtin +CPPFLAGS=-I../include +LD= arm-elf-ld +OBJCOPY=arm-elf-objcopy + +PROG= helloapp +OBJS= crt0.o main.o mygetchar.o +LIBS= ../libprintf/libprintf.a ../libcommon/libcommon.a +LDS= ../env/iram.lds + +TC_LIBS=`${CC} -print-file-name=libc.a` \ + `${CC} -print-file-name=libgcc.a` + +all: ${PROG}.srec + +crt0.S: ../env/crt0.S + ln -s $< . + +${PROG}.elf: ${OBJS} ${LIBS} ${LDS} + ${LD} -N --defsym stack_bottom=0x83FFFC -T ${LDS} -o $@ ${OBJS} ${LIBS}\ + --start-group ${TC_LIBS} --end-group + +${PROG}.srec: ${PROG}.elf + ${OBJCOPY} -O srec --srec-forceS3 --srec-len=30 $< $@ + +clean: + rm -f *.o *errs *core *.elf *.bin *.srec crt0.S + +FRC: diff -r e2e80a09338e -r 40f607bb0a2c target-utils/helloapp/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/helloapp/main.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,25 @@ +/* + * FreeCalypso loadagent main() function lives here + */ + +#include "types.h" +#include "romvars.h" + +#include + +extern struct boot_rom_vars rom_vars; + +extern char *uart_name; + +main() +{ + uart_select_init(); + printf("FreeCalypso loadagent running\n"); + printf("Loaded via UART %d (%s) at baud rate #%d\n", rom_vars.uart_id, + uart_name, rom_vars.baud_rate_code); + printf("TCXO clock input autodetected to be %d MHz\n", + rom_vars.clktcxo_13mhz ? 13 : 26); + /* interactive command mode to be implemented */ + while (1) + ; +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/helloapp/mygetchar.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/helloapp/mygetchar.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,21 @@ +/* + * The interactive command entry (editing) function in libcommon + * will call mygetchar() for its character input. It is supposed + * to be a blocking wait for input, but in some programs other + * processing can be done while waiting - for example, check for + * keypad presses as well. This is the basic version which waits + * for serial input and nothing else. + */ + +extern int serial_in_poll(); + +int +mygetchar() +{ + register int c; + + do + c = serial_in_poll(); + while (c < 0); + return c; +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/include/halt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/include/halt.h Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,10 @@ +/* + * In some error cases in our loadagent code we have no better course + * of action available than to halt in a tight loop. We define _exit() + * to do the latter. We have defined some codes for the argument value + * that goes into R0; if you manage to hook up JTAG and get it to work, + * you might be able to see what went wrong. + */ + +#define HALTCODE_MAINEXITED 0x40 +#define HALTCODE_INVALIDUART 0x41 diff -r e2e80a09338e -r 40f607bb0a2c target-utils/include/ns16550.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/include/ns16550.h Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,101 @@ +#ifndef __NS16550_H +#define __NS16550_H + +/* NS16550 registers */ +#define NS16550_RBR 0 +#define NS16550_THR 0 +#define NS16550_IER 1 +#define NS16550_IIR 2 +#define NS16550_FCR 2 +#define NS16550_LCR 3 +#define NS16550_MCR 4 +#define NS16550_LSR 5 +#define NS16550_MSR 6 +#define NS16550_SCR 7 +#define NS16550_DLL 0 +#define NS16550_DLM 1 + +#ifndef __ASSEMBLER__ +#include "types.h" + +struct ns16550_regs { + u8 datareg; + u8 ier; + u8 iir_fcr; + u8 lcr; + u8 mcr; + u8 lsr; + u8 msr; + u8 scr; +}; +#endif + +/* IER bits */ +#define NS16550_IER_EDSSI 0x08 +#define NS16550_IER_ELSI 0x04 +#define NS16550_IER_ETBEI 0x02 +#define NS16550_IER_ERBFI 0x01 + +/* IIR bits */ +#define NS16550_IIR_FIFOEN 0xC0 +#define NS16550_IIR_INTID 0x0E +#define NS16550_IIR_INT_RLS 0x06 +#define NS16550_IIR_INT_RDA 0x04 +#define NS16550_IIR_INT_CTO 0x0C +#define NS16550_IIR_INT_THRE 0x02 +#define NS16550_IIR_INT_MODEM 0x00 +#define NS16550_IIR_INTPEND 0x01 + +/* FCR bits */ + +#define NS16550_FCR_RXTR 0xC0 +#define NS16550_FCR_RXTR_1 0x00 +#define NS16550_FCR_RXTR_4 0x40 +#define NS16550_FCR_RXTR_8 0x80 +#define NS16550_FCR_RXTR_14 0xC0 +#define NS16550_FCR_DMAMODE 0x08 +#define NS16550_FCR_TXRST 0x04 +#define NS16550_FCR_RXRST 0x02 +#define NS16550_FCR_FIFOEN 0x01 + +/* LCR bits */ +#define NS16550_LCR_DLAB 0x80 +#define NS16550_LCR_BREAK 0x40 +#define NS16550_LCR_STICK 0x20 +#define NS16550_LCR_EPS 0x10 +#define NS16550_LCR_PEN 0x08 +#define NS16550_LCR_STB 0x04 +#define NS16550_LCR_WLS 0x03 +#define NS16550_LCR_WLS_5 0x00 +#define NS16550_LCR_WLS_6 0x01 +#define NS16550_LCR_WLS_7 0x02 +#define NS16550_LCR_WLS_8 0x03 + +/* MCR bits */ +#define NS16550_MCR_LOOP 0x10 +#define NS16550_MCR_OUT2 0x08 +#define NS16550_MCR_OUT1 0x04 +#define NS16550_MCR_RTS 0x02 +#define NS16550_MCR_DTR 0x01 + +/* LSR bits */ +#define NS16550_LSR_ERR 0x80 +#define NS16550_LSR_TEMP 0x40 +#define NS16550_LSR_THRE 0x20 +#define NS16550_LSR_BI 0x10 +#define NS16550_LSR_FE 0x08 +#define NS16550_LSR_PE 0x04 +#define NS16550_LSR_OE 0x02 +#define NS16550_LSR_DR 0x01 + +/* MSR bits */ +#define NS16550_MSR_DCD 0x80 +#define NS16550_MSR_RI 0x40 +#define NS16550_MSR_DSR 0x20 +#define NS16550_MSR_CTS 0x10 +#define NS16550_MSR_DDCD 0x08 +#define NS16550_MSR_TERI 0x04 +#define NS16550_MSR_DDSR 0x02 +#define NS16550_MSR_DCTS 0x01 + +#endif /* __NS16550_H */ diff -r e2e80a09338e -r 40f607bb0a2c target-utils/include/romvars.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/include/romvars.h Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,36 @@ +/* + * Our loadagent will always be loaded into Calypso targets by the on-chip + * boot ROM operating in the UART download mode. The lowest IRAM address + * at which we can load our code is 0x800750; somewhat lower at 0x800518 + * the boot ROM downloader has a few variables which may have been intended + * to be private to the boot ROM, but which are useful to us. For example, + * by looking at these variables, we can see which of the two UARTs was + * used to feed our code to the boot ROM, and use the same UART for + * subsequent communication - without building multiple versions of our + * loadagent or resorting to other ugliness. + * + * This header file defines the layout of the IRAM structure in question, + * based on the disassembly of the boot ROM. + */ + +#ifndef __ROMVARS_H +#define __ROMVARS_H + +#include "types.h" + +struct boot_rom_vars { + u8 baud_rate_code; + u8 pad1[3]; + u32 uart_timeout; + u8 uart_id; + u8 pll_config; + u16 cs_ws_config; + u8 clktcxo_13mhz; + u8 rhea_cntl; + u16 chksum_cmd; + u16 chksum_accum; + u16 pad2; + u32 branch_addr; +}; + +#endif /* include guard */ diff -r e2e80a09338e -r 40f607bb0a2c target-utils/include/types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/include/types.h Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,18 @@ +/* + * I personally like the u8/u16/u32 types, but I don't see them + * being defined in any of the headers provided by newlib. + * So we'll define them ourselves. + */ + +#ifndef __OUR_OWN_TYPES_H +#define __OUR_OWN_TYPES_H + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; + +#endif /* include guard */ diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libcommon/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libcommon/Makefile Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,16 @@ +CC= arm-elf-gcc +CFLAGS= -Os -fno-builtin +CPPFLAGS=-I../include +AR= arm-elf-ar +RANLIB= arm-elf-ranlib + +OBJS= serio.o uartsel.o + +all: libcommon.a + +libcommon.a: ${OBJS} + ${AR} cru $@ ${OBJS} + ${RANLIB} $@ + +clean: + rm -f *.[oa] *errs diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libcommon/serio.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libcommon/serio.S Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,26 @@ +#include "ns16550.h" + +@ this module implements the elementary serial I/O operations + + .text + .code 32 + .global serial_out +serial_out: + ldr r1, =uart_base + ldr r2, [r1] +1: ldrb r3, [r2, #NS16550_LSR] + tst r3, #NS16550_LSR_THRE + beq 1b + strb r0, [r2, #NS16550_THR] + bx lr + + .global serial_in_poll +serial_in_poll: + ldr r1, =uart_base + ldr r2, [r1] + ldrb r3, [r2, #NS16550_LSR] + tst r3, #NS16550_LSR_DR + mvneq r0, #1 + bxeq lr + ldrb r0, [r2, #NS16550_RBR] + bx lr diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libcommon/uartsel.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libcommon/uartsel.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,31 @@ +/* + * uart_select_init() figures out which UART was used to load us + * through the boot ROM, and sets things up for us to use the same + * UART for our communication. + */ + +#include "types.h" +#include "romvars.h" +#include "ns16550.h" +#include "halt.h" + +extern struct boot_rom_vars rom_vars; + +struct ns16550_regs *uart_base; +char *uart_name; + +uart_select_init() +{ + switch (rom_vars.uart_id) { + case 0: + uart_base = (struct ns16550_regs *) 0xFFFF5800; + uart_name = "MODEM"; + break; + case 1: + uart_base = (struct ns16550_regs *) 0xFFFF5000; + uart_name = "IrDA"; + break; + default: + _exit(HALTCODE_INVALIDUART); + } +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/Makefile Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,16 @@ +CC= arm-elf-gcc +CFLAGS= -Os -fno-builtin +AR= arm-elf-ar +RANLIB= arm-elf-ranlib + +OBJS= doprnt.o printf.o putchar.o puts.o sprintf.o sprintf_putchar.o \ + vprintf.o vsprintf.o + +all: libprintf.a + +libprintf.a: ${OBJS} + ${AR} cru $@ ${OBJS} + ${RANLIB} $@ + +clean: + rm -f *.[oa] *errs diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/README Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,15 @@ +The present libprintf is a very light printf implementation that is well-suited +for simple bare-metal programs like loadagent; in the present case it overrides +the much heavier printf implementation in newlib. Programs like the present +loadagent only need printf in order to scribble on the serial console port, +and the most sensible implementation is to have the "character output" function +from the guts of printf point directly to the physical UART output routine, or +a trivial wrapper that turns \n into \r\n. In contrast, newlib's version would +pull in the complete FILE table infrastructure and malloc etc - maybe OK for +more complex embedded programs that use those facilities for other things under +a bona fide RTOS, but it would be disgusting to pull that stuff in for a +minimal program like ours. + +The present printf implementation has been used earlier by the same author +(Michael Spacefalcon) in the StarMON family of PowerPC bootloaders, and in my +MC68x302-based SDSL CPE devices (Hack-o-Rocket and OSDCU). diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/doprnt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/doprnt.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,300 @@ +/* the guts of printf - this implementation came from 4.3BSD-Tahoe */ + +#include +#include +#include + +#define PUTC(ch) ((*outfunc)((ch), outfunc_param)) + +#define ARG() \ + _ulong = flags&LONGINT ? va_arg(argp, long) : va_arg(argp, int); + +#define BUF 256 + +#define todigit(c) ((c) - '0') +#define tochar(n) ((n) + '0') + +/* have to deal with the negative buffer count kludge */ +#define NEGATIVE_COUNT_KLUDGE + +#define LONGINT 0x01 /* long integer */ +#define LONGDBL 0x02 /* long double; unimplemented */ +#define SHORTINT 0x04 /* short integer */ +#define ALT 0x08 /* alternate form */ +#define LADJUST 0x10 /* left adjustment */ +#define ZEROPAD 0x20 /* zero (as opposed to blank) pad */ +#define HEXPREFIX 0x40 /* add 0x or 0X prefix */ + +_doprnt(fmt0, argp, outfunc, outfunc_param) + u_char *fmt0; + va_list argp; + void (*outfunc)(); + void *outfunc_param; +{ + register u_char *fmt; /* format string */ + register int ch; /* character from fmt */ + register int cnt; /* return value accumulator */ + register int n; /* random handy integer */ + register char *t; /* buffer pointer */ + u_long _ulong; /* integer arguments %[diouxX] */ + int base; /* base for [diouxX] conversion */ + int dprec; /* decimal precision in [diouxX] */ + int fieldsz; /* field size expanded by sign, etc */ + int flags; /* flags as above */ + int prec; /* precision from format (%.3d), or -1 */ + int realsz; /* field size expanded by decimal precision */ + int size; /* size of converted field or string */ + int width; /* width from format (%8d), or 0 */ + char sign; /* sign prefix (' ', '+', '-', or \0) */ + char softsign; /* temporary negative sign for floats */ + char *digs; /* digits for [diouxX] conversion */ + char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ + + fmt = fmt0; + digs = "0123456789abcdef"; + for (cnt = 0;; ++fmt) { + for (; (ch = *fmt) && ch != '%'; ++cnt, ++fmt) + PUTC(ch); + if (!ch) + return (cnt); + + flags = 0; dprec = 0; width = 0; + prec = -1; + sign = '\0'; + +rflag: switch (*++fmt) { + case ' ': + /* + * ``If the space and + flags both appear, the space + * flag will be ignored.'' + * -- ANSI X3J11 + */ + if (!sign) + sign = ' '; + goto rflag; + case '#': + flags |= ALT; + goto rflag; + case '*': + /* + * ``A negative field width argument is taken as a + * - flag followed by a positive field width.'' + * -- ANSI X3J11 + * They don't exclude field widths read from args. + */ + if ((width = va_arg(argp, int)) >= 0) + goto rflag; + width = -width; + /* FALLTHROUGH */ + case '-': + flags |= LADJUST; + goto rflag; + case '+': + sign = '+'; + goto rflag; + case '.': + if (*++fmt == '*') + n = va_arg(argp, int); + else { + n = 0; + while (isascii(*fmt) && isdigit(*fmt)) + n = 10 * n + todigit(*fmt++); + --fmt; + } + prec = n < 0 ? -1 : n; + goto rflag; + case '0': + /* + * ``Note that 0 is taken as a flag, not as the + * beginning of a field width.'' + * -- ANSI X3J11 + */ + flags |= ZEROPAD; + goto rflag; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = 0; + do { + n = 10 * n + todigit(*fmt); + } while (isascii(*++fmt) && isdigit(*fmt)); + width = n; + --fmt; + goto rflag; + case 'L': + flags |= LONGDBL; + goto rflag; + case 'h': + flags |= SHORTINT; + goto rflag; + case 'l': + flags |= LONGINT; + goto rflag; + case 'c': + *(t = buf) = va_arg(argp, int); + size = 1; + sign = '\0'; + goto pforw; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': + ARG(); + if ((long)_ulong < 0) { + _ulong = -_ulong; + sign = '-'; + } + base = 10; + goto number; + case 'n': + if (flags & LONGINT) + *va_arg(argp, long *) = cnt; + else if (flags & SHORTINT) + *va_arg(argp, short *) = cnt; + else + *va_arg(argp, int *) = cnt; + break; + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': + ARG(); + base = 8; + goto nosign; + case 'p': + /* + * ``The argument shall be a pointer to void. The + * value of the pointer is converted to a sequence + * of printable characters, in an implementation- + * defined manner.'' + * -- ANSI X3J11 + */ + /* NOSTRICT */ + _ulong = (u_long)va_arg(argp, void *); + base = 16; + goto nosign; + case 's': + if (!(t = va_arg(argp, char *))) + t = "(null)"; + if (prec >= 0) { + /* + * can't use strlen; can only look for the + * NUL in the first `prec' characters, and + * strlen() will go further. + */ + char *p; + + for (p = t, size = 0; size < prec; p++, size++) + if (*p == '\0') + break; + } else + size = strlen(t); + sign = '\0'; + goto pforw; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': + ARG(); + base = 10; + goto nosign; + case 'X': + digs = "0123456789ABCDEF"; + /* FALLTHROUGH */ + case 'x': + ARG(); + base = 16; + /* leading 0x/X only if non-zero */ + if (flags & ALT && _ulong != 0) + flags |= HEXPREFIX; + + /* unsigned conversions */ +nosign: sign = '\0'; + /* + * ``... diouXx conversions ... if a precision is + * specified, the 0 flag will be ignored.'' + * -- ANSI X3J11 + */ +number: if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; + + /* + * ``The result of converting a zero value with an + * explicit precision of zero is no characters.'' + * -- ANSI X3J11 + */ + t = buf + BUF; + if (_ulong != 0 || prec != 0) { + do { + *--t = digs[_ulong % base]; + _ulong /= base; + } while (_ulong); + digs = "0123456789abcdef"; + if (flags & ALT && base == 8 && *t != '0') + *--t = '0'; /* octal leading 0 */ + } + size = buf + BUF - t; + +pforw: + /* + * All reasonable formats wind up here. At this point, + * `t' points to a string which (if not flags&LADJUST) + * should be padded out to `width' places. If + * flags&ZEROPAD, it should first be prefixed by any + * sign or other prefix; otherwise, it should be blank + * padded before the prefix is emitted. After any + * left-hand padding and prefixing, emit zeroes + * required by a decimal [diouxX] precision, then print + * the string proper, then emit zeroes required by any + * leftover floating precision; finally, if LADJUST, + * pad with blanks. + */ + + /* + * compute actual size, so we know how much to pad + * fieldsz excludes decimal prec; realsz includes it + */ + fieldsz = size; + if (sign) + fieldsz++; + if (flags & HEXPREFIX) + fieldsz += 2; + realsz = dprec > fieldsz ? dprec : fieldsz; + + /* right-adjusting blank padding */ + if ((flags & (LADJUST|ZEROPAD)) == 0 && width) + for (n = realsz; n < width; n++) + PUTC(' '); + /* prefix */ + if (sign) + PUTC(sign); + if (flags & HEXPREFIX) { + PUTC('0'); + PUTC((char)*fmt); + } + /* right-adjusting zero padding */ + if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) + for (n = realsz; n < width; n++) + PUTC('0'); + /* leading zeroes from decimal precision */ + for (n = fieldsz; n < dprec; n++) + PUTC('0'); + + for (n = size; --n >= 0; ) + PUTC(*t++); + /* left-adjusting padding (always blank) */ + if (flags & LADJUST) + for (n = realsz; n < width; n++) + PUTC(' '); + /* finally, adjust cnt */ + cnt += width > realsz ? width : realsz; + break; + case '\0': /* "%?" prints ?, unless ? is NULL */ + return (cnt); + default: + PUTC((char)*fmt); + cnt++; + } + } + /* NOTREACHED */ +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/printf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/printf.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,15 @@ +#include + +extern void putchar(); + +int +printf(char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = _doprnt(fmt, ap, &putchar); + va_end(ap); + return(len); +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/putchar.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/putchar.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,9 @@ +extern void serial_out(); + +void +putchar(ch) +{ + if (ch == '\n') + serial_out('\r'); + serial_out(ch); +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/puts.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/puts.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,10 @@ +void +puts(s) + char *s; +{ + int c; + + while (c = *s++) + putchar(c); + putchar('\n'); +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/sprintf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/sprintf.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,18 @@ +#include + +extern void _sprintf_putchar(); + +int +sprintf(char *strdest, char *fmt, ...) +{ + va_list ap; + char *strptr; + int len; + + strptr = strdest; + va_start(ap, fmt); + len = _doprnt(fmt, ap, &_sprintf_putchar, &strptr); + va_end(ap); + *strptr = '\0'; + return(len); +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/sprintf_putchar.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/sprintf_putchar.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,8 @@ +void +_sprintf_putchar(ch, pp) + int ch; + char **pp; +{ + **pp = ch; + (*pp)++; +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/vprintf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/vprintf.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,11 @@ +#include + +extern void putchar(); + +int +vprintf(fmt, ap) + char *fmt; + va_list ap; +{ + return(_doprnt(fmt, ap, &putchar)); +} diff -r e2e80a09338e -r 40f607bb0a2c target-utils/libprintf/vsprintf.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libprintf/vsprintf.c Wed May 01 07:39:35 2013 +0000 @@ -0,0 +1,17 @@ +#include + +extern void _sprintf_putchar(); + +int +vsprintf(str, fmt, ap) + va_list ap; + char *str, *fmt; +{ + char *strptr; + int len; + + strptr = str; + len = _doprnt(fmt, ap, &_sprintf_putchar, &strptr); + *strptr = '\0'; + return(len); +}