diff options
author | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
---|---|---|
committer | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
commit | 03261851a10dd2d6900a0a00a7515a0a46fb5d76 (patch) | |
tree | 7c22ac6cbbc99fd5cd1b5426853be8d4fd7bfcf1 /libgloss/doc | |
parent | fae4c299f14fc23e2829c8656992eba21f79242a (diff) | |
download | cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.gz cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.bz2 cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.zip |
20000317 sourceware import
Diffstat (limited to 'libgloss/doc')
-rw-r--r-- | libgloss/doc/Makefile.in | 147 | ||||
-rwxr-xr-x | libgloss/doc/configure | 887 | ||||
-rw-r--r-- | libgloss/doc/configure.in | 15 | ||||
-rw-r--r-- | libgloss/doc/porting.texi | 2053 |
4 files changed, 3102 insertions, 0 deletions
diff --git a/libgloss/doc/Makefile.in b/libgloss/doc/Makefile.in new file mode 100644 index 000000000..0432e026f --- /dev/null +++ b/libgloss/doc/Makefile.in @@ -0,0 +1,147 @@ +# 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. +# + +srcdir = @srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +mandir = @mandir@ +man1dir = $(mandir)/man1 +infodir = @infodir@ + +MAKEINFO = makeinfo +TEXI2DVI = TEXINPUTS=$(TEXIDIR):$(srcdir):$$TEXINPUTS texi2dvi + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +# Where to find texinfo.tex to format docn with TeX +TEXIDIR = $(srcdir)/../../texinfo + +MANPAGES = + +all: + +info: porting.info + +dvi: porting.dvi + +ps: porting.ps + +doc: info dvi + +porting: porting.dvi porting.info + +###################################################################### +# DOCUMENTATION TARGETS +# TeX output +porting.dvi: $(srcdir)/porting.texi $(srcdir)/porting.texi + $(TEXI2DVI) $(srcdir)/porting.texi + +# info file for online browsing +porting.info: $(srcdir)/porting.texi $(srcdir)/porting.texi + $(MAKEINFO) -I $(srcdir) -o porting.info $(srcdir)/porting.texi + +porting.ps: porting.dvi + dvips -f porting.dvi > porting.ps + +# different targets for -ms, -mm, -me +# Try to use a recent texi2roff. v2 was put on prep in jan91. +# If you want an index, see texi2roff doc for postprocessing +# and add -i to texi2roff invocations below. +# Workarounds for texi2roff-2 (probably fixed in later texi2roff's, delete +# correspondint -e lines when later texi2roff's are current) +# + @ifinfo's deleted explicitly due to texi2roff-2 bug w nested constructs. +# + @c's deleted explicitly because texi2roff sees texinfo commands in them +# + @ (that's at-BLANK) not recognized by texi2roff, turned into blank +# + @alphaenumerate is ridiculously new, turned into @enumerate + +# roff output (-ms) +porting.ms: $(srcdir)/porting.texi + sed -e '/\\input texinfo/d' \ + -e '/@c TEXI2ROFF-KILL/,/@c END TEXI2ROFF-KILL/d' \ + -e '/^@ifinfo/,/^@end ifinfo/d' \ + -e '/^@c/d' \ + -e 's/{.*,,/{/' \ + -e 's/@ / /g' \ + -e 's/^@alphaenumerate/@enumerate/g' \ + -e 's/^@end alphaenumerate/@end enumerate/g' \ + $(srcdir)/porting.texi | \ + $(TEXI2ROFF) -ms | \ + sed -e 's/---/\\(em/g' \ + >porting.ms + +# roff output (-mm) +# '@noindent's removed due to texi2roff-2 mm bug; if yours is newer, +# try leaving them in +porting.mm: $(srcdir)/porting.texi + sed -e '/\\input texinfo/d' \ + -e '/@c TEXI2ROFF-KILL/,/@c END TEXI2ROFF-KILL/d' \ + -e '/^@ifinfo/,/^@end ifinfo/d' \ + -e '/^@c/d' \ + -e 's/{.*,,/{/' \ + -e '/@noindent/d' \ + -e 's/@ / /g' \ + -e 's/^@alphaenumerate/@enumerate/g' \ + -e 's/^@end alphaenumerate/@end enumerate/g' \ + $(srcdir)/porting.texi | \ + $(TEXI2ROFF) -mm | \ + sed -e 's/---/\\(em/g' \ + >porting.mm + +# roff output (-me) +porting.me: $(srcdir)/porting.texi + sed -e '/\\input texinfo/d' \ + -e '/@c TEXI2ROFF-KILL/,/@c END TEXI2ROFF-KILL/d' \ + -e '/^@ifinfo/,/^@end ifinfo/d' \ + -e '/^@c/d' \ + -e 's/{.*,,/{/' \ + -e 's/@ / /g' \ + -e 's/^@alphaenumerate/@enumerate/g' \ + -e 's/^@end alphaenumerate/@end enumerate/g' \ + $(srcdir)/porting.texi | \ + $(TEXI2ROFF) -me | \ + sed -e 's/---/\\(em/g' \ + >porting.me + + +###################################################################### + +clean mostlyclean: + -rm -f *.o *~ \#* core *.aux *.cp *.dvi *.fn *.ky *.log *.pg *.toc \ + *.tp *.vr *.cps *.fns *.kys *.pgs *.tps *.vrs *.info* *.1 *.ps + +maintainer-clean realclean: clean + -rm -f + +install: + +install-info: info + for i in *.info* ; do \ + $(INSTALL_DATA) $$i $(infodir)/$$i ; \ + done + +clean-info: + -rm -rf *.info* + +distclean: clean + -rm -f Makefile config.cache config.log config.status + +Makefile: Makefile.in config.status + $(SHELL) config.status + +config.status: configure + $(SHELL) config.status --recheck diff --git a/libgloss/doc/configure b/libgloss/doc/configure new file mode 100755 index 000000000..8d1886320 --- /dev/null +++ b/libgloss/doc/configure @@ -0,0 +1,887 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.12.1 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.12.1" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=porting.texi + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +if test "$srcdir" = "." ; then + mdir=`echo "${with_multisubdir}/" \ + | sed -e 's,\([^/][^/]*\),..,g' -e 's,^/$,,'` + ac_aux_dir= +for ac_dir in ${mdir}../../.. $srcdir/${mdir}../../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ${mdir}../../.. $srcdir/${mdir}../../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +else + ac_aux_dir= +for ac_dir in ${srcdir}/../.. $srcdir/${srcdir}/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ${srcdir}/../.. $srcdir/${srcdir}/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:580: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set) 2>&1 | grep ac_space` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.12.1" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/libgloss/doc/configure.in b/libgloss/doc/configure.in new file mode 100644 index 000000000..570b33794 --- /dev/null +++ b/libgloss/doc/configure.in @@ -0,0 +1,15 @@ +dnl Process this file with autoconf to produce a configure script. +AC_PREREQ(2.5)dnl +AC_INIT(porting.texi) + +if test "$srcdir" = "." ; then + mdir=`echo "${with_multisubdir}/" \ + | sed -e 's,\([[^/]][[^/]]*\),..,g' -e 's,^/$,,'` + AC_CONFIG_AUX_DIR(${mdir}../../..) +else + AC_CONFIG_AUX_DIR(${srcdir}/../..) +fi + +AC_PROG_INSTALL + +AC_OUTPUT(Makefile) diff --git a/libgloss/doc/porting.texi b/libgloss/doc/porting.texi new file mode 100644 index 000000000..babc22eea --- /dev/null +++ b/libgloss/doc/porting.texi @@ -0,0 +1,2053 @@ +\input texinfo @c -*- Texinfo -*- +@setfilename porting.info +@settitle Embed with GNU + +@c +@c This file documents the process of porting the GNU tools to an +@c embedded environment. +@c + +@finalout +@setchapternewpage off +@iftex +@raggedbottom +@global@parindent=0pt +@end iftex + +@titlepage +@title Embed With GNU +@subtitle Porting The GNU Tools To Embedded Systems +@sp 4 +@subtitle Spring 1995 +@subtitle Very *Rough* Draft +@author Rob Savoye - Cygnus Support +@page + +@vskip 0pt plus 1filll +Copyright @copyright{} 1993, 1994, 1995 Cygnus Support + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. +@end titlepage + +@ifinfo +@format +START-INFO-DIR-ENTRY +* Embed with GNU: (porting-). Embed with GNU +END-INFO-DIR-ENTRY +@end format +Copyright (c) 1993, 1994, 1995 Cygnus Support + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that +the entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions. + +@node Top +@top Embed with GNU + +@end ifinfo +@strong{Rough Draft} + +The goal of this document is to gather all the information needed to +port the GNU tools to a new embedded target in one place. This will +duplicate some info found in the other manual for the GNU tools, but +this should be all you'll need. + +@menu +* Libgloss:: Libgloss, a library of board support packages. +* GCC:: Porting GCC/G++ to a new embedded target. +* Libraries:: Making Newlib run on an new embedded target. +* GDB:: Making GDB understand a new back end. +* Binutils:: Using the GNU binary utilities. +* Code Listings:: Listings of the commented source code from the + text. +@end menu + +@node Libgloss, GCC, Top, Top +@chapter Libgloss +Libgloss is a library for all the details that usually get glossed over. +This library refers to things like startup code, and usually I/O support +for @code{gcc} and @code{C library}. The C library used through out +this manual is @code{newlib}. Newlib is a ANSI conforming C library +developed by Cygnus Support. Libgloss could easily be made to +support other C libraries, and it can be used standalone as well. The +standalone configuration is typically used when bringing up new +hardware, or on small systems. + +For a long time, these details were part of newlib. This approach worked +well when a complete tool chain only had to support one system. A tool +chain refers to the series of compiler passes required to produce a +binary file that will run on an embedded system. For C, the passes are +cpp, gcc, gas, ld. Cpp is the preprocessor, which process all the header +files and macros. Gcc is the compiler, which produces assembler from the +processed C files. Gas assembles the code into object files, and then ld +combines the object files and binds the code to addresses and produces +the final executable image. + +Most of the time a tool chain does only have to support one target +execution environment. An example of this would be a tool chain for the +AMD 29k processor family. All of the execution environments for this +processor are have the same interface, the same memory map, and the same +I/O code. In this case all of the support code is in newlib/sys/FIXME. +Libgloss's creation was forced initially be the @code{cpu32} processor +family. There are many different execution environments for this line, +and they vary wildly. newlib itself has only has a few dependencies that +it needs for each target. These are explained later in this doc. The +hardware dependent part of newlib was reorganized into a separate +directory structure within newlib called the stub dirs. It was initially +called this because most of the routines newlib needs for a target were +simple stubs that do nothing, but return a value to the application. They +only exist so the linker can produce a final executable image. This work +was done during the early part of 1993. + +After a while it became apparent that this approach of isolating the +hardware and systems files together made sense. Around this same time +the stub dirs were made to run standalone, mostly so it could also be +used to support GDB's remote debugging needs. At this time it was +decided to move the stub dirs out of newlib and into it's own separate +library so it could be used standalone, and be included in various other +GNU tools without having to bring in all of newlib, which is large. The +new library is called Libgloss, for Gnu Low-level OS support. + +@menu +* Supported targets:: What targets libgloss currently + supports. +* Building libgloss:: How to configure and built libgloss + for a target. +@end menu + +@node Supported targets, Building libgloss, Libgloss, Libgloss +@subsection Supported Targets +Currently libgloss is being used for the following targets: + +@menu +* Sparclite:: Fujitsu's sparclite. +* CPU32:: Various m68k based targets. +* Mips:: Mips code based targets. +* PA-RISC:: Precision Risc Organization.. +@end menu + +@node Sparclite, CPU32, , Supported targets +@subsection Sparclite Targets Supported +@c FIXME: put links to the docs in etc/targetdoc +This is for the Fujitsu Sparclite family of processors. Currently this +covers the ex930, ex931, ex932, ex933, and the ex934. In addition to the +I/O code a startup file, this has a GDB debug-stub that gets linked into +your application. This is an exception handler style debug stub. For +more info, see the section on Porting GDB. @ref{GDB,,Porting GDB}. + +The Fujitsu eval boards use a host based terminal program to load and +execute programs on the target. This program, @code{pciuh} is relatively +new (in 1994) and it replaced the previous ROM monitor which had the +shell in the ROM. GDB uses the the GDB remote protocol, the relevant +source files from the gdb sources are remote-sparcl.c. The debug stub is +part of libgloss and is called sparcl-stub.c. + +@node CPU32, Mips, Sparclite, Supported targets +@subsection Motorola CPU32 Targets supported +This refers to Motorola's m68k based CPU32 processor family. The crt0.S +startup file should be usable with any target environment, and it's +mostly just the I/O code and linker scripts that vary. Currently there +is support for the Motorola MVME line of 6U VME boards and IDP +line of eval boards. All of the +Motorola VME boards run @code{Bug}, a ROM based debug monitor. +This monitor has the feature of using user level traps to do I/O, so +this code should be portable to other MVME boards with little if any +change. The startup file also can remain unchanged. About the only thing +that varies is the address for where the text section begins. This can +be accomplished either in the linker script, or on the command line +using the @samp{-Ttext [address]}. + +@c FIXME: Intermetrics or ISI wrote rom68k ? +There is also support for the @code{rom68k} monitor as shipped on +Motorola's IDP eval board line. This code should be portable across the +range of CPU's the board supports. There is also GDB support for this +target environment in the GDB source tree. The relevant files are +gdb/monitor.c, monitor.h, and rom58k-rom.c. The usage of these files is +discussed in the GDB section. + +@node Mips, PA-RISC, CPU32, Supported targets +@subsection Mips core Targets Supported +The Crt0 startup file should run on any mips target that doesn't require +additional hardware initialization. The I/O code so far only supports a +custom LSI33k based RAID disk controller board. It should easy to +change to support the IDT line of eval boards. Currently the two +debugging protocols supported by GDB for mips targets is IDT's mips +debug protocol, and a customized hybrid of the standard GDB remote +protocol and GDB's standard ROM monitor support. Included here is the +debug stub for the hybrid monitor. This supports the LSI33k processor, +and only has support for the GDB protocol commands @code{g}, @code{G}, +@code{m}, @code{M}, which basically only supports the register and +memory reading and writing commands. This is part of libgloss and is +called lsi33k-stub.c. + +The crt0.S should also work on the IDT line of eval boards, but has only +been run on the LSI33k for now. There is no I/O support for the IDT eval +board at this time. The current I/O code is for a customized version of +LSI's @code{pmon} ROM monitor. This uses entry points into the monitor, +and should easily port to other versions of the pmon monitor. Pmon is +distributed in source by LSI. + +@node PA-RISC, , Mips, Supported targets +@subsection PA-RISC Targets Supported +This supports the various boards manufactured by the HP-PRO consortium. +This is a group of companies all making variations on the PA-RISC +processor. Currently supported are ports to the WinBond @samp{Cougar} +board based around their w89k version of the PA. Also supported is the +Oki op50n processor. + +There is also included, but never built an unfinished port to the HP 743 +board. This board is the main CPU board for the HP700 line of industrial +computers. This target isn't exactly an embedded system, in fact it's +really only designed to load and run HP-UX. Still, the crt0.S and I/O +code are fully working. It is included mostly because their is a barely +functioning exception handler GDB debug stub, and I hope somebody could +use it. The other PRO targets all use GDB's ability to talk to ROM +monitors directly, so it doesn't need a debug stub. There is also a +utility that will produce a bootable file by HP's ROM monitor. This is +all included in the hopes somebody else will finish it. :-) + +Both the WinBond board and the Oki board download srecords. The WinBond +board also has support for loading the SOM files as produced by the +native compiler on HP-UX. WinBond supplies a set of DOS programs that +will allow the loading of files via a bidirectional parallel port. This +has never been tested with the output of GNU SOM, as this manual is +mostly for Unix based systems. + +@node Building libgloss, , Supported targets, Libgloss +@subsection Configuring and building libgloss. + +Libgloss uses an autoconf based script to configure. Autoconf scripts +are portable shell scripts that are generated from a configure.in file. +Configure input scripts are based themselves on m4. Most configure +scripts run a series of tests to determine features the various +supported features of the target. For features that can't be determined +by a feature test, a makefile fragment is merged in. The configure +process leaves creates a Makefile in the build directory. For libgloss, +there are only a few configure options of importance. These are --target +and --srcdir. + +Typically libgloss is built in a separate tree just for objects. In this +manner, it's possible to have a single source tree, and multiple object +trees. If you only need to configure for a single target environment, +then you can configure in the source tree. The argument for --target is +a config string. It's usually safest to use the full canonical opposed +to the target alias. So, to configure for a CPU32 (m68k) with a separate +source tree, use: + +@smallexample +../src/libgloss/configure --verbose --target m68k-coff +@end smallexample + +The configure script is in the source tree. When configure is invoked +it will determine it's own source tree, so the --srcdir is would be +redundant here. + +Once libgloss is configured, @code{make} is sufficient to build it. The +default values for @code{Makefiles} are typically correct for all +supported systems. The test cases in the testsuite will also built +automatically as opposed to a @code{make check}, where test binaries +aren't built till test time. This is mostly cause the libgloss +testsuites are the last thing built when building the entire GNU source +tree, so it's a good test of all the other compilation passes. + +The default values for the Makefiles are set in the Makefile fragment +merged in during configuration. This fragment typically has rules like + +@smallexample +CC_FOR_TARGET = `if [ -f $$@{OBJROOT@}/gcc/xgcc ] ; \ + then echo $@{OBJROOT@}/gcc/xgcc -B$@{OBJROOT@}/gcc/ ; \ + else t='$@{program_transform_name@}'; echo gcc | sed -e '' $$t ; fi` +@end smallexample + +Basically this is a runtime test to determine whether there are freshly +built executables for the other main passes of the GNU tools. If there +isn't an executable built in the same object tree, then +@emph{transformed}the generic tool name (like gcc) is transformed to the +name typically used in GNU cross compilers. The names are +typically based on the target's canonical name, so if you've configured +for @code{m68k-coff} the transformed name is @code{m68k-coff-gcc} in +this case. If you install with aliases or rename the tools, this won't +work, and it will always look for tools in the path. You can force the a +different name to work by reconfiguring with the +@code{--program-transform-name} option to configure. This option takes a +sed script like this @code{-e s,^,m68k-coff-,} which produces tools +using the standard names (at least here at Cygnus). + +The search for the other GNU development tools is exactly the same idea. +This technique gets messier when build options like @code{-msoft-float} +support are used. The Makefile fragments set the @code{MUTILIB} +variable, and if it is set, the search path is modified. If the linking +is done with an installed cross compiler, then none of this needs to be +used. This is done so libgloss will build automatically with a fresh, +and uninstalled object tree. It also makes it easier to debug the other +tools using libgloss's test suites. + +@node GCC, Libraries, Libgloss, Top +@chapter Porting GCC + +Porting GCC requires two things, neither of which has anything to do +with GCC. If GCC already supports a processor type, then all the work in +porting GCC is really a linker issue. All GCC has to do is produce +assembler output in the proper syntax. Most of the work is done by the +linker, which is described elsewhere. + +Mostly all GCC does is format the command line for the linker pass. The +command line for GCC is set in the various config subdirectories of gcc. +The options of interest to us are @code{CPP_SPEC} and +@code{STARTFILE_SPEC}. CPP_SPEC sets the builtin defines for your +environment. If you support multiple environments with the same +processor, then OS specific defines will need to be elsewhere. +@c FIXME: Check these names + +@code{STARTFILE_SPEC} + +Once you have linker support, GCC will be able to produce a fully linked +executable image. The only @emph{part} of GCC that the linker wants is a +crt0.o, and a memory map. If you plan on running any programs that do +I/O of any kind, you'll need to write support for the C library, which +is described elsewhere. + +@menu +* Overview:: An overview as to the compilation passes. +* Options:: Useful GCC options for embedded systems. +@end menu + +@node Overview, Options, , GCC +@subsection Compilation passes + +GCC by itself only compiles the C or C++ code into assembler. Typically +GCC invokes all the passes required for you. These passes are cpp, cc1, +gas, ld. @code{cpp} is the C preprocessor. This will merge in the +include files, expand all macros definitions, and process all the +@code{#ifdef} sections. To see the output of ccp, invoke gcc with the +@code{-E} option, and the preprocessed file will be printed on the +stdout. cc1 is the actual compiler pass that produces the assembler for +the processed file. GCC is actually only a driver program for all the +compiler passes. It will format command line options for the other passes. +The usual command line GCC uses for the final link phase will have LD +link in the startup code and additional libraries by default. + +GNU AS started it's life to only function as a compiler pass, but +these days it can also be used as a source level assembler. When used as +a source level assembler, it has a companion assembler preprocessor +called @code{gasp}. This has a syntax similar to most other assembler +macros packages. GAS emits a relocatable object file from the assembler +source. The object file contains the executable part of the application, +and debug symbols. + +LD is responsible for resolving the addresses and symbols to something +that will be fully self-contained. Some RTOS's use relocatable object +file formats like @code{a.out}, but more commonly the final image will +only use absolute addresses for symbols. This enables code to be burned +into PROMS as well. Although LD can produce an executable image, there +is usually a hidden object file called @code{crt0.o} that is required as +startup code. With this startup code and a memory map, the executable +image will actually run on the target environment. @ref{Crt0,,Startup +Files}. + +The startup code usually defines a special symbol like @code{_start} +that is the default base address for the application, and the first +symbol in the executable image. If you plan to use any routines from the +standard C library, you'll also need to implement the functions that +this library is dependent on. @ref{Libraries,,Porting Newlib}. + +@node Options, , Overview, GCC +@c FIXME: Need stuff here about -fpic, -Ttext, etc... + +Options for the various development tools are covered in more detail +elsewhere. Still, the amount of options can be an overwhelming amount of +stuff, so the options most suited to embedded systems are summarized +here. If you use GCC as the main driver for all the passes, most of the +linker options can be passed directly to the compiler. There are also +GCC options that control how the GCC driver formats the command line +arguments for the linker. + +@menu +* GCC Options:: Options for the compiler. +* GAS Options:: Options for the assembler. +* LD Options:: Options for the linker. +@end menu + +@node GCC Options, GAS Options, , Options +Most of the GCC options that we're interested control how the GCC driver +formats the options for the linker pass. + +@c FIXME: this section is still under work. +@table @code +@item -nostartfiles +@item -nostdlib +@item -Xlinker +Pass the next option directly to the linker. + +@item -v +@item -fpic +@end table + +@node GAS Options, LD Options, GCC Options, Options +@c FIXME: Needs stuff here + +@node LD Options, , GAS Options, Options +@c FIXME: Needs stuff here + + +@node Libraries, GDB, GCC, Top +@chapter Porting newlib + +@menu +* Crt0:: Crt0.S. +* Linker Scripts:: Linker scripts for memory management. +* What to do now:: Tricks for manipulating formats. +* Libc:: Making libc work. +@end menu + +@node Crt0, Linker Scripts, , Libraries +@section Crt0, the main startup file + +To make a program that has been compiled with GCC to run, you +need to write some startup code. The initial piece of startup code is +called a crt0. (C RunTime 0) This is usually written in assembler, and +it's object gets linked in first, and bootstraps the rest of the +application when executed. This file needs to do the following things. + +@enumerate +@item +Initialize anything that needs it. This init section varies. If you are +developing an application that gets download to a ROM monitor, then +there is usually no need for any special initialization. The ROM monitor +handles it for you. + +If you plan to burn your code in a ROM, then the crt0 typically has to +do all the hardware initialization that is required to run an +application. This can include things like initializing serial ports or +run a memory check. It all depends on the hardware. + +@item +Zero the BSS section. This is for uninitialized data. All the addresses in +this section need to be initialized to zero so that programs that forget +to check new variables default value will get unpredictable results. + +@item +Call main() +This is what basically starts things running. If your ROM monitor +supports it, then first setup argc and argv for command line arguments +and an environment pointer. Then branch to main(). For G++ the the main +routine gets a branch to __main inserted by the code generator at the +very top. __main() is used by G++ to initialize it's internal tables. +__main() then returns back to your original main() and your code gets +executed. + +@item +Call exit() +After main() has returned, you need to cleanup things and return control +of the hardware from the application. On some hardware, there is nothing +to return to, especially if your program is in ROM. Sometimes the best +thing to do in this case is do a hardware reset, or branch back to the +start address all over again. + +When there is a ROM monitor present, usually a user trap can be called +and then the ROM takes over. Pick a safe vector with no side +effects. Some ROMs have a builtin trap handler just for this case. +@end enumerate +portable between all the m68k based boards we have here. +@ref{crt0.S,,Example Crt0.S}. + + +@smallexample +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b +@end smallexample +These we'll use later. + +@smallexample +/* These are predefined by new versions of GNU cpp. */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +/* Use the right prefix for global labels. */ +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +@end smallexample + +These macros are to make this code portable between both @emph{COFF} and +@emph{a.out}. @emph{COFF} always has an @var{_ (underline)} prepended on +the front of all global symbol names. @emph{a.out} has none. + +@smallexample +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* Use the right prefix for registers. */ +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define d0 REG (d0) +#define d1 REG (d1) +#define d2 REG (d2) +#define d3 REG (d3) +#define d4 REG (d4) +#define d5 REG (d5) +#define d6 REG (d6) +#define d7 REG (d7) +#define a0 REG (a0) +#define a1 REG (a1) +#define a2 REG (a2) +#define a3 REG (a3) +#define a4 REG (a4) +#define a5 REG (a5) +#define a6 REG (a6) +#define fp REG (fp) +#define sp REG (sp) +@end smallexample + +This is for portability between assemblers. Some register names have a +@var{%} or @var{$} prepended to the register name. + +@smallexample +/* + * Set up some room for a stack. We just grab a chunk of memory. + */ + .set stack_size, 0x2000 + .comm SYM (stack), stack_size +@end smallexample + +Set up space for the stack. This can also be done in the linker script, +but it typically gets done here. + +@smallexample +/* + * Define an empty environment. + */ + .data + .align 2 +SYM (environ): + .long 0 +@end smallexample + +Set up an empty space for the environment. This is bogus on any most ROM +monitor, but we setup a valid address for it, and pass it to main. At +least that way if an application checks for it, it won't crash. + +@smallexample + .align 2 + .text + .global SYM (stack) + + .global SYM (main) + .global SYM (exit) +/* + * This really should be __bss_start, not SYM (__bss_start). + */ + .global __bss_start +@end smallexample + +Setup a few global symbols that get used elsewhere. @var{__bss_start} +needs to be unchanged, as it's setup by the linker script. + +@smallexample +/* + * start -- set things up so the application will run. + */ +SYM (start): + link a6, #-8 + moveal #SYM (stack) + stack_size, sp + +/* + * zerobss -- zero out the bss section + */ + moveal #__bss_start, a0 + moveal #SYM (end), a1 +1: + movel #0, (a0) + leal 4(a0), a0 + cmpal a0, a1 + bne 1b +@end smallexample + +The global symbol @code{start} is used by the linker as the default +address to use for the @code{.text} section. then it zeros the +@code{.bss} section so the uninitialized data will all be cleared. Some +programs have wild side effects from having the .bss section let +uncleared. Particularly it causes problems with some implementations of +@code{malloc}. + +@smallexample +/* + * Call the main routine from the application to get it going. + * main (argc, argv, environ) + * We pass argv as a pointer to NULL. + */ + pea 0 + pea SYM (environ) + pea sp@@(4) + pea 0 + jsr SYM (main) + movel d0, sp@@- +@end smallexample + +Setup the environment pointer and jump to @code{main()}. When +@code{main()} returns, it drops down to the @code{exit} routine below. + +@smallexample +/* + * _exit -- Exit from the application. Normally we cause a user trap + * to return to the ROM monitor for another run. + */ +SYM (exit): + trap #0 +@end smallexample + +Implementing @code{exit} here is easy. Both the @code{rom68k} and @code{bug} +can handle a user caused exception of @code{zero} with no side effects. +Although the @code{bug} monitor has a user caused trap that will return +control to the ROM monitor, this solution has been more portable. + +@node Linker Scripts, What to do now, Crt0, Libraries +@section Linker scripts for memory management + +The linker script sets up the memory map of an application. It also +sets up default values for variables used elsewhere by sbrk() and the +crt0. These default variables are typically called @code{_bss_start} and +@code{_end}. + +For G++, the constructor and destructor tables must also be setup here. +The actual section names vary depending on the object file format. For +@code{a.out} and @code{coff}, the three main sections are @code{.text}, +@code{.data}, and @code{.bss}. + +Now that you have an image, you can test to make sure it got the +memory map right. You can do this by having the linker create a memory +map (by using the @code{-Map} option), or afterwards by using @code{nm} to +check a few critical addresses like @code{start}, @code{bss_end}, and +@code{_etext}. + +Here's a breakdown of a linker script for a m68k based target board. +See the file @code{libgloss/m68k/idp.ld}, or go to the appendixes in +the end of the manual. @ref{idp.ld,,Example Linker Script}. + +@smallexample +STARTUP(crt0.o) +OUTPUT_ARCH(m68k) +INPUT(idp.o) +SEARCH_DIR(.) +__DYNAMIC = 0; +@end smallexample + +The @code{STARTUP} command loads the file specified so that it's +first. In this case it also doubles to load the file as well, because +the m68k-coff configuration defaults to not linking in the crt0.o by +default. It assumes that the developer probably has their own crt0.o. +This behavior is controlled in the config file for each architecture. +It's a macro called @code{STARTFILE_SPEC}, and if it's set to +@code{null}, then when @code{gcc} formats it's command line, it doesn't +add @code{crto.o}. Any file name can be specified here, but the default +is always @code{crt0.o}. + +Course if you only use @code{ld} to link, then the control of whether or +not to link in @code{crt0.o} is done on the command line. If you have +multiple crto files, then you can leave this out all together, and link +in the @code{crt0.o} in the makefile, or by having different linker +scripts. Sometimes this is done for initializing floating point +optionally, or to add device support. + +The @code{OUTPUT_ARCH} sets architecture the output file is for. + +@code{INPUT} loads in the file specified. In this case, it's a relocated +library that contains the definitions for the low-level functions need +by libc.a. This could have also been specified on the command line, but +as it's always needed, it might as well be here as a default. +@code{SEARCH_DIR} specifies the path to look for files, and +@code{_DYNAMIC} means in this case there are no shared libraries. + +@c FIXME: Check the linker manual to make sure this is accurate. +@smallexample +/* + * Setup the memory map of the MC68ec0x0 Board (IDP) + * stack grows up towards high memory. This works for + * both the rom68k and the mon68k monitors. + */ +MEMORY +@{ + ram : ORIGIN = 0x10000, LENGTH = 2M +@} +@end smallexample + +This specifies a name for a section that can be referred to later in the +script. In this case, it's only a pointer to the beginning of free RAM +space, with an upper limit at 2M. If the output file exceeds the upper +limit, it will produce an error message. + +@smallexample +/* + * stick everything in ram (of course) + */ +SECTIONS +@{ + .text : + @{ + CREATE_OBJECT_SYMBOLS + *(.text) + etext = .; + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + *(.lit) + *(.shdata) + @} > ram + .shbss SIZEOF(.text) + ADDR(.text) : @{ + *(.shbss) + @} +@end smallexample + +Set up the @code{.text} section. In a @code{COFF} file, .text is where +all the actual instructions are. This also sets up the @emph{CONTRUCTOR} +and the @emph{DESTRUCTOR} tables for @code{G++}. Notice that the section +description redirects itself to the @emph{ram} variable setup earlier. + +@smallexample + .talias : @{ @} > ram + .data : @{ + *(.data) + CONSTRUCTORS + _edata = .; + @} > ram +@end smallexample + +Setup the @code{.data} section. In a @code{coff} file, this is where all +he initialized data goes. @code{CONSTRUCTORS} is a special command used +by @code{ld}. + +@smallexample + .bss SIZEOF(.data) + ADDR(.data) : + @{ + __bss_start = ALIGN(0x8); + *(.bss) + *(COMMON) + end = ALIGN(0x8); + _end = ALIGN(0x8); + __end = ALIGN(0x8); + @} + .mstack : @{ @} > ram + .rstack : @{ @} > ram + .stab . (NOLOAD) : + @{ + [ .stab ] + @} + .stabstr . (NOLOAD) : + @{ + [ .stabstr ] + @} +@} +@end smallexample + +Setup the @code{.bss} section. In a @code{COFF} file, this is where +unitialized data goes. The symbols @code{_bss_start} and @code{_end} +are setup here for use by the @code{crt0.o} when it zero's the +@code{.bss} section. + + +@node What to do now, Libc, Linker Scripts, Libraries +@section What to do when you have a binary image + +A few ROM monitors load binary images, typically @code{a.out}, but most all +will load an @code{srecord}. An srecord is an ASCII representation of a binary +image. At it's simplest, an srecord is an address, followed by a byte +count, followed by the bytes, and a 2's compliment checksum. A whole +srecord file has an optional @emph{start} record, and a required @emph{end} +record. To make an srecord from a binary image, the GNU @code{objcopy} program +is used. This will read the image and make an srecord from it. To do +this, invoke objcopy like this: @code{objcopy -O srec infile outfile}. Most +PROM burners also read srecords or a similar format. Use @code{objdump -i} to +get a list of support object files types for your architecture. + +@node Libc, , What to do now, Libraries +@section Libraries + +This describes @code{newlib}, a freely available libc replacement. Most +applications use calls in the standard C library. When initially linking +in libc.a, several I/O functions are undefined. If you don't plan on +doing any I/O, then you're OK, otherwise they need to be created. These +routines are read, write, open, close. sbrk, and kill. Open & close +don't need to be fully supported unless you have a filesystems, so +typically they are stubbed out. Kill is also a stub, since you can't do +process control on an embedded system. + +Sbrk() is only needed by applications that do dynamic memory +allocation. It's uses the symbol @code{_end} that is setup in the linker +script. It also requires a compile time option to set the upper size +limit on the heap space. This leaves us with read and write, which are +required for serial I/O. Usually these two routines are written in C, +and call a lower level function for the actual I/O operation. These two +lowest level I/O primitives are inbyte() and outbyte(), and are also +used by GDB back ends if you've written an exception handler. Some +systems also implement a havebyte() for input as well. + +Other commonly included functions are routines for manipulating +LED's on the target (if they exist) or low level debug help. Typically a +putnum() for printing words and bytes as a hex number is helpful, as +well as a low-level print() to output simple strings. + +As libg++ uses the I/O routines in libc.a, if read and write work, +then libg++ will also work with no additional changes. + +@menu +* I/O Support:: Functions that make serial I/O work. +* Memory Support:: Memory support. +* Misc Support:: Other needed functions. +* Debugging:: Useful Debugging Functions +@end menu + +@node I/O Support, Memory Support, , Libc +@subsection Making I/O work + +@node Memory Support, Misc Support, I/O Support, Libc +@subsection Routines for dynamic memory allocation +To support using any of the memory functions, you need to implement +sbrk(). @code{malloc()}, @code{calloc()}, and @code{realloc()} all call +@code{sbrk()} at there lowest level. @code{caddr_t} is defined elsewhere +as @code{char *}. @code{RAMSIZE} is presently a compile time option. All +this does is move a pointer to heap memory and check for the upper +limit. @ref{glue.c,,Example libc support code}. @code{sbrk()} returns a +pointer to the previous value before more memory was allocated. + +@smallexample +/* _end is set in the linker command file * +extern caddr_t _end;/ + +/* just in case, most boards have at least some memory */ +#ifndef RAMSIZE +# define RAMSIZE (caddr_t)0x100000 +#endif + +/* + * sbrk -- changes heap size size. Get nbytes more + * RAM. We just increment a pointer in what's + * left of memory on the board. + */ +caddr_t +sbrk(nbytes) + int nbytes; +@{ + static caddr_t heap_ptr = NULL; + caddr_t base; + + if (heap_ptr == NULL) @{ + heap_ptr = (caddr_t)&_end; + @} + + if ((RAMSIZE - heap_ptr) >= 0) @{ + base = heap_ptr; + heap_ptr += nbytes; + return (base); + @} else @{ + errno = ENOMEM; + return ((caddr_t)-1); + @} +@} +@end smallexample + +@node Misc Support, Debugging, Memory Support, Libc +@subsection Misc support routines + +These are called by @code{newlib} but don't apply to the embedded +environment. @code{isatty()} is self explanatory. @code{kill()} doesn't +apply either in an environment withno process control, so it justs +exits, which is a similar enough behavior. @code{getpid()} can safely +return any value greater than 1. The value doesn't effect anything in +@code{newlib} because once again there is no process control. + +@smallexample +/* + * 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 +isatty(fd) + int fd; +@{ + return (1); +@} + +/* + * getpid -- only one process, so just return 1. + */ +#define __MYPID 1 +int +getpid() +@{ + return __MYPID; +@} + +/* + * kill -- go out via exit... + */ +int +kill(pid, sig) + int pid; + int sig; +@{ + if(pid == __MYPID) + _exit(sig); + return 0; +@} +@end smallexample + +@node Debugging, , Misc Support, Libc +@subsection Useful debugging functions + +There are always a few useful functions for debugging your project in +progress. I typically implement a simple @code{print()} routine that +runs standalone in liblgoss, with no @code{newlib} support. The I/O +function @code{outbyte()} can also be used for low level debugging. Many +times print will work when there are problems that cause @code{printf()} to +cause an exception. @code{putnum()} is just to print out values in hex +so they are easier to read. + +@smallexample +/* + * print -- do a raw print of a string + */ +int +print(ptr) +char *ptr; +@{ + while (*ptr) @{ + outbyte (*ptr++); + @} +@} + +/* + * putnum -- print a 32 bit number in hex + */ +int +putnum (num) +unsigned int num; +@{ + char buffer[9]; + int count; + char *bufptr = buffer; + int digit; + + for (count = 7 ; count >= 0 ; count--) @{ + digit = (num >> (count * 4)) & 0xf; + + if (digit <= 9) + *bufptr++ = (char) ('0' + digit); + else + *bufptr++ = (char) ('a' - 10 + digit); + @} + + *bufptr = (char) 0; + print (buffer); + return; +@} +@end smallexample + +If there are LEDs on the board, they can also be put to use for +debugging when the serial I/O code is being written. I usually implement +a @code{zylons()} function, which strobes the LEDS (if there is more +than one) in sequence, creating a rotating effect. This is convenient +between I/O to see if the target is still alive. Another useful LED +function is @code{led_putnum()}, which takes a digit and displays it as +a bit pattern or number. These usually have to be written in assembler +for each target board. Here are a number of C based routines that may be +useful. + +@code{led_putnum()} puts a number on a single digit segmented +LED display. This LED is set by setting a bit mask to an address, where +1 turns the segment off, and 0 turns it on. There is also a little +decimal point on the LED display, so it gets the leftmost bit. The other +bits specify the segment location. The bits look like: + +@smallexample + [d.p | g | f | e | d | c | b | a ] is the byte. +@end smallexample + +The locations are set up as: + +@smallexample + a + ----- + f | | b + | g | + ----- + | | + e | | c + ----- + d +@end smallexample + +This takes a number that's already been converted to a string, and +prints it. + +@smallexample +#define LED_ADDR 0xd00003 + +void +led_putnum ( num ) +char num; +@{ + static unsigned char *leds = (unsigned char *)LED_ADDR; + static unsigned char num_bits [18] = @{ + 0xff, /* clear all */ + 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */ + 0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe /* letters a-f */ + @}; + + if (num >= '0' && num <= '9') + num = (num - '0') + 1; + + if (num >= 'a' && num <= 'f') + num = (num - 'a') + 12; + + if (num == ' ') + num = 0; + + *leds = num_bits[num]; +@} + +/* + * zylons -- draw a rotating pattern. NOTE: this function never returns. + */ +void +zylons() +@{ + unsigned char *leds = (unsigned char *)LED_ADDR; + unsigned char curled = 0xfe; + + while (1) + @{ + *leds = curled; + curled = (curled >> 1) | (curled << 7); + delay ( 200 ); + @} +@} +@end smallexample + + +@node GDB, Binutils, Libraries, Top +@chapter Writing a new GDB backend + +Typically, either the low-level I/O routines are used for debugging, or +LEDs, if present. It is much easier to use GDb for debugging an +application. There are several different techniques used to have GDB work +remotely. Commonly more than one kind of GDB interface is used to cober +a wide variety of development needs. + +The most common style of GDB backend is an exception handler for +breakpoints. This is also called a @emph{gdb stub}, and is requires the +two additional lines of init code in your @code{main()} routine. The GDB +stubs all use the GDB @emph{remote protocol}. When the application gets a +breakpoint exception, it communicates to GDB on the host. + +Another common style of interfacing GDB to a target is by using an +existing ROM monitor. These break down into two main kinds, a similar +protocol to the GDB remote protocol, and an interface that uses the ROM +monitor directly. This kind has GDB simulating a human operator, and all +GDB does is work as a command formatter and parser. + +@menu +* GNU remote protocol:: The standard remote protocol. +* Exception handler:: A linked in exception handler. +* ROM monitors:: Using a ROM monitor as a backend. +* Other remote protocols:: Adding support for new protocols. +@end menu + +@node GNU remote protocol, Exception handler, ,GDB +@section The standard remote protocol + +The standard remote protocol is a simple, packet based scheme. A debug +packet whose contents are @emph{<data>} is encapsulated for transmission +in the form: + +@smallexample + $ <data> # CSUM1 CSUM2 +@end smallexample + +@emph{<data>} must be ASCII alphanumeric and cannot include characters +@code{$} or @code{#}. If @emph{<data>} starts with two characters +followed by @code{:}, then the existing stubs interpret this as a +sequence number. For example, the command @code{g} is used to read the +values of the registers. So, a packet to do this would look like + +@smallexample + $g#67 +@end smallexample + +@emph{CSUM1} and @emph{CSUM2} are an ascii representation in hex of an +8-bit checksum of @emph{<data>}, the most significant nibble is sent first. +the hex digits 0-9,a-f are used. + +A simple protocol is used when communicating with the target. This is +mainly to give a degree of error handling over the serial cable. For +each packet transmitted successfully, the target responds with a +@code{+} (@code{ACK}). If there was a transmission error, then the target +responds with a @code{-} (@code{NAK}). An error is determined when the +checksum doesn't match the calculated checksum for that data record. +Upon reciept of the @code{ACK}, @code{GDB} can then transmit the next +packet. + +Here is a list of the main functions that need to be supported. Each data +packet is a command with a set number of bytes in the command packet. +Most commands either return data, or respond with a @code{NAK}. Commands +that don't return data respond with an @code{ACK}. All data values are +ascii hex digits. Every byte needs two hex digits to represent t. This +means that a byte with the value @samp{7} becomes @samp{07}. On a 32 bit +machine this works out to 8 characters per word. All of the bytes in a +word are stored in the target byte order. When writing the host side of +the GDB protocol, be careful of byte order, and make sure that the code +will run on both big and little endian hosts and produce the same answers. + +These functions are the minimum required to make a GDB backend work. All +other commands are optional, and not supported by all GDB backends. + +@table @samp +@item read registers @code{g} + +returns @code{XXXXXXXX...} + +Registers are in the internal order for GDB, and the bytes in a register +are in the same order the machine uses. All values are in sequence +starting with register 0. All registers are listed in the same packet. A +sample packet would look like @code{$g#}. + +@item write registers @code{GXXXXXXXX...} +@code{XXXXXXXX} is the value to set the register to. Registers are in +the internal order for GDB, and the bytes in a register are in the same +order the machine uses. All values are in sequence starting with +register 0. All registers values are listed in the same packet. A sample +packet would look like @code{$G000000001111111122222222...#} + +returns @code{ACK} or @code{NAK} + +@item read memory @code{mAAAAAAAA,LLLL} +@code{AAAAAAAA} is address, @code{LLLL} is length. A sample packet would +look like @code{$m00005556,0024#}. This would request 24 bytes starting +at address @emph{00005556} + +returns @code{XXXXXXXX...} +@code{XXXXXXXX} is the memory contents. Fewer bytes than requested will +be returned if only part of the data can be read. This can be determined +by counting the values till the end of packet @code{#} is seen and +comparing that with the total count of bytes that was requested. + +@item write memory @code{MAAAAAAAA,LLLL:XXXXXXXX} +@code{AAAAAAAA} is the starting address, @code{LLLL} is the number of +bytes to be written, and @code{XXXXXXXX} is value to be written. A +sample packet would look like +@code{$M00005556,0024:101010101111111100000000...#} + +returns @code{ACK} or @code{NAK} for an error. @code{NAK} is also +returned when only part of the data is written. + +@item continue @code{cAAAAAAAAA} +@code{AAAAAAAA} is address to resume execution at. If @code{AAAAAAAA} is +omitted, resume at the curent address of the @code{pc} register. + +returns the same replay as @code{last signal}. There is no immediate +replay to @code{cont} until the next breakpoint is reached, and the +program stops executing. + +@item step sAA..AA +@code{AA..AA} is address to resume +If @code{AA..AA} is omitted, resume at same address. + +returns the same replay as @code{last signal}. There is no immediate +replay to @code{step} until the next breakpoint is reached, and the +program stops executing. + +@item last signal @code{?} + +This returns one of the following: + +@itemize @bullet +@item @code{SAA} +Where @code{AA} is the number of the last signal. +Exceptions on the target are converted to the most similar Unix style +signal number, like @code{SIGSEGV}. A sample response of this type would +look like @code{$S05#}. + +@item TAAnn:XXXXXXXX;nn:XXXXXXXX;nn:XXXXXXXX; +@code{AA} is the signal number. +@code{nn} is the register number. +@code{XXXXXXXX} is the register value. + +@item WAA +The process exited, and @code{AA} is the exit status. This is only +applicable for certains sorts of targets. + +@end itemize + +These are used in some GDB backends, but not all. + +@item write reg @code{Pnn=XXXXXXXX} +Write register @code{nn} with value @code{XXXXXXXX}. + +returns @code{ACK} or @code{NAK} + +@item kill request k + +@item toggle debug d +toggle debug flag (see 386 & 68k stubs) + +@item reset r +reset -- see sparc stub. + +@item reserved @code{other} +On other requests, the stub should ignore the request and send an empty +response @code{$#<checksum>}. This way we can extend the protocol and GDB +can tell whether the stub it is talking to uses the old or the new. + +@item search @code{tAA:PP,MM} +Search backwards starting at address @code{AA} for a match with pattern +PP and mask @code{MM}. @code{PP} and @code{MM} are 4 bytes. + +@item general query @code{qXXXX} +Request info about XXXX. + +@item general set @code{QXXXX=yyyy} +Set value of @code{XXXX} to @code{yyyy}. + +@item query sect offs @code{qOffsets} +Get section offsets. Reply is @code{Text=xxx;Data=yyy;Bss=zzz} + +@item console output Otext +Send text to stdout. The text gets display from the target side of the +serial connection. + +@end table + +Responses can be run-length encoded to save space. A @code{*}means that +the next character is an ASCII encoding giving a repeat count which +stands for that many repetitions of the character preceding the @code{*}. +The encoding is n+29, yielding a printable character where n >=3 +(which is where run length encoding starts to win). You can't use a +value of where n >126 because it's only a two byte value. An example +would be a @code{0*03} means the same thing as @code{0000}. + +@node Exception handler, ROM monitors, GNU remote protocol, GDB +@section A linked in exception handler + +A @emph{GDB stub} consists of two parts, support for the exception +handler, and the exception handler itself. The exception handler needs +to communicate to GDB on the host whenever there is a breakpoint +exception. When GDB starts a program running on the target, it's polling +the serial port during execution looking for any debug packets. So when +a breakpoint occurs, the exception handler needs to save state, and send +a GDB remote protocol packet to GDB on the host. GDB takes any output +that isn't a debug command packet and displays it in the command window. + +Support for the exception handler varies between processors, but the +minimum supported functions are those needed by GDB. These are functions +to support the reading and writing of registers, the reading and writing +of memory, start execution at an address, single step, and last signal. +Sometimes other functions for adjusting the baud rate, or resetting the +hardware are implemented. + +Once GDB gets the command packet from the breakpoint, it will read a few +registers and memory locations an then wait for the user. When the user +types @code{run} or @code{continue} a @code{continue} command is issued +to the backend, and control returns from the breakpoint routine to the +application. + +@node ROM monitors, Other remote protocols, Exception handler, GDB +@section Using a ROM monitor as a backend +GDB also can mimic a human user and use a ROM monitors normal debug +commands as a backend. This consists mostly of sending and parsing +@code{ASCII} strings. All the ROM monitor interfaces share a common set +of routines in @code{gdb/monitor.c}. This supports adding new ROM +monitor interfaces by filling in a structure with the common commands +GDB needs. GDb already supports several command ROM monitors, including +Motorola's @code{Bug} monitor for their VME boards, and the Rom68k +monitor by Integrated Systems, Inc. for various m68k based boards. GDB +also supports the custom ROM monitors on the WinBond and Oki PA based +targets. There is builtin support for loading files to ROM monitors +specifically. GDB can convert a binary into an srecord and then load it +as an ascii file, or using @code{xmodem}. + +@c FIXME: do I need trademark somethings here ? Is Integrated the right +@c company? + +@node Other remote protocols, ,ROM monitors, GDB +@section Adding support for new protocols +@c FIXME: write something here + +@node Binutils, Code Listings, GDB, Top + +@node Code Listings, idp.ld, Binutils, Top +@appendix Code Listings + +@menu +* idp.ld:: A m68k linker script. +* crt0.S:: Crt0.S for an m68k. +* glue.c:: C based support for for Stdio functions. +* mvme.S:: Rom monitor based I/O support in assembler. +* io.c:: C based for memory mapped I/O. +* leds.c:: C based LED routines. +@end menu + +@node idp.ld, crt0.S, Code Listings, Code Listings +@section Linker script for the IDP board + +This is the linker script script that is used on the Motorola IDP board. + +@example +STARTUP(crt0.o) +OUTPUT_ARCH(m68k) +INPUT(idp.o) +SEARCH_DIR(.) +__DYNAMIC = 0; +/* + * Setup the memory map of the MC68ec0x0 Board (IDP) + * stack grows up towards high memory. This works for + * both the rom68k and the mon68k monitors. + */ +MEMORY +@{ + ram : ORIGIN = 0x10000, LENGTH = 2M +@} +/* + * stick everything in ram (of course) + */ +SECTIONS +@{ + .text : + @{ + CREATE_OBJECT_SYMBOLS + *(.text) + etext = .; + __CTOR_LIST__ = .; + LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) + *(.ctors) + LONG(0) + __CTOR_END__ = .; + __DTOR_LIST__ = .; + LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) + *(.dtors) + LONG(0) + __DTOR_END__ = .; + *(.lit) + *(.shdata) + @} > ram + .shbss SIZEOF(.text) + ADDR(.text) : @{ + *(.shbss) + @} + .talias : @{ @} > ram + .data : @{ + *(.data) + CONSTRUCTORS + _edata = .; + @} > ram + + .bss SIZEOF(.data) + ADDR(.data) : + @{ + __bss_start = ALIGN(0x8); + *(.bss) + *(COMMON) + end = ALIGN(0x8); + _end = ALIGN(0x8); + __end = ALIGN(0x8); + @} + .mstack : @{ @} > ram + .rstack : @{ @} > ram + .stab . (NOLOAD) : + @{ + [ .stab ] + @} + .stabstr . (NOLOAD) : + @{ + [ .stabstr ] + @} +@} +@end example + +@node crt0.S, glue.c, idp.ld, Code Listings +@section crt0.S - The startup file + +@example +/* + * crt0.S -- startup file for m68k-coff + * + */ + + .title "crt0.S for m68k-coff" + +/* These are predefined by new versions of GNU cpp. */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define d0 REG (d0) +#define d1 REG (d1) +#define d2 REG (d2) +#define d3 REG (d3) +#define d4 REG (d4) +#define d5 REG (d5) +#define d6 REG (d6) +#define d7 REG (d7) +#define a0 REG (a0) +#define a1 REG (a1) +#define a2 REG (a2) +#define a3 REG (a3) +#define a4 REG (a4) +#define a5 REG (a5) +#define a6 REG (a6) +#define fp REG (fp) +#define sp REG (sp) + +/* + * Set up some room for a stack. We just grab a chunk of memory. + */ + .set stack_size, 0x2000 + .comm SYM (stack), stack_size + +/* + * Define an empty environment. + */ + .data + .align 2 +SYM (environ): + .long 0 + + .align 2 + .text + .global SYM (stack) + + .global SYM (main) + .global SYM (exit) +/* + * This really should be __bss_start, not SYM (__bss_start). + */ + .global __bss_start + +/* + * start -- set things up so the application will run. + */ +SYM (start): + link a6, #-8 + moveal #SYM (stack) + stack_size, sp + +/* + * zerobss -- zero out the bss section + */ + moveal #__bss_start, a0 + moveal #SYM (end), a1 +1: + movel #0, (a0) + leal 4(a0), a0 + cmpal a0, a1 + bne 1b + +/* + * Call the main routine from the application to get it going. + * main (argc, argv, environ) + * We pass argv as a pointer to NULL. + */ + pea 0 + pea SYM (environ) + pea sp@@(4) + pea 0 + jsr SYM (main) + movel d0, sp@@- + +/* + * _exit -- Exit from the application. Normally we cause a user trap + * to return to the ROM monitor for another run. + */ +SYM (exit): + trap #0 +@end example + +@node glue.c, mvme.S, crt0.S, Code Listings +@section C based "glue" code. + +@example + +/* + * glue.c -- all the code to make GCC and the libraries run on + * a bare target board. These should work with any + * target if inbyte() and outbyte() exist. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#ifndef NULL +#define NULL 0 +#endif + +/* FIXME: this is a hack till libc builds */ +__main() +@{ + return; +@} + +#undef errno +int errno; + +extern caddr_t _end; /* _end is set in the linker command file */ +extern int outbyte(); +extern unsigned char inbyte(); +extern int havebyte(); + +/* just in case, most boards have at least some memory */ +#ifndef RAMSIZE +# define RAMSIZE (caddr_t)0x100000 +#endif + +/* + * read -- read bytes from the serial port. Ignore fd, since + * we only have stdin. + */ +int +read(fd, buf, nbytes) + int fd; + char *buf; + int nbytes; +@{ + int i = 0; + + for (i = 0; i < nbytes; i++) @{ + *(buf + i) = inbyte(); + if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) @{ + (*(buf + i)) = 0; + break; + @} + @} + return (i); +@} + +/* + * 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 +write(fd, buf, nbytes) + int fd; + char *buf; + int nbytes; +@{ + int i; + + for (i = 0; i < nbytes; i++) @{ + if (*(buf + i) == '\n') @{ + outbyte ('\r'); + @} + outbyte (*(buf + i)); + @} + return (nbytes); +@} + +/* + * open -- open a file descriptor. We don't have a filesystem, so + * we return an error. + */ +int +open(buf, flags, mode) + char *buf; + int flags; + int mode; +@{ + errno = EIO; + return (-1); +@} + +/* + * close -- close a file descriptor. We don't need + * to do anything, but pretend we did. + */ +int +close(fd) + int fd; +@{ + return (0); +@} + +/* + * sbrk -- changes heap size size. Get nbytes more + * RAM. We just increment a pointer in what's + * left of memory on the board. + */ +caddr_t +sbrk(nbytes) + int nbytes; +@{ + static caddr_t heap_ptr = NULL; + caddr_t base; + + if (heap_ptr == NULL) @{ + heap_ptr = (caddr_t)&_end; + @} + + if ((RAMSIZE - heap_ptr) >= 0) @{ + base = heap_ptr; + heap_ptr += nbytes; + return (base); + @} else @{ + errno = ENOMEM; + return ((caddr_t)-1); + @} +@} + +/* + * 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 +isatty(fd) + int fd; +@{ + return (1); +@} + +/* + * lseek -- move read/write pointer. Since a serial port + * is non-seekable, we return an error. + */ +off_t +lseek(fd, offset, whence) + int fd; + off_t offset; + int whence; +@{ + errno = ESPIPE; + return ((off_t)-1); +@} + +/* + * fstat -- get status of a file. Since we have no file + * system, we just return an error. + */ +int +fstat(fd, buf) + int fd; + struct stat *buf; +@{ + errno = EIO; + return (-1); +@} + +/* + * getpid -- only one process, so just return 1. + */ +#define __MYPID 1 +int +getpid() +@{ + return __MYPID; +@} + +/* + * kill -- go out via exit... + */ +int +kill(pid, sig) + int pid; + int sig; +@{ + if(pid == __MYPID) + _exit(sig); + return 0; +@} + +/* + * print -- do a raw print of a string + */ +int +print(ptr) +char *ptr; +@{ + while (*ptr) @{ + outbyte (*ptr++); + @} +@} + +/* + * putnum -- print a 32 bit number in hex + */ +int +putnum (num) +unsigned int num; +@{ + char buffer[9]; + int count; + char *bufptr = buffer; + int digit; + + for (count = 7 ; count >= 0 ; count--) @{ + digit = (num >> (count * 4)) & 0xf; + + if (digit <= 9) + *bufptr++ = (char) ('0' + digit); + else + *bufptr++ = (char) ('a' - 10 + digit); + @} + + *bufptr = (char) 0; + print (buffer); + return; +@} +@end example + +@node mvme.S, io.c, glue.c, Code Listings +@section I/O assembler code sample + +@example +/* + * mvme.S -- board support for m68k + */ + + .title "mvme.S for m68k-coff" + +/* These are predefined by new versions of GNU cpp. */ + +#ifndef __USER_LABEL_PREFIX__ +#define __USER_LABEL_PREFIX__ _ +#endif + +#ifndef __REGISTER_PREFIX__ +#define __REGISTER_PREFIX__ +#endif + +/* ANSI concatenation macros. */ + +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ + +#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) + +/* Use the right prefix for registers. */ + +#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x) + +#define d0 REG (d0) +#define d1 REG (d1) +#define d2 REG (d2) +#define d3 REG (d3) +#define d4 REG (d4) +#define d5 REG (d5) +#define d6 REG (d6) +#define d7 REG (d7) +#define a0 REG (a0) +#define a1 REG (a1) +#define a2 REG (a2) +#define a3 REG (a3) +#define a4 REG (a4) +#define a5 REG (a5) +#define a6 REG (a6) +#define fp REG (fp) +#define sp REG (sp) +#define vbr REG (vbr) + + .align 2 + .text + .global SYM (_exit) + .global SYM (outln) + .global SYM (outbyte) + .global SYM (putDebugChar) + .global SYM (inbyte) + .global SYM (getDebugChar) + .global SYM (havebyte) + .global SYM (exceptionHandler) + + .set vbr_size, 0x400 + .comm SYM (vbr_table), vbr_size + +/* + * inbyte -- get a byte from the serial port + * d0 - contains the byte read in + */ + .align 2 +SYM (getDebugChar): /* symbol name used by m68k-stub */ +SYM (inbyte): + link a6, #-8 + trap #15 + .word inchr + moveb sp@@, d0 + extbl d0 + unlk a6 + rts + +/* + * outbyte -- sends a byte out the serial port + * d0 - contains the byte to be sent + */ + .align 2 +SYM (putDebugChar): /* symbol name used by m68k-stub */ +SYM (outbyte): + link fp, #-4 + moveb fp@@(11), sp@@ + trap #15 + .word outchr + unlk fp + rts + +/* + * outln -- sends a string of bytes out the serial port with a CR/LF + * a0 - contains the address of the string's first byte + * a1 - contains the address of the string's last byte + */ + .align 2 +SYM (outln): + link a6, #-8 + moveml a0/a1, sp@@ + trap #15 + .word outln + unlk a6 + rts + +/* + * outstr -- sends a string of bytes out the serial port without a CR/LF + * a0 - contains the address of the string's first byte + * a1 - contains the address of the string's last byte + */ + .align 2 +SYM (outstr): + link a6, #-8 + moveml a0/a1, sp@@ + trap #15 + .word outstr + unlk a6 + rts + +/* + * havebyte -- checks to see if there is a byte in the serial port, + * returns 1 if there is a byte, 0 otherwise. + */ +SYM (havebyte): + trap #15 + .word instat + beqs empty + movel #1, d0 + rts +empty: + movel #0, d0 + rts + +/* + * These constants are for the MVME-135 board's boot monitor. They + * are used with a TRAP #15 call to access the monitor's I/O routines. + * they must be in the word following the trap call. + */ + .set inchr, 0x0 + .set instat, 0x1 + .set inln, 0x2 + .set readstr, 0x3 + .set readln, 0x4 + .set chkbrk, 0x5 + + .set outchr, 0x20 + .set outstr, 0x21 + .set outln, 0x22 + .set write, 0x23 + .set writeln, 0x24 + .set writdln, 0x25 + .set pcrlf, 0x26 + .set eraseln, 0x27 + .set writd, 0x28 + .set sndbrk, 0x29 + + .set tm_ini, 0x40 + .set dt_ini, 0x42 + .set tm_disp, 0x43 + .set tm_rd, 0x44 + + .set redir, 0x60 + .set redir_i, 0x61 + .set redir_o, 0x62 + .set return, 0x63 + .set bindec, 0x64 + + .set changev, 0x67 + .set strcmp, 0x68 + .set mulu32, 0x69 + .set divu32, 0x6A + .set chk_sum, 0x6B + +@end example + +@node io.c, leds.c, mvme.S, Code Listings +@section I/O code sample + +@example +#include "w89k.h" + +/* + * outbyte -- shove a byte out the serial port. We wait till the byte + */ +int +outbyte(byte) + unsigned char byte; +@{ + while ((inp(RS232REG) & TRANSMIT) == 0x0) @{ @} ; + return (outp(RS232PORT, byte)); +@} + +/* + * inbyte -- get a byte from the serial port + */ +unsigned char +inbyte() +@{ + while ((inp(RS232REG) & RECEIVE) == 0x0) @{ @}; + return (inp(RS232PORT)); +@} +@end example + +@node leds.c, ,io.c, Code Listings +@section Led control sample + +@example +/* + * leds.h -- control the led's on a Motorola mc68ec0x0 board. + */ + +#ifndef __LEDS_H__ +#define __LEDS_H__ + +#define LED_ADDR 0xd00003 +#define LED_0 ~0x1 +#define LED_1 ~0x2 +#define LED_2 ~0x4 +#define LED_3 ~0x8 +#define LED_4 ~0x10 +#define LED_5 ~0x20 +#define LED_6 ~0x40 +#define LED_7 ~0x80 +#define LEDS_OFF 0xff +#define LEDS_ON 0x0 + +#define FUDGE(x) ((x >= 0xa && x <= 0xf) ? (x + 'a') & 0x7f : (x + '0') & 0x7f) + +extern void led_putnum( char ); + +#endif /* __LEDS_H__ */ + +/* + * leds.c -- control the led's on a Motorola mc68ec0x0 (IDP)board. + */ +#include "leds.h" + +void zylons(); +void led_putnum(); + +/* + * led_putnum -- print a hex number on the LED. the value of num must be a char with + * the ascii value. ie... number 0 is '0', a is 'a', ' ' (null) clears + * the led display. + * Setting the bit to 0 turns it on, 1 turns it off. + * the LED's are controlled by setting the right bit mask in the base + * address. + * The bits are: + * [d.p | g | f | e | d | c | b | a ] is the byte. + * + * The locations are: + * + * a + * ----- + * f | | b + * | g | + * ----- + * | | + * e | | c + * ----- + * d . d.p (decimal point) + */ +void +led_putnum ( num ) +char num; +@{ + static unsigned char *leds = (unsigned char *)LED_ADDR; + static unsigned char num_bits [18] = @{ + 0xff, /* clear all */ + 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */ + 0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe /* letters a-f */ + @}; + + if (num >= '0' && num <= '9') + num = (num - '0') + 1; + + if (num >= 'a' && num <= 'f') + num = (num - 'a') + 12; + + if (num == ' ') + num = 0; + + *leds = num_bits[num]; +@} + +/* + * zylons -- draw a rotating pattern. NOTE: this function never returns. + */ +void +zylons() +@{ + unsigned char *leds = (unsigned char *)LED_ADDR; + unsigned char curled = 0xfe; + + while (1) + @{ + *leds = curled; + curled = (curled >> 1) | (curled << 7); + delay ( 200 ); + @} +@} +@end example + +@page +@contents +@c second page break makes sure right-left page alignment works right +@c with a one-page toc, even though we don't have setchapternewpage odd. +@page +@bye |