aboutsummaryrefslogtreecommitdiff
path: root/libgloss/sparc
diff options
context:
space:
mode:
authorRanjith Kumaran <ranjith@cygnus.com>2000-03-17 22:48:54 +0000
committerRanjith Kumaran <ranjith@cygnus.com>2000-03-17 22:48:54 +0000
commit03261851a10dd2d6900a0a00a7515a0a46fb5d76 (patch)
tree7c22ac6cbbc99fd5cd1b5426853be8d4fd7bfcf1 /libgloss/sparc
parentfae4c299f14fc23e2829c8656992eba21f79242a (diff)
downloadnewlib-03261851a10dd2d6900a0a00a7515a0a46fb5d76.zip
newlib-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.gz
newlib-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.bz2
20000317 sourceware import
Diffstat (limited to 'libgloss/sparc')
-rw-r--r--libgloss/sparc/Makefile.in286
-rw-r--r--libgloss/sparc/asm.h39
-rw-r--r--libgloss/sparc/cache.c147
-rwxr-xr-xlibgloss/sparc/configure1201
-rw-r--r--libgloss/sparc/configure.in120
-rw-r--r--libgloss/sparc/crt0-701.S105
-rw-r--r--libgloss/sparc/crt0.S186
-rw-r--r--libgloss/sparc/cygmon-crt0.S144
-rw-r--r--libgloss/sparc/cygmon-salib.c220
-rw-r--r--libgloss/sparc/cygmon-sparc64-ld.src159
-rw-r--r--libgloss/sparc/cygmon.ld.src195
-rw-r--r--libgloss/sparc/dtor.C25
-rw-r--r--libgloss/sparc/elfsim.ld202
-rw-r--r--libgloss/sparc/erc32-crt0.S75
-rw-r--r--libgloss/sparc/erc32-io.c47
-rw-r--r--libgloss/sparc/erc32-stub.c363
-rw-r--r--libgloss/sparc/erc32.ld146
-rw-r--r--libgloss/sparc/ex930.ld160
-rw-r--r--libgloss/sparc/ex931.ld160
-rw-r--r--libgloss/sparc/ex934.ld160
-rw-r--r--libgloss/sparc/fixctors.c54
-rw-r--r--libgloss/sparc/libsys/Makefile.in167
-rw-r--r--libgloss/sparc/libsys/_exit.S14
-rw-r--r--libgloss/sparc/libsys/cerror.S47
-rwxr-xr-xlibgloss/sparc/libsys/configure991
-rw-r--r--libgloss/sparc/libsys/configure.in50
-rw-r--r--libgloss/sparc/libsys/isatty.c17
-rw-r--r--libgloss/sparc/libsys/libsys-crt0.S127
-rw-r--r--libgloss/sparc/libsys/sbrk.S66
-rw-r--r--libgloss/sparc/libsys/syscall.h39
-rw-r--r--libgloss/sparc/libsys/syscallasm.h93
-rw-r--r--libgloss/sparc/libsys/template.S14
-rw-r--r--libgloss/sparc/libsys/template_r.S26
-rw-r--r--libgloss/sparc/salib-701.c288
-rw-r--r--libgloss/sparc/salib.c388
-rw-r--r--libgloss/sparc/slite.h127
-rw-r--r--libgloss/sparc/sparc-stub.c848
-rw-r--r--libgloss/sparc/sparc86x.ld177
-rw-r--r--libgloss/sparc/sparcl-stub.c1005
-rw-r--r--libgloss/sparc/sparclet-stub.c1233
-rw-r--r--libgloss/sparc/sparclite.h81
-rw-r--r--libgloss/sparc/sysc-701.c55
-rw-r--r--libgloss/sparc/syscalls.c85
-rw-r--r--libgloss/sparc/test.c69
-rw-r--r--libgloss/sparc/traps.S651
-rw-r--r--libgloss/sparc/tsc701.ld55
46 files changed, 10907 insertions, 0 deletions
diff --git a/libgloss/sparc/Makefile.in b/libgloss/sparc/Makefile.in
new file mode 100644
index 0000000..fcf5448
--- /dev/null
+++ b/libgloss/sparc/Makefile.in
@@ -0,0 +1,286 @@
+# Copyright (c) 1995, 1996, 1997 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.
+
+# Makefile for libgloss/sparc. This is the board support
+# code for the various sparc targets.
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+objdir = .
+srcroot = $(srcdir)/../..
+objroot = $(objdir)/../..
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+
+bindir = @bindir@
+libdir = @libdir@
+tooldir = $(exec_prefix)/$(target_alias)
+
+# Multilib support variables.
+# TOP is used instead of MULTI{BUILD,SRC}TOP.
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SHELL = /bin/sh
+
+CC = @CC@
+
+AS = @AS@
+AR = @AR@
+LD = @LD@
+RANLIB = @RANLIB@
+AR_FLAGS = qrv
+
+OBJDUMP = `if [ -f ${objroot}/../binutils/objdump ] ; \
+ then echo ${objroot}/../binutils/objdump ; \
+ else t='$(program_transform_name)'; echo objdump | sed -e $$t ; fi`
+OBJCOPY = `if [ -f ${objroot}/../binutils/objcopy ] ; \
+ then echo ${objroot}/../binutils/objcopy ; \
+ else t='$(program_transform_name)'; echo objcopy | sed -e $$t ; fi`
+
+CYGMON_CRT0 = cygmon-crt0.o
+CYGMON_BSP = libcygmon.a
+CYGMON_OBJS = cygmon-salib.o
+
+701_CRT0 = crt0-701.o
+701_BSP = libsplet701.a
+701_OBJS = sysc-701.o salib-701.o sparclet-stub.o
+
+930_BSP = libslite930.a
+931_BSP = libslite931.a
+934_BSP = libslite934.a
+86X_BSP = libslite86x.a
+
+# for the time being, built the stub without hardware breakpoint support
+SLITE_OBJS = salib.o sparcl-stub.o cache.o
+
+# ERC32: SIS simulator, see sim/erc32.
+ERC32_CRT0 = erc32-crt0.o
+ERC32_BSP = liberc32.a
+ERC32_OBJS = erc32-io.o traps.o erc32-stub.o debug.o fixctors.o
+ERC32_ALL = $(ERC32_CRT0) $(ERC32_BSP)
+
+CRT0 = crt0.o
+OBJS = close.o fstat.o getpid.o isatty.o kill.o \
+ lseek.o open.o print.o putnum.o read.o sbrk.o stat.o \
+ unlink.o write.o
+
+# This is set to one of SPARC, SLITE, or SPLET by configure.
+# It's not clear what to do here.
+# One could certainly build everything. The assembler supports all cpu
+# variants (via runtime switches). However, the compiler [currently] doesn't.
+# Of course, it may be the case that there isn't any cpu specific code in
+# C source files, but there might be in the future.
+CPU = @CPU@
+
+# sparc stuff (not sparclite or sparclet)
+SPARC_ALL = $(CYGMON_BSP) $(CYGMON_CRT0) $(objdir)/cygmon.ld
+SPARC_INSTALL = sparc-install
+SPARC_OBJ_FORMAT = sparc
+SPARC_RAM_START = 0x4000
+
+# sparc 64 stuff
+SPARC64_ALL = $(CYGMON_BSP) $(CYGMON_CRT0) $(objdir)/cygmon.ld
+SPARC64_INSTALL = sparc-install
+SPARC64_OBJ_FORMAT = sparc:v9
+SPARC64_RAM_START = 0x4000
+
+# sparclite stuff
+SLITE_ALL = $(930_BSP) $(931_BSP) $(CYGMON_BSP) $(CYGMON_CRT0) $(objdir)/cygmon.ld $(934_BSP) $(86X_BSP)
+SLITE_INSTALL = slite-install
+SLITE_OBJ_FORMAT = sparc
+SLITE_RAM_START = 0x40050000
+
+# sparclet stuff
+SPLET_ALL = $(701_CRT0) $(701_BSP)
+SPLET_INSTALL = splet-install
+
+#### Host specific Makefile fragment comes in here.
+@host_makefile_frag@
+
+all: ${CRT0} $($(CPU)_ALL) $(ERC32_ALL)
+
+$(CYGMON_CRT0): cygmon-crt0.S
+ $(CC) $(CFLAGS_FOR_TARGET) $(CFLAGS) -DTARGET_CPU_$(CPU) $(INCLUDES) -o $@ -c $(srcdir)/cygmon-crt0.S
+
+$(CYGMON_BSP): $(CYGMON_OBJS)
+ @rm -f $@
+ ${AR} ${AR_FLAGS} $@ $(CYGMON_OBJS)
+ ${RANLIB} $@
+
+#$(STUBLIBS): $(OBJS) $(SLITE_OBJS) $(CRT0)
+# ${CC} -nostdlib -r $(SLITE_OBJS) $(SHARED_OBJS) -o $(930_BSP)
+# ${CC} -DSL931 -nostdlib -r $(SLITE_OBJS) $(SHARED_OBJS) -o $(931_BSP)
+# ${CC} -nostdlib -r $(SLITE_OBJS) $(SHARED_OBJS) -o $(934_BSP)
+
+$(CRT0): $(srcdir)/crt0.S $(srcdir)/asm.h $(srcdir)/slite.h
+ $(CC) $(CFLAGS_FOR_TARGET) $(CFLAGS) $(INCLUDES) -o $@ -c $(srcdir)/crt0.S
+
+$(930_BSP) $(931_BSP) $(934_BSP) $(86X_BSP): $(OBJS) $(SLITE_OBJS)
+ @rm -f $@
+ ${AR} ${AR_FLAGS} $@ $(OBJS) $(SLITE_OBJS)
+ ${RANLIB} $@
+
+$(701_BSP): $(701_OBJS)
+ @rm -f $@
+ ${AR} ${AR_FLAGS} $@ $(701_OBJS)
+ ${RANLIB} $@
+
+erc32-crt0.o: $(srcdir)/erc32-crt0.S $(srcdir)/asm.h $(srcdir)/slite.h
+ $(CC) $(CFLAGS_FOR_TARGET) $(CFLAGS) $(INCLUDES) -o $@ -c $(srcdir)/erc32-crt0.S
+
+liberc32.a: $(OBJS) $(ERC32_OBJS)
+ @rm -f $@
+ ${AR} ${AR_FLAGS} $@ $(OBJS) $(ERC32_OBJS)
+ ${RANLIB} $@
+
+crt0-701.o: crt0-701.S
+sysc-701.o: sysc-701.c
+salib-701.o: salib-701.c
+sparclet-stub.o: sparclet-stub.c
+cygmon-salib.o: cygmon-salib.c
+ $(CC) -DTARGET_CPU_$(CPU) $(CFLAGS_FOR_TARGET) $(CFLAGS) $(INCLUDES) -o $@ -c $(srcdir)/cygmon-salib.c
+cache.o: $(srcdir)/cache.c
+salib.o: $(srcdir)/salib.c
+win.o: $(srcdir)/win.S
+syscalls.o: $(srcdir)/syscalls.c
+sparcl-stub.o: $(srcdir)/sparcl-stub.c $(srcdir)/../debug.h $(srcdir)/../debug.c
+erc32-stub.o: $(srcdir)/erc32-stub.c $(srcdir)/../debug.h $(srcdir)/../debug.c
+fixctors.o : $(srcdir)/fixctors.c
+
+$(objdir)/cygmon.ld: @CYGMONLDSCRIPTTEMPL@
+ sed 's/TARGET_OBJ_FORMAT/$($(CPU)_OBJ_FORMAT)/g;s/TARGET_RAM_START/$($(CPU)_RAM_START)/g;' < $(<) > $(objdir)/cygmon.ld
+
+install: $($(CPU)_INSTALL)
+ $(INSTALL_DATA) $(CRT0) $(tooldir)/lib${MULTISUBDIR}/$(CRT0)
+
+sparc-install:
+ $(INSTALL_DATA) $(CYGMON_BSP) $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(CYGMON_OBJS) $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(objdir)/cygmon.ld $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(CYGMON_CRT0) $(tooldir)/lib${MULTISUBDIR}
+
+slite-install:
+ $(INSTALL_DATA) $(930_BSP) $(tooldir)/lib${MULTISUBDIR}/$(930_BSP)
+ $(INSTALL_DATA) $(931_BSP) $(tooldir)/lib${MULTISUBDIR}/$(931_BSP)
+ $(INSTALL_DATA) $(934_BSP) $(tooldir)/lib${MULTISUBDIR}/$(934_BSP)
+ $(INSTALL_DATA) $(86X_BSP) $(tooldir)/lib${MULTISUBDIR}/$(86X_BSP)
+ $(INSTALL_DATA) $(srcdir)/ex930.ld $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(srcdir)/ex931.ld $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(srcdir)/ex934.ld $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(srcdir)/sparc86x.ld $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(srcdir)/elfsim.ld $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(ERC32_CRT0) $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(ERC32_BSP) $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(objdir)/traps.o $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(CYGMON_BSP) $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(CYGMON_OBJS) $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(objdir)/cygmon.ld $(tooldir)/lib${MULTISUBDIR}
+ $(INSTALL_DATA) $(CYGMON_CRT0) $(tooldir)/lib${MULTISUBDIR}
+
+splet-install:
+ $(INSTALL_DATA) $(701_CRT0) $(tooldir)/lib${MULTISUBDIR}/$(701_CRT0)
+ $(INSTALL_DATA) $(701_BSP) $(tooldir)/lib${MULTISUBDIR}/$(701_BSP)
+ $(INSTALL_DATA) $(srcdir)/tsc701.ld $(tooldir)/lib${MULTISUBDIR}
+
+# Make a simple test case to test the linker script, startup code, and
+# I/O code
+#
+test: ex930-test.x ex931-test.x erc32-test.x
+ @echo Done...
+
+# compile a fully linked binary. The -N option is for a.out, so the
+# base address will be zero, rather than the default of 0x2020. The
+# -Wl,-T*.ld is for the linker script. By using -Wl, the linker script
+# is put on the proper place in the comand line for ld, and all the
+# symbols will get fully resolved.
+
+erc32-test.x: test.o ${ERC32_CRT0} ${srcdir}/erc32.ld Makefile ${ERC32_BSP}
+ ${CC} -L${srcdir} -L${objdir} test.o -o $@ $(LDFLAGS_FOR_TARGET) \
+ -N -Wl,-Terc32.ld -Wl,-Map -Wl,erc32.map -nostdlib
+erc32-test.srec: erc32-test.x
+ $(OBJCOPY) -O srec erc32-test.x $@
+erc32-test.dis: erc32-test.x
+ @rm -fr erc32-test.dis
+ $(OBJDUMP) -d erc32-test.x > $@
+erc32-test: erc32-test.srec erc32-test.dis
+
+ex930-test.x: test.o ${CRT0} ${srcdir}/ex930.ld Makefile ${930_BSP}
+ ${CC} -L${srcdir} -L${objdir} test.o -o $@ $(LDFLAGS_FOR_TARGET) \
+ -N -Wl,-Tex930.ld -nostdlib
+ex930-test.srec: ex930-test.x
+ $(OBJCOPY) -O srec ex930-test.x $@
+ex930-test.dis: ex930-test.x
+ @rm -fr ex930-test.dis
+ $(OBJDUMP) -d ex930-test.x > $@
+ex930-test: ex930-test.srec ex930-test.dis
+
+ex931-test.x: test.o ${CRT0} ${srcdir}/ex931.ld Makefile ${931_BSP}
+ ${CC} -L${srcdir} -L${objdir} test.o -o $@ $(LDFLAGS_FOR_TARGET) \
+ -N -Wl,-Tex931.ld -nostdlib
+ex931-test.srec: ex931-test.x
+ $(OBJCOPY) -O srec ex931-test.x $@
+ex931-test.dis: ex931-test.x
+ @rm -fr ex931-test.dis
+ $(OBJDUMP) -d ex931-test.x > $@
+ex931-test: ex931-test.srec ex931-test.dis
+
+ex934-test.x: test.o ${CRT0} ${srcdir}/ex934.ld Makefile ${934_BSP}
+ ${CC} -L${srcdir} -L${objdir} test.o -o $@ $(LDFLAGS_FOR_TARGET) \
+ -N -Wl,-Tex934.ld -nostdlib
+ex934-test.srec: ex934-test.x
+ $(OBJCOPY) -O srec ex934-test.x $@
+ex934-test.dis: ex934-test.x
+ @rm -fr ex934-test.dis
+ $(OBJDUMP) -d ex934-test.x > $@
+ex934-test: ex934-test.srec ex934-test.dis
+
+# a C++ test case
+dtor.o: $(srcdir)/dtor.C
+ $(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -o $@ -c $?
+dtor.dis: dtor.x
+ @rm -fr dtor.dis
+ $(OBJDUMP) -d dtor.x > $@
+dtor.x: dtor.o ${ERC32_CRT0} ${srcdir}/erc32.ld Makefile ${ERC32_BSP}
+ ${CC} -L${srcdir} -L${objdir} dtor.o -o $@ $(LIBS_FOR_TARGET) \
+ -N -Wl,-Terc32.ld
+
+# target specific makefile fragment comes in here.
+@target_makefile_frag@
+
+clean mostlyclean:
+ rm -f *.o *.a *.map *.x
+
+distclean maintainer-clean realclean: clean
+ rm -f Makefile config.cache config.log config.status
+
+.PHONY: info dvi doc install-info clean-info
+info doc dvi:
+install-info:
+clean-info:
+
+Makefile: Makefile.in config.status @host_makefile_frag_path@ \
+ @target_makefile_frag_path@
+ $(SHELL) config.status
+
+config.status: configure
+ $(SHELL) config.status --recheck
diff --git a/libgloss/sparc/asm.h b/libgloss/sparc/asm.h
new file mode 100644
index 0000000..daeff34
--- /dev/null
+++ b/libgloss/sparc/asm.h
@@ -0,0 +1,39 @@
+/* asm.h -- macros for sparc asm
+ *
+ * Copyright (c) 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.
+ */
+
+#ifndef __SPARC_ASM_h
+#define __SPARC_ASM_h
+
+/* Indicate we are in an assembly file and get the basic CPU definitions. */
+#define ASM
+
+/* ANSI concatenation macros. */
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.
+ Note that it's too late to have coff have no underscores
+ (would break user programs).
+ One school of thought likes having underscores for both a.out and coff
+ (simplicity in consistency). */
+#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__,x)
+
+/* STRINGSYM makes a string out of a symbol name with the proper assembly
+ prefix. Useful for inline assembly language in C source files. */
+#define STRINGIT2(x) #x
+#define STRINGIT1(x) STRINGIT2(x)
+#define STRINGSYM(x) STRINGIT1(SYM(x))
+
+#endif
diff --git a/libgloss/sparc/cache.c b/libgloss/sparc/cache.c
new file mode 100644
index 0000000..5b6e270
--- /dev/null
+++ b/libgloss/sparc/cache.c
@@ -0,0 +1,147 @@
+/* Cache code for SPARClite
+ *
+ * Copyright (c) 1998 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include "sparclite.h"
+
+/* Ancillary registers on the DANlite */
+
+#define DIAG 30
+#define ICCR 31
+
+/* Bits in the DIAG register */
+
+#define ICD 0x40000000 /* ICACHE disable */
+#define DCD 0x20000000 /* DCACHE disable */
+
+/* Bits in the ICCR register */
+
+#define CE 1 /* cache enable*/
+
+
+/* Forward declarations. */
+
+void flush_i_cache ();
+
+
+/* Determine if this is a DANlite (MB8686x), as opposed to an earlier
+ SPARClite (MB8683x). This is done by examining the impl and ver
+ fields in the PSR:
+
+ MB8683x: impl(bit31-28)=0x0; ver(bit27-24)=0xf;
+ MB8686x: impl(bit31-28)=0x1; ver(bit27-24)=0xe;
+*/
+
+static int
+is_danlite ()
+{
+ static int checked = 0;
+ static int danlite = 0;
+
+ if (!checked)
+ {
+ int psr = read_psr ();
+ danlite = (psr & 0xff000000) == 0x1e000000;
+ checked = 1;
+ }
+ return danlite;
+}
+
+/* This cache code is known to work on both the 930 & 932 processors. It just
+ cheats and clears the all of the address space that could contain tags, as
+ opposed to striding the tags at 8 or 16 word intervals, or using the cache
+ flush registers, which don't exist on all processors. */
+
+void
+cache_off ()
+{
+ if (is_danlite ())
+ {
+ /* Disable the ICACHE. Disabling the DCACHE crashes the machine. */
+ unsigned int diag = read_asr (DIAG);
+ write_asr (DIAG, diag | ICD);
+ }
+ else
+ {
+ write_asi (1, 0, 0);
+ }
+}
+
+void
+cache_on ()
+{
+ if (is_danlite ())
+ {
+ unsigned int diag;
+
+ /* Flush the caches. */
+ flush_i_cache ();
+
+ /* Enable the ICACHE and DCACHE */
+ diag = read_asr (DIAG);
+ write_asr (DIAG, diag & ~ (ICD | DCD));
+ }
+ else
+ {
+ unsigned long addr;
+
+ cache_off (); /* Make sure the cache is off */
+
+ /* Reset all of the cache line valid bits */
+
+ for (addr = 0; addr < 0x1000; addr += 8)
+ {
+ write_asi (0xc, addr, 0); /* Clear bank 1, icache */
+ write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
+
+ write_asi (0xe, addr, 0); /* Clear bank 1, dcache */
+ write_asi (0xe, addr + 0x80000000, 0); /* Clear bank 2, dcache */
+ }
+
+ /* turn on the cache */
+
+ write_asi (1, 0, 0x35); /* Write buf ena, prefetch buf ena, data
+ & inst caches enab */
+ }
+}
+
+/* Flush the instruction cache. We need to do this for the debugger stub so
+ that breakpoints, et. al. become visible to the instruction stream after
+ storing them in memory.
+ */
+
+void
+flush_i_cache ()
+{
+ if (is_danlite ())
+ {
+ write_asi (0x31, 0, 0); /* Flush entire i/d caches */
+ }
+ else
+ {
+ int cache_reg;
+ unsigned long addr;
+
+ cache_reg = read_asi (1, 0); /* Read cache/bus interface reg */
+
+ if (!(cache_reg & 1))
+ return; /* Just return if cache is already off */
+
+ for (addr = 0; addr < 0x1000; addr += 8)
+ {
+ write_asi (0xc, addr, 0); /* Clear bank 1, icache */
+ write_asi (0xc, addr + 0x80000000, 0); /* Clear bank 2, icache */
+ }
+ }
+}
diff --git a/libgloss/sparc/configure b/libgloss/sparc/configure
new file mode 100755
index 0000000..8c5c76c
--- /dev/null
+++ b/libgloss/sparc/configure
@@ -0,0 +1,1201 @@
+#! /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=sparc-stub.c
+
+# 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 "${enable_shared}" = "yes" ; then
+ echo "Shared libraries not supported for cross compiling, ignored"
+fi
+
+if test "$srcdir" = "." ; then
+ if test "${with_target_subdir}" != "." ; then
+ libgloss_topdir="${with_multisrctop}../../.."
+ else
+ libgloss_topdir="${with_multisrctop}../.."
+ fi
+else
+ libgloss_topdir="${srcdir}/../.."
+fi
+
+ac_aux_dir=
+for ac_dir in $libgloss_topdir $srcdir/$libgloss_topdir; 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 $libgloss_topdir $srcdir/$libgloss_topdir" 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.
+
+
+# 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:570: 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'
+
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:649: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:670: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:688: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+
+# FIXME: We temporarily define our own version of AC_PROG_CC. This is
+# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
+# are probably using a cross compiler, which will not be able to fully
+# link an executable. This should really be fixed in autoconf
+# itself.
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:722: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:751: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:799: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:808: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:823: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+AS=${AS-as}
+
+AR=${AR-ar}
+
+LD=${LD-ld}
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:859: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+case ${target_cpu} in
+sparclite*) CPU=SLITE ;;
+sparclet*) CPU=SPLET ;;
+sparc64*) CPU=SPARC64 ;;
+sparc86x*) CPU=SLITE ;;
+*) CPU=SPARC ;;
+esac
+
+
+case ${target_cpu} in
+sparc64*) CYGMONLDSCRIPTTEMPL=${srcdir}/cygmon-sparc64-ld.src ;;
+*) CYGMONLDSCRIPTTEMPL=${srcdir}/cygmon.ld.src
+esac
+
+host_makefile_frag=${srcdir}/../config/default.mh
+target_makefile_frag=${srcdir}/../config/default.mt
+
+host_makefile_frag_path=$host_makefile_frag
+
+
+target_makefile_frag_path=$target_makefile_frag
+
+
+
+
+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` 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
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CC@%$CC%g
+s%@AS@%$AS%g
+s%@AR@%$AR%g
+s%@LD@%$LD%g
+s%@RANLIB@%$RANLIB%g
+s%@CPU@%$CPU%g
+s%@host_makefile_frag_path@%$host_makefile_frag_path%g
+/@host_makefile_frag@/r $host_makefile_frag
+s%@host_makefile_frag@%%g
+s%@target_makefile_frag_path@%$target_makefile_frag_path%g
+/@target_makefile_frag@/r $target_makefile_frag
+s%@target_makefile_frag@%%g
+s%@CYGMONLDSCRIPTTEMPL@%$CYGMONLDSCRIPTTEMPL%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
+srcdir=${srcdir}
+target=${target}
+ac_configure_args="${ac_configure_args} --enable-multilib"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+libgloss_topdir=${libgloss_topdir}
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+. ${libgloss_topdir}/config-ml.in
+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/sparc/configure.in b/libgloss/sparc/configure.in
new file mode 100644
index 0000000..c836f6c
--- /dev/null
+++ b/libgloss/sparc/configure.in
@@ -0,0 +1,120 @@
+# 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.
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.5)dnl
+AC_INIT(sparc-stub.c)
+
+if test "${enable_shared}" = "yes" ; then
+ echo "Shared libraries not supported for cross compiling, ignored"
+fi
+
+if test "$srcdir" = "." ; then
+ if test "${with_target_subdir}" != "." ; then
+ libgloss_topdir="${with_multisrctop}../../.."
+ else
+ libgloss_topdir="${with_multisrctop}../.."
+ fi
+else
+ libgloss_topdir="${srcdir}/../.."
+fi
+
+AC_CONFIG_AUX_DIR($libgloss_topdir)
+
+AC_PROG_INSTALL
+
+AC_CANONICAL_SYSTEM
+
+# FIXME: We temporarily define our own version of AC_PROG_CC. This is
+# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
+# are probably using a cross compiler, which will not be able to fully
+# link an executable. This should really be fixed in autoconf
+# itself.
+
+AC_DEFUN(LIB_AC_PROG_CC,
+[AC_BEFORE([$0], [AC_PROG_CPP])dnl
+AC_CHECK_PROG(CC, gcc, gcc)
+if test -z "$CC"; then
+ AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
+ test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
+fi
+
+AC_PROG_CC_GNU
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+dnl Check whether -g works, even if CFLAGS is set, in case the package
+dnl plays around with CFLAGS (such as to build both debugging and
+dnl normal versions of a library), tasteless as that idea is.
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ AC_PROG_CC_G
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+])
+
+LIB_AC_PROG_CC
+AS=${AS-as}
+AC_SUBST(AS)
+AR=${AR-ar}
+AC_SUBST(AR)
+LD=${LD-ld}
+AC_SUBST(LD)
+AC_PROG_RANLIB
+
+case ${target_cpu} in
+sparclite*) CPU=SLITE ;;
+sparclet*) CPU=SPLET ;;
+sparc64*) CPU=SPARC64 ;;
+sparc86x*) CPU=SLITE ;;
+*) CPU=SPARC ;;
+esac
+AC_SUBST(CPU)
+
+case ${target_cpu} in
+sparc64*) CYGMONLDSCRIPTTEMPL=${srcdir}/cygmon-sparc64-ld.src ;;
+*) CYGMONLDSCRIPTTEMPL=${srcdir}/cygmon.ld.src
+esac
+
+host_makefile_frag=${srcdir}/../config/default.mh
+target_makefile_frag=${srcdir}/../config/default.mt
+
+dnl We have to assign the same value to other variables because autoconf
+dnl doesn't provide a mechanism to substitute a replacement keyword with
+dnl arbitrary data or pathnames.
+dnl
+host_makefile_frag_path=$host_makefile_frag
+AC_SUBST(host_makefile_frag_path)
+AC_SUBST_FILE(host_makefile_frag)
+target_makefile_frag_path=$target_makefile_frag
+AC_SUBST(target_makefile_frag_path)
+AC_SUBST_FILE(target_makefile_frag)
+AC_SUBST(CYGMONLDSCRIPTTEMPL)
+
+AC_OUTPUT(Makefile,
+. ${libgloss_topdir}/config-ml.in,
+srcdir=${srcdir}
+target=${target}
+ac_configure_args="${ac_configure_args} --enable-multilib"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+libgloss_topdir=${libgloss_topdir}
+)
+
diff --git a/libgloss/sparc/crt0-701.S b/libgloss/sparc/crt0-701.S
new file mode 100644
index 0000000..44ffadc
--- /dev/null
+++ b/libgloss/sparc/crt0-701.S
@@ -0,0 +1,105 @@
+/* crt0.S for the sparclet 701.
+
+ At the moment, all the necessary syscalls are here.
+ Convention has them in a separate file but libgloss is still in
+ too much flux. */
+
+ .text
+
+ .global start
+start:
+
+! zero bss
+
+ sethi %hi(_end), %o1
+ or %o1, %lo(_end), %o1
+ sethi %hi(_edata), %o0
+ or %o0, %lo (_edata), %o0
+ sub %o1, %o0, %o1
+Lzero_bss:
+ subcc %o1, 4, %o1
+ clr [%o0]
+ bne Lzero_bss
+ add %o0, 4, %o0
+
+! set up argc, argv, envp (?)
+
+ ld [%sp+64], %o0
+ sll %o0, 2, %o2
+ add %o2, 4, %o2
+ add %sp, 68, %o1
+ add %o1, %o2, %o2
+ sethi %hi(_environ), %o3
+ st %o2, [%o3+%lo(_environ)]
+
+! call main, exit
+
+ call _main
+ sub %sp, 32, %sp
+ call _exit
+ nop
+
+! void _exit (int rc)
+
+ .global __exit
+__exit:
+ mov 1, %g1
+ ta 0
+! If that does not work, just loop forever.
+Lloop_forever:
+ b Lloop_forever
+ nop
+
+! int _open (char *, int)
+
+ .global _open
+_open:
+ mov 5, %g1
+ ta 0
+ bcc Lnoerr
+ nop
+ b Lcerror
+ nop
+
+! int _close (int)
+
+ .global _close
+_close:
+ mov 6, %g1
+ ta 0
+ bcc Lnoerr
+ nop
+ b Lcerror
+ nop
+
+! int read (int, char *, int)
+
+ .global _read
+_read:
+ mov 3, %g1
+ ta 0
+ bcc Lnoerr
+ nop
+ b Lcerror
+ nop
+
+! int write (int, char *, int)
+
+ .global _write
+_write:
+ mov 4, %g1
+ ta 0
+ bcc Lnoerr
+ nop
+ b Lcerror
+ nop
+
+Lnoerr:
+ retl
+ nop
+
+Lcerror:
+ sethi %hi(__impure_ptr), %g1
+ st %o0, [%g1+%lo(__impure_ptr)]
+ retl
+ mov -1, %o0
diff --git a/libgloss/sparc/crt0.S b/libgloss/sparc/crt0.S
new file mode 100644
index 0000000..90e18c5
--- /dev/null
+++ b/libgloss/sparc/crt0.S
@@ -0,0 +1,186 @@
+/*
+ * C startup code for the Fujitsu SPARClite demo board
+ *
+ * Copyright (c) 1995, 1996 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include "asm.h"
+
+.data
+ .align 8
+ .ascii "DaTa" ! this is the first address in the data section
+ .long SYM(sdata)
+SYM(environ):
+ .long 0
+
+ .text
+ .align 8
+
+ .globl SYM(_start)
+SYM(_start):
+ .globl SYM(start)
+SYM(start):
+ /* see if the stack is already setup. if not, then default
+ * to using the value of %sp as set by the ROM monitor
+ */
+ sethi %hi(__stack), %g1
+ or %g1,%lo(__stack),%g1
+ cmp %g0,%g1
+ be 1f
+ mov %g1, %sp ! set the stack pointer
+ mov %sp, %fp
+1:
+
+ /* zero the bss section */
+ sethi %hi(__bss_start),%g2
+ or %g2,%lo(__bss_start),%g2 ! start of bss
+ sethi %hi(_end),%g3
+ or %g3,%lo(_end),%g3 ! end of bss
+ mov %g0,%g1 ! so std has two zeros
+zerobss:
+ std %g0,[%g2]
+ add %g2,8,%g2
+ cmp %g2,%g3
+ bleu,a zerobss
+ nop
+
+/*
+ * copy prom & trap vectors to sram.
+ */
+ set 0x30000000, %l0
+ set 0xfff8, %l1
+ tst %l1 ! Set condition codes
+
+copyloop:
+ ldd [%l1], %l2
+ std %l2, [%l0 + %l1]
+ bg copyloop
+ deccc 8, %l1
+
+ set 0x30000000, %l0 ! Base of new trap vector
+ mov %l0, %tbr ! Install the new tbr
+
+ set SYM(win_ovf_trap), %l1 ! Setup window overflow trap
+ ldd [%l1], %l2
+ std %l2, [%l0 + 5 * 16]
+ ldd [%l1 + 8], %l2
+ std %l2, [%l0 + 5 * 16 + 8]
+
+ set SYM(win_unf_trap), %l1 ! Setup window underflow trap
+ ldd [%l1], %l2
+ std %l2, [%l0 + 6 * 16]
+ ldd [%l1 + 8], %l2
+ std %l2, [%l0 + 6 * 16 + 8]
+
+/*
+ * Try enabling the FPU by setting EF. If that causes a trap, then we probably
+ * don't have an FPU.
+ */
+
+ ldd [%l0 + 2 * 16], %l4 ! Save original trap routine
+ set SYM(no_fpu_trap), %l1 ! Install new one
+ ldd [%l1], %l2
+ std %l2, [%l0 + 2 * 16]
+
+ mov %psr, %l0
+ sethi %hi(0x1000), %l1
+ bset %l1, %l0
+! mov %l0, %psr
+
+ std %l4, [2 * 16] ! Restore original trap routine
+
+
+/*
+ * Move the data segment from it's ROM address to RAM where it
+ * belongs.
+ */
+
+relocd:
+#if 0 /* This code is broken. FIXME */
+ set (_sdata),%g2 ! %g2 = start of data in aout file
+ set SYM(environ),%g4 ! %g4 = actual data base address
+ set (_edata),%g3 ! %g3 = end of where data should go
+ subcc %g3, %g4, %g5 ! %g5 = length of data
+
+ subcc %g4, %g2, %g0 ! need to relocate data ?
+ ble init
+ ld [%g4], %g6
+ subcc %g6, 1, %g0
+ be init
+mvdata:
+ subcc %g5, 8, %g5
+ ldd [%g2 + %g5], %g6
+ bg mvdata
+#endif
+
+/*
+ * initialize target specific stuff. Only execute these
+ * functions it they exist.
+ */
+init:
+ sethi %hi(SYM(hardware_init_hook)), %g1
+ or %g1,%lo(SYM(hardware_init_hook)),%g1
+ cmp %g0,%g1
+ be 1f
+ nop
+ call SYM(hardware_init_hook)
+ nop
+
+1:
+ sethi %hi(SYM(software_init_hook)), %g1
+ or %g1,%lo(SYM(software_init_hook)),%g1
+ cmp %g0,%g1
+ be 2f
+ nop
+ call SYM(software_init_hook)
+ nop
+2:
+ call SYM(main)
+ nop
+
+ /* call exit from the C library so atexit gets called, and the
+ * C++ destructors get run. This calls our exit routine below
+ * when it's done.
+ */
+ call SYM(exit)
+ nop
+
+/*
+ * This should drop control back to the ROM monitor, if there is
+ * one.
+ */
+ .globl SYM(_exit)
+SYM(_exit):
+ call 0
+ nop
+
+/*
+ * Trap handlers.
+ */
+
+ .align 8
+
+SYM(win_ovf_trap):
+ sethi %hi(SYM(win_ovf)), %l3
+ jmpl %lo(SYM(win_ovf))+%l3, %g0
+ mov %wim, %l0
+ nop
+
+SYM(win_unf_trap):
+ sethi %hi(SYM(win_unf)), %l3
+ jmpl %lo(SYM(win_unf))+%l3, %g0
+ mov %wim, %l0
+ nop
+
+SYM(no_fpu_trap): ! Come here when no fpu exists.
+ jmpl %l2, %g0 ! This just skips the
+ rett %l2+4 ! offending instruction.
diff --git a/libgloss/sparc/cygmon-crt0.S b/libgloss/sparc/cygmon-crt0.S
new file mode 100644
index 0000000..272c00d
--- /dev/null
+++ b/libgloss/sparc/cygmon-crt0.S
@@ -0,0 +1,144 @@
+/*
+ * C startup code for the Fujitsu SPARClite demo board
+ *
+ * Copyright (c) 1995, 1996 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+#include "asm.h"
+
+#ifdef TARGET_CPU_SPARC64
+#define STACK_BIAS 2047
+#define SAVE_SIZE -128
+#else
+#define SAVE_SIZE -64
+#endif
+
+.data
+ .align 8
+SYM(environ): ! this is the first address in the data section
+ .long 0
+
+SYM(argc):
+ .long 0
+
+ .text
+ .align 8
+
+ .globl SYM(start)
+ .globl start
+SYM(start):
+start:
+ /* see if the stack is already setup. if not, then default
+ * to using the value of %sp as set by the ROM monitor
+ */
+ sethi %hi(__stack), %g1
+ or %g1,%lo(__stack),%g1
+ cmp %g0,%g1
+ be 1f
+ nop
+#ifdef STACK_BIAS
+ sub %g1, STACK_BIAS, %g1
+#endif
+ mov %g1, %sp ! set the stack pointer
+ mov 0, %fp
+1:
+
+ /* zero the bss section */
+ sethi %hi(__bss_start),%g2
+ or %g2,%lo(__bss_start),%g2 ! start of bss
+ sethi %hi(_end),%g3
+ or %g3,%lo(_end),%g3 ! end of bss
+ mov %g0,%g1 ! so std has two zeros
+zerobss:
+ std %g0,[%g2]
+ add %g2,8,%g2
+ cmp %g2,%g3
+ bleu,a zerobss
+ nop
+
+/*
+ * initialize target specific stuff. Only execute these
+ * functions it they exist.
+ */
+init:
+ sethi %hi(SYM(hardware_init_hook)), %g1
+ or %g1,%lo(SYM(hardware_init_hook)),%g1
+ cmp %g0,%g1
+ be 1f
+ nop
+ call SYM(hardware_init_hook)
+ nop
+
+1:
+ sethi %hi(SYM(software_init_hook)), %g1
+ or %g1,%lo(SYM(software_init_hook)),%g1
+ cmp %g0,%g1
+ be 2f
+ nop
+ call SYM(software_init_hook)
+ nop
+2:
+ set SYM(__sigtramp), %o0
+ call SYM(__install_signal_handler)
+ nop
+
+ set do_dtors,%o0
+ call SYM(atexit)
+ nop
+
+ call do_ctors
+ nop
+
+ set SYM(argc), %o0
+ call SYM(__getProgramArgs)
+ nop
+
+ mov %o0, %o1
+ set SYM(argc), %o0
+ ld [%o0], %o0
+ call SYM(main)
+ nop
+
+ /* call exit from the C library so atexit gets called, and the
+ * C++ destructors get run. This calls our exit routine below
+ * when it's done.
+ */
+ call SYM(exit)
+ nop
+
+do_ctors:
+ save %sp,SAVE_SIZE,%sp
+ set __CTOR_LIST__,%l0
+our_entry:
+ ld [%l0],%l1
+ add %l0,4,%l0
+ tst %l1
+1:
+ beq 2f
+ nop
+ ld [%l0],%l2
+ add %l0,4,%l0
+
+ call %l2
+ nop
+ deccc %l1
+ b 1b
+ nop
+2:
+ ret
+ restore
+
+do_dtors:
+ save %sp,SAVE_SIZE,%sp
+ set __DTOR_LIST__,%l0
+ b our_entry
+ nop
diff --git a/libgloss/sparc/cygmon-salib.c b/libgloss/sparc/cygmon-salib.c
new file mode 100644
index 0000000..4f65c0f
--- /dev/null
+++ b/libgloss/sparc/cygmon-salib.c
@@ -0,0 +1,220 @@
+#ifdef TARGET_CPU_SPARC64
+#include <sys/types.h>
+#endif
+#include <sys/time.h>
+
+void
+putTtyChar(int c)
+{
+ /* 2 is fork under solaris; bad juju */
+ asm(" mov %i0,%o0
+ or %g0,2,%g1
+ ta 8
+ nop");
+}
+
+int
+write(int fd,char *ptr,int amt)
+{
+ if (fd < 0 || fd > 2)
+ {
+ return -1;
+ }
+ asm(" or %g0, 4, %g1
+ ta 8
+ nop");
+ return amt;
+}
+
+int
+read(int fd,char *ptr,int amt)
+{
+ if (fd < 0 || fd > 2)
+ {
+ return -1;
+ }
+ asm(" or %g0, 3, %g1
+ ta 8
+ nop");
+ return amt;
+}
+
+void
+_exit(int code)
+{
+ while(1) {
+ asm(" or %g0,1,%g1
+ ta 8
+ nop
+ ta 1
+ nop");
+ }
+}
+
+int
+setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
+{
+ asm(" or %g0, 158, %g1
+ ta 8
+ nop");
+}
+
+
+
+long
+sbrk (unsigned long amt)
+{
+ extern char _end;
+ static char *ptr = 0;
+ char *res;
+ if (ptr == 0)
+ ptr = &_end;
+ if (amt == 0)
+ return (long)ptr;
+
+ if (((long)ptr) % 8)
+ ptr = ptr + (8 - (((long)(ptr)) % 8));
+ res = ptr;
+ ptr += amt;
+ return (long)res;
+}
+
+#ifdef TARGET_CPU_SPARC64
+long
+_sbrk_r (void *foo, unsigned long amt)
+{
+ return sbrk(amt);
+}
+
+long
+_fstat_r (void *foo, void *bar, void *baz)
+{
+ return -1;
+}
+
+long
+_brk_r (void *foo)
+{
+ return sbrk(0);
+}
+
+int
+_open_r (char *filename, int mode)
+{
+ return open (filename, mode);
+}
+
+int
+_close_r (int fd)
+{
+ return close(fd);
+}
+#endif
+
+int
+close (int fd)
+{
+ return 0;
+}
+
+int
+fstat(int des,void *buf)
+{
+ return -1;
+}
+
+int
+lseek(int des,unsigned long offset, int whence)
+{
+ return -1;
+}
+
+int
+isatty(int fd)
+{
+ return (fd < 3);
+}
+
+int
+kill (int pid, int signal)
+{
+ asm ("or %g0, 37, %g1
+ ta 8
+ nop");
+}
+
+int
+getpid ()
+{
+ return -1;
+}
+
+int
+getitimer (int which, struct itimerval *value)
+{
+ asm ("or %g0, 157, %g1
+ ta 8
+ nop");
+}
+
+void
+__install_signal_handler (void *func)
+{
+ asm ("mov %o0, %o1
+ mov %g0, %o0
+ or %g0, 48, %g1
+ ta 8
+ nop");
+}
+
+int
+gettimeofday (struct timeval *tp, struct timezone *tzp)
+{
+ asm ("or %g0, 156, %g1
+ ta 8
+ nop");
+}
+
+int
+stime (long *seconds)
+{
+ asm ("or %g0, 25, %g1
+ ta 8
+ nop");
+}
+
+int
+add_mapping (long vma, long pma, long size)
+{
+ asm ("or %g0, 115, %g1
+ ta 8
+ nop");
+}
+
+int
+remove_mapping (long vma, long vma_end)
+{
+ asm ("or %g0, 117, %g1
+ ta 8
+ nop");
+}
+
+int
+open (char *filename, int mode)
+{
+ return -1;
+}
+
+void *
+__getProgramArgs (int *argv)
+{
+ int *res;
+
+ /* 184 is tsolsys under solaris; bad juju */
+ asm ("mov %1, %%o0
+ or %%g0, 184, %%g1
+ ta 8
+ nop
+ mov %%o0, %0" : "=r" (res) : "r" (argv): "g1");
+ return res;
+}
diff --git a/libgloss/sparc/cygmon-sparc64-ld.src b/libgloss/sparc/cygmon-sparc64-ld.src
new file mode 100644
index 0000000..efa0da1
--- /dev/null
+++ b/libgloss/sparc/cygmon-sparc64-ld.src
@@ -0,0 +1,159 @@
+/*
+ *uncomment this if you want the linker to output srecords.
+OUTPUT_FORMAT(srec)
+ *
+ */
+ENTRY(start)
+OUTPUT_ARCH(TARGET_OBJ_FORMAT)
+SEARCH_DIR(.)
+STARTUP(cygmon-crt0.o)
+GROUP(cygmon-salib.o -lc -lgcc -lc)
+
+/*
+ * The memory map looks like this:
+ * +--------------------+ <- low memory
+ * | .text |
+ * | _stext |
+ * | _etext |
+ * | ctor list | the ctor and dtor lists are for
+ * | dtor list | C++ support
+ * | _end_text |
+ * +--------------------+
+ * | .data | initialized data goes here
+ * | _sdata |
+ * | _edata |
+ * +--------------------+
+ * | .bss |
+ * | __bss_start | start of bss, cleared by crt0
+ * | _end | start of heap, used by sbrk()
+ * +--------------------+
+ * | heap space |
+ * | _ENDHEAP |
+ * | stack space |
+ * | __stack | top of stack
+ * +--------------------+ <- high memory
+ */
+
+_STACK_SIZE = (16 * 1024);
+_RAM_SIZE = 1M;
+_RAM_START = 0x4000;
+_RAM_END = _RAM_START + _RAM_SIZE;
+
+/*
+ * Setup the standard memory map. The stack grows down towards low memory.
+ */
+MEMORY
+{
+ ram : ORIGIN = 0x4000, LENGTH = 1M
+}
+
+__stack = (_RAM_START + _RAM_SIZE - 4 * 16) - _STACK_SIZE;
+
+/*
+ * All the symbols that might be accessed from C code need to be
+ * listed twice, once with an additional underscore. aout format needs
+ * and extra underscore, whereas coff & elf doesn't. This is to work
+ * with both.
+ */
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we cover a.out (which prepends
+ * an underscore) and coff object file formats.
+ */
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (_hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+PROVIDE (_software_init_hook = 0);
+SECTIONS
+{
+ .text : {
+ stext = .;
+ _stext = .;
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ __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__ = .;
+ *(.init)
+ *(.lit)
+ *(.rodata)
+ *(.shdata)
+ *(.eh_frame)
+ *(.gnu.linkonce.t*)
+ *(.gnu.linkonce.r*)
+ *(.gcc_except_table)
+ *(.fini)
+ _etext = .;
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .talias : { } > ram
+ .data : {
+ sdata = .;
+ _sdata = .;
+ *(.data)
+ *(.gnu.linkonce.d*)
+ edata = .;
+ _edata = .;
+ } > ram
+ .bss SIZEOF(.data) + ADDR(.data) : {
+ sbss = . ;
+ _sbss = . ;
+ __bss_start = ALIGN(0x8);
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ ebss = .;
+ _ebss = .;
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/libgloss/sparc/cygmon.ld.src b/libgloss/sparc/cygmon.ld.src
new file mode 100644
index 0000000..bf06825
--- /dev/null
+++ b/libgloss/sparc/cygmon.ld.src
@@ -0,0 +1,195 @@
+/*
+ *uncomment this if you want the linker to output srecords.
+OUTPUT_FORMAT(srec)
+ *
+ */
+ENTRY(start)
+OUTPUT_ARCH(TARGET_OBJ_FORMAT)
+SEARCH_DIR(.)
+STARTUP(cygmon-crt0.o)
+GROUP(cygmon-salib.o -lc -lgcc -lc)
+
+/*
+ * The memory map looks like this:
+ * +--------------------+ <- low memory
+ * | .text |
+ * | _stext |
+ * | _etext |
+ * | ctor list | the ctor and dtor lists are for
+ * | dtor list | C++ support
+ * | _end_text |
+ * +--------------------+
+ * | .data | initialized data goes here
+ * | _sdata |
+ * | _edata |
+ * +--------------------+
+ * | .bss |
+ * | __bss_start | start of bss, cleared by crt0
+ * | _end | start of heap, used by sbrk()
+ * +--------------------+
+ * | heap space |
+ * | _ENDHEAP |
+ * | stack space |
+ * | __stack | top of stack
+ * +--------------------+ <- high memory
+ */
+
+_STACK_SIZE = (16 * 1024);
+_RAM_SIZE = 1M;
+_RAM_START = TARGET_RAM_START;
+_RAM_END = _RAM_START + _RAM_SIZE;
+
+/*
+ * Setup the standard memory map. The stack grows down towards low memory.
+ */
+MEMORY
+{
+ ram : ORIGIN = TARGET_RAM_START, LENGTH = 1M
+}
+
+__stack = (_RAM_START + _RAM_SIZE - 4 * 16) - _STACK_SIZE;
+
+/*
+ * All the symbols that might be accessed from C code need to be
+ * listed twice, once with an additional underscore. aout format needs
+ * and extra underscore, whereas coff & elf doesn't. This is to work
+ * with both.
+ */
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we cover a.out (which prepends
+ * an underscore) and coff object file formats.
+ */
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (_hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+PROVIDE (_software_init_hook = 0);
+SECTIONS
+{
+ .text : {
+ stext = .;
+ _stext = .;
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ LONG(0)
+ __CTOR_END__ = .;
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+ LONG(0)
+ __DTOR_END__ = .;
+ *(.init)
+ *(.lit)
+ *(.rodata)
+ *(.shdata)
+ *(.eh_frame)
+ *(.gnu.linkonce.t*)
+ *(.gnu.linkonce.r*)
+ *(.gcc_except_table)
+ *(.fini)
+ _etext = .;
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .talias : { } > ram
+ .data : {
+ sdata = .;
+ _sdata = .;
+ *(.data)
+ *(.gnu.linkonce.d*)
+ edata = .;
+ _edata = .;
+ } > ram
+ .bss SIZEOF(.data) + ADDR(.data) : {
+ sbss = . ;
+ _sbss = . ;
+ __bss_start = ALIGN(0x8);
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ ebss = .;
+ _ebss = .;
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ .stab 0 (NOLOAD) : {
+ [ .stab ]
+ }
+ .stabstr 0 (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+/* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+/* DWARF 1 */
+ .debug 0 (NOLOAD) :
+ {
+ [ .debug ]
+ }
+ .line 0 (NOLOAD) :
+ {
+ [ .line ]
+ }
+/* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 (NOLOAD) :
+ {
+ [ .debug_srcinfo ]
+ }
+ .debug_sfnames 0 (NOLOAD) :
+ {
+ [ .debug_sfnames ]
+ }
+/* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 (NOLOAD) :
+ {
+ [ .debug_aranges ]
+ }
+ .debug_pubnames 0 (NOLOAD) :
+ {
+ [ .debug_pubnames ]
+ }
+/* DWARF 2 */
+ .debug_info 0 (NOLOAD) :
+ {
+ [ .debug_info ]
+ }
+ .debug_abbrev 0 (NOLOAD) :
+ {
+ [ .debug_abbrev ]
+ }
+ .debug_line 0 (NOLOAD) :
+ {
+ [ .debug_line ]
+ }
+ .debug_frame 0 (NOLOAD) :
+ {
+ [ .debug_frame ]
+ }
+ .debug_str 0 (NOLOAD) :
+ {
+ [ .debug_str ]
+ }
+ .debug_loc 0 (NOLOAD) :
+ {
+ [ .debug_loc ]
+ }
+ .debug_macinfo 0 (NOLOAD) :
+ {
+ [ .debug_macinfo ]
+ }
+}
diff --git a/libgloss/sparc/dtor.C b/libgloss/sparc/dtor.C
new file mode 100644
index 0000000..abde4f1
--- /dev/null
+++ b/libgloss/sparc/dtor.C
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+extern "C" void print (char *, ...);
+
+class foo
+{
+public:
+ foo () { print ("ctor\n"); }
+ ~foo () { print ("dtor\n"); }
+};
+
+foo x;
+
+main ()
+{
+ outbyte ('&');
+ outbyte ('@');
+ outbyte ('$');
+ outbyte ('%');
+ print ("FooBar\r\n");
+
+ /* whew, we made it */
+ print ("\r\nDone...\r\n");
+/* fflush(stdout); */
+}
diff --git a/libgloss/sparc/elfsim.ld b/libgloss/sparc/elfsim.ld
new file mode 100644
index 0000000..d1831be
--- /dev/null
+++ b/libgloss/sparc/elfsim.ld
@@ -0,0 +1,202 @@
+/* Linker script for running ELF programs in the Sparc simulator */
+
+/* OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparcle") */
+/* OUTPUT_FORMAT("elf32-sparc") */
+OUTPUT_ARCH(sparc)
+STARTUP(traps.o)
+INPUT(erc32-crt0.o)
+ENTRY(_trap_table)
+GROUP(-lc -lerc32 -lgcc) /* -lerc32 used to be -lsim */
+
+SEARCH_DIR(.)
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+
+/*
+ * The memory map looks like this:
+ * +--------------------+ <- low memory
+ * | .text |
+ * | _stext |
+ * | _etext |
+ * | ctor list | the ctor and dtor lists are for
+ * | dtor list | C++ support
+ * | _end_text |
+ * +--------------------+
+ * | .data | initialized data goes here
+ * | _sdata |
+ * | _edata |
+ * +--------------------+
+ * | .bss |
+ * | __bss_start | start of bss, cleared by crt0
+ * | _end | start of heap, used by sbrk()
+ * +--------------------+
+ * | heap space |
+ * | _ENDHEAP |
+ * | stack space |
+ * | __stack | top of stack
+ * +--------------------+ <- high memory
+ */
+
+/*
+ * User modifiable values:
+ *
+ * _CLOCK_SPEED in Mhz (used to program the counter/timers)
+ *
+ * _PROM_SIZE size of PROM (permissible values are 4K, 8K, 16K
+ * 32K, 64K, 128K, 256K, and 512K)
+ * _RAM_SIZE size of RAM (permissible values are 256K, 512K,
+ * 1MB, 2Mb, 4Mb, 8Mb, 16Mb, and 32Mb)
+ *
+ * These symbols are only used in assembler code, so they only need to
+ * be listed once. They should always be refered to without SYM().
+ */
+
+_CLOCK_SPEED = 10;
+
+_PROM_SIZE = 4M;
+_RAM_SIZE = 256K;
+
+_RAM_START = 0x02000000;
+_RAM_END = _RAM_START + _RAM_SIZE;
+_STACK_SIZE = (16 * 1024);
+_PROM_START = 0x00000000;
+_PROM_END = _PROM_START + _PROM_SIZE;
+
+
+/*
+ * Base address of the on-CPU peripherals
+ */
+
+_ERC32_MEC = 0x01f80000;
+
+/*
+ * Setup the memory map for the SIS simulator.
+ * stack grows up towards low memory.
+ */
+
+MEMORY
+{
+ rom : ORIGIN = 0x00000000, LENGTH = 4M
+ ram (rwx) : ORIGIN = 0x02000000, LENGTH = 2M
+}
+
+__stack = _RAM_START + _RAM_SIZE - 4 * 16;
+__trap_stack = (_RAM_START + _RAM_SIZE - 4 * 16) - _STACK_SIZE;
+
+/*
+ * All the symbols that might be accessed from C code need to be
+ * listed twice, once with an additional underscore. aout format needs
+ * and extra underscore, whereas coff & elf doesn't. This is to work
+ * with both.
+ */
+SECTIONS
+{
+ .text :
+ {
+ _stext = .;
+ PROVIDE (stext = .);
+ __EH_FRAME_BEGIN__ = .;
+ *(.text)
+ _etext = .;
+ PROVIDE (etext = .);
+
+ /* For a.out. */
+ CONSTRUCTORS
+
+ /* For ELF. */
+ __CTOR_LIST__ = .;
+ LONG(-1)
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ LONG(0)
+ __CTOR_END__ = .;
+ __DTOR_LIST__ = .;
+ LONG(-1)
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+ LONG(0)
+ __DTOR_END__ = .;
+
+ *(.init)
+ *(.lit)
+ *(.rodata)
+ *(.shdata)
+ *(.eh_frame)
+ *(.gnu.linkonce.t*)
+ *(.gnu.linkonce.r*)
+ *(.gcc_except_table)
+ *(.fini)
+
+ _endtext = .;
+ PROVIDE(endtext = .);
+ } > ram
+
+ .shbss SIZEOF(.text) + ADDR(.text) :
+ {
+ *(.shbss)
+ }
+
+ .talias : { } > ram
+
+ .data :
+ {
+ _sdata = .;
+ PROVIDE (sdata = .);
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ _edata = .;
+ PROVIDE (edata = .);
+ } > ram
+
+ .bss SIZEOF(.data) + ADDR(.data) :
+ {
+ _sbss = . ;
+ PROVIDE (sbss = . );
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ _ebss = .;
+ PROVIDE (ebss = .);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ PROVIDE (end = ALIGN(0x8));
+ }
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/libgloss/sparc/erc32-crt0.S b/libgloss/sparc/erc32-crt0.S
new file mode 100644
index 0000000..8f8b1ea
--- /dev/null
+++ b/libgloss/sparc/erc32-crt0.S
@@ -0,0 +1,75 @@
+/*
+ * This is based on the file srt0.s provided with the binary
+ * distribution of the SPARC Instruction Simulator (SIS) found
+ * at ftp://ftp.estec.esa.nl/pub/ws/wsd/erc32.
+ */
+
+#include "asm.h"
+
+ .data
+ .align 8
+SYM(environ):
+ .long 0
+
+ .text
+
+ .globl SYM(start)
+SYM(start):
+ sethi %hi(__stack), %g1
+ or %g1,%lo(__stack),%g1
+ mov %g1, %sp ! set the stack pointer
+ mov %sp, %fp
+
+ /* clear the bss */
+ sethi %hi(__bss_start),%g2
+ or %g2,%lo(__bss_start),%g2 ! start of bss
+ sethi %hi(_end),%g3
+ or %g3,%lo(_end),%g3 ! end of bss
+ mov %g0,%g1 ! so std has two zeros
+zerobss:
+ std %g0,[%g2]
+ add %g2,8,%g2
+ cmp %g2,%g3
+ bleu,a zerobss
+ nop
+
+ /* move data segment to proper location */
+
+#if 0
+relocd:
+ set (_endtext),%g2 ! g2 = start of data in aout file
+ set (_environ),%g4 ! g4 = start of where data should go
+ set (_edata),%g3 ! g3 = end of where data should go
+ subcc %g3, %g4, %g5 ! g5 = length of data
+
+ subcc %g4, %g2, %g0 ! need to relocate data ?
+ ble initok
+ ld [%g4], %g6
+ subcc %g6, 1, %g0
+ be initok
+mvdata:
+ subcc %g5, 8, %g5
+ ldd [%g2 + %g5], %g6
+ bg mvdata
+ std %g6, [%g4 + %g5]
+
+initok:
+#endif
+
+ call SYM(__fix_ctors)
+ nop
+ call SYM(main)
+ nop
+
+ /* call exit from the C library so atexit gets called, and the
+ * C++ destructors get run. This calls our exit routine below * when it's done.
+ */
+ call SYM(exit)
+ nop
+
+ .globl SYM(_exit)
+SYM(_exit):
+ set 0xdeadd00d, %o1 ! Magic number for simulator.
+ ta 0 ! Halt if _main returns ...
+ nop
+
diff --git a/libgloss/sparc/erc32-io.c b/libgloss/sparc/erc32-io.c
new file mode 100644
index 0000000..082d9f9
--- /dev/null
+++ b/libgloss/sparc/erc32-io.c
@@ -0,0 +1,47 @@
+#define USE_PORT_A
+
+#define RXADATA (int *) 0x01F800E0
+#define RXBDATA (int *) 0x01F800E4
+#define RXSTAT (int *) 0x01F800E8
+
+void
+outbyte (int c)
+{
+ volatile int *rxstat;
+ volatile int *rxadata;
+ int rxmask;
+
+ rxstat = RXSTAT;
+#ifdef USE_PORT_A
+ rxadata = RXADATA;
+ rxmask = 6;
+#else
+ rxadata = RXBDATA;
+ rxmask = 0x60000;
+#endif
+
+ while ((*rxstat & rxmask) == 0);
+
+ *rxadata = c;
+}
+
+int
+inbyte (void)
+{
+ volatile int *rxstat;
+ volatile int *rxadata;
+ int rxmask;
+
+ rxstat = RXSTAT;
+#ifdef USE_PORT_A
+ rxadata = RXADATA;
+ rxmask = 1;
+#else
+ rxadata = RXBDATA;
+ rxmask = 0x10000;
+#endif
+
+ while ((*rxstat & rxmask) == 0);
+
+ return *rxadata;
+}
diff --git a/libgloss/sparc/erc32-stub.c b/libgloss/sparc/erc32-stub.c
new file mode 100644
index 0000000..71a65b2
--- /dev/null
+++ b/libgloss/sparc/erc32-stub.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 1996 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include <string.h>
+#include <signal.h>
+#include "debug.h"
+#include "asm.h"
+#include "slite.h"
+
+extern unsigned long rdtbr();
+extern struct trap_entry fltr_proto;
+extern void trap_low();
+exception_t default_trap_hook = trap_low;
+void target_reset();
+void flush_i_cache();
+char *target_read_registers(unsigned long *);
+char *target_write_registers(unsigned long *);
+char *target_dump_state(unsigned long *);
+
+#define NUMREGS 72
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+
+enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
+ O0, O1, O2, O3, O4, O5, SP, O7,
+ L0, L1, L2, L3, L4, L5, L6, L7,
+ I0, I1, I2, I3, I4, I5, FP, I7,
+
+ F0, F1, F2, F3, F4, F5, F6, F7,
+ F8, F9, F10, F11, F12, F13, F14, F15,
+ F16, F17, F18, F19, F20, F21, F22, F23,
+ F24, F25, F26, F27, F28, F29, F30, F31,
+ Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR };
+
+/*
+ * Each entry in the trap vector occupies four words, typically a jump
+ * to the processing routine.
+ */
+struct trap_entry {
+ unsigned sethi_filler:10;
+ unsigned sethi_imm22:22;
+ unsigned jmpl_filler:19;
+ unsigned jmpl_simm13:13;
+ unsigned long filler[2];
+};
+
+/*
+ * This table contains the mapping between SPARC hardware trap types, and
+ * signals, which are primarily what GDB understands. It also indicates
+ * which hardware traps we need to commandeer when initializing the stub.
+ */
+struct trap_info hard_trap_info[] = {
+ {1, SIGSEGV}, /* instruction access error */
+ {2, SIGILL}, /* privileged instruction */
+ {3, SIGILL}, /* illegal instruction */
+ {4, SIGEMT}, /* fp disabled */
+ {36, SIGEMT}, /* cp disabled */
+ {7, SIGBUS}, /* mem address not aligned */
+ {9, SIGSEGV}, /* data access exception */
+ {10, SIGEMT}, /* tag overflow */
+ {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
+ {0, 0} /* Must be last */
+};
+
+extern struct trap_entry fltr_proto;
+void
+exception_handler (int tt, unsigned long routine)
+{
+ struct trap_entry *tb; /* Trap vector base address */
+
+ DEBUG (1, "Entering exception_handler()");
+ if (tt != 256) {
+ tb = (struct trap_entry *) (rdtbr() & ~0xfff);
+ } else {
+ tt = 255;
+ tb = (struct trap_entry *) 0;
+ }
+
+ tb[tt] = fltr_proto;
+
+ tb[tt].sethi_imm22 = routine >> 10;
+ tb[tt].jmpl_simm13 = routine & 0x3ff;
+
+ DEBUG (1, "Leaving exception_handler()");
+}
+
+/*
+ * This is so we can trap a memory fault when reading or writing
+ * directly to memory.
+ */
+void
+set_mem_fault_trap(enable)
+ int enable;
+{
+ extern void fltr_set_mem_err();
+
+ DEBUG (1, "Entering set_mem_fault_trap()");
+
+ mem_err = 0;
+
+ if (enable)
+ exception_handler(9, (unsigned long)fltr_set_mem_err);
+ else
+ exception_handler(9, (unsigned long)trap_low);
+
+ DEBUG (1, "Leaving set_mem_fault_trap()");
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb. It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+extern void breakinst();
+
+void
+handle_exception (registers)
+ unsigned long *registers;
+{
+ int sigval;
+
+ /* First, we must force all of the windows to be spilled out */
+
+ DEBUG (1, "Entering handle_exception()");
+
+/* asm("mov %g0, %wim ; nop; nop; nop"); */
+ asm(" save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+");
+
+ if (registers[PC] == (unsigned long)breakinst) {
+ registers[PC] = registers[NPC];
+ registers[NPC] += 4;
+ }
+
+ /* get the last know signal number from the trap register */
+ sigval = computeSignal((registers[TBR] >> 4) & 0xff);
+
+ /* call the main command processing loop for gdb */
+ gdb_event_loop (sigval, registers);
+}
+
+/*
+ * This function will generate a breakpoint exception. It is used at the
+ * beginning of a program to sync up with a debugger and can be used
+ * otherwise as a quick means to stop program execution and "break" into
+ * the debugger.
+ */
+void
+breakpoint()
+{
+ DEBUG (1, "Entering breakpoint()");
+
+ if (!initialized)
+ return;
+
+ asm(" .globl " STRINGSYM(breakinst) "
+ " STRINGSYM(breakinst) ": ta 128+1
+ nop
+ nop
+ ");
+}
+
+/*
+ * This is just a test vector for debugging excpetions.
+ */
+void
+bad_trap(tt)
+int tt;
+{
+ print ("Got a bad trap #");
+ outbyte (tt);
+ outbyte ('\n');
+ asm("ta 0
+ nop
+ nop
+ ");
+}
+
+/*
+ * This is just a test vector for debugging excpetions.
+ */
+void
+soft_trap(tt)
+int tt;
+{
+ print ("Got a soft trap #");
+ outbyte (tt);
+ outbyte ('\n');
+ asm("ta 0
+ nop
+ nop
+ ");
+}
+
+/*
+ * Flush the instruction cache. We need to do this for the debugger stub so
+ * that breakpoints, et. al. become visible to the instruction stream after
+ * storing them in memory.
+ *
+ * For the sparclite, we need to do something here, but for a standard
+ * sparc (which SIS simulates), we don't.
+ */
+
+void
+flush_i_cache ()
+{
+}
+
+/*
+ * This will reset the processor, so we never return from here.
+ */
+void
+target_reset()
+{
+ asm ("call 0
+ nop ");
+}
+
+/*
+ * g - read registers.
+ * no params.
+ * returns a vector of words, size is NUM_REGS.
+ */
+char *
+target_read_registers(unsigned long *registers)
+{
+ char *ptr;
+ unsigned long *sp;
+
+ DEBUG (1, "In target_read_registers()");
+
+ ptr = packet_out_buf;
+ ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */
+ ptr = mem2hex((unsigned char *)(sp + 0), ptr, 16 * 4, 0); /* L & I regs */
+ memset(ptr, '0', 32 * 8); /* Floating point */
+ mem2hex((char *)&registers[Y],
+ ptr + 32 * 4 * 2,
+ 8 * 4,
+ 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ return (ptr);
+}
+
+/*
+ * G - write registers.
+ * param is a vector of words, size is NUM_REGS.
+ * returns an OK or an error number.
+ */
+char *
+target_write_registers(unsigned long *registers)
+{
+ unsigned char *ptr;
+ unsigned long *sp;
+ unsigned long *newsp, psr;
+
+ DEBUG (1, "In target_write_registers()");
+
+ psr = registers[PSR];
+
+ ptr = &packet_in_buf[1];
+
+ hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
+ hex2mem(ptr + 16 * 4 * 2, (unsigned char *)(sp + 0), 16 * 4, 0); /* L & I regs */
+ hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
+ 8 * 4, 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+
+ /*
+ * see if the stack pointer has moved. If so, then copy the saved
+ * locals and ins to the new location. This keeps the window
+ * overflow and underflow routines happy.
+ */
+
+ newsp = (unsigned long *)registers[SP];
+ if (sp != newsp)
+ sp = memcpy(newsp, sp, 16 * 4);
+
+ /* Don't allow CWP to be modified. */
+
+ if (psr != registers[PSR])
+ registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
+ return (ptr);
+}
+
+char *
+target_dump_state(unsigned long *registers)
+{
+ int tt; /* Trap type */
+ int sigval;
+ char *ptr;
+ unsigned long *sp;
+
+ DEBUG (1, "In target_dump_state()");
+
+ sp = (unsigned long *)registers[SP];
+
+ tt = (registers[TBR] >> 4) & 0xff;
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal(tt);
+ ptr = packet_out_buf;
+
+ *ptr++ = 'T';
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[FP >> 4];
+ *ptr++ = hexchars[FP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)(sp + 8 + 6), ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[SP >> 4];
+ *ptr++ = hexchars[SP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((unsigned char *)&sp, ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[NPC >> 4];
+
+ return (packet_out_buf);
+}
+
+void
+write_pc(unsigned long *registers, unsigned long addr)
+{
+ DEBUG (1, "In write_pc");
+
+ registers[PC] = addr;
+ registers[NPC] = addr + 4;
+}
diff --git a/libgloss/sparc/erc32.ld b/libgloss/sparc/erc32.ld
new file mode 100644
index 0000000..179dcc0
--- /dev/null
+++ b/libgloss/sparc/erc32.ld
@@ -0,0 +1,146 @@
+/*
+ *uncomment this if you want the linker to output srecords.
+OUTPUT_FORMAT(srec)
+ *
+ */
+STARTUP(traps.o)
+INPUT(sim-crt0.o)
+OUTPUT_ARCH(sparc)
+SEARCH_DIR(.)
+__DYNAMIC = 0;
+GROUP(-lc -lsim -lgcc)
+
+/*
+ * The memory map looks like this:
+ * +--------------------+ <- low memory
+ * | .text |
+ * | _stext |
+ * | _etext |
+ * | ctor list | the ctor and dtor lists are for
+ * | dtor list | C++ support
+ * | _end_text |
+ * +--------------------+
+ * | .data | initialized data goes here
+ * | _sdata |
+ * | _edata |
+ * +--------------------+
+ * | .bss |
+ * | __bss_start | start of bss, cleared by crt0
+ * | _end | start of heap, used by sbrk()
+ * +--------------------+
+ * | heap space |
+ * | _ENDHEAP |
+ * | stack space |
+ * | __stack | top of stack
+ * +--------------------+ <- high memory
+ */
+
+/*
+ * User modifiable values:
+ *
+ * _CLOCK_SPEED in Mhz (used to program the counter/timers)
+ *
+ * _PROM_SIZE size of PROM (permissible values are 4K, 8K, 16K
+ * 32K, 64K, 128K, 256K, and 512K)
+ * _RAM_SIZE size of RAM (permissible values are 256K, 512K,
+ * 1MB, 2Mb, 4Mb, 8Mb, 16Mb, and 32Mb)
+ *
+ * These symbols are only used in assembler code, so they only need to
+ * be listed once. They should always be refered to without SYM().
+ */
+
+_CLOCK_SPEED = 10;
+
+_PROM_SIZE = 4M;
+_RAM_SIZE = 2M;
+
+_RAM_START = 0x02020000;
+_RAM_END = _RAM_START + _RAM_SIZE;
+_STACK_SIZE = (16 * 1024);
+_PROM_START = 0x00000000;
+_PROM_END = _PROM_START + _PROM_SIZE;
+
+
+/*
+ * Base address of the on-CPU peripherals
+ */
+
+_ERC32_MEC = 0x01f80000;
+
+/*
+ * Setup the memory map for the SIS simulator.
+ * stack grows up towards low memory.
+ */
+/*
+MEMORY
+{
+ rom : ORIGIN = 0x00000000, LENGTH = 4M
+ ram (rwx) : ORIGIN = 0x02000000, LENGTH = 2M
+}
+*/
+
+__stack = _RAM_START + _RAM_SIZE - 4 * 16;
+__trap_stack = (_RAM_START + _RAM_SIZE - 4 * 16) - _STACK_SIZE;
+
+/*
+ * All the symbols that might be accessed from C code need to be
+ * listed twice, once with an additional underscore. aout format needs
+ * and extra underscore, whereas coff & elf doesn't. This is to work
+ * with both.
+ */
+SECTIONS
+{
+ .text 0x02000000 : {
+ stext = .;
+ _stext = .;
+ *(.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)
+ _endtext = .;
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .talias : { } > ram
+ .data : {
+ sdata = .;
+ _sdata = .;
+ *(.data)
+ edata = .;
+ _edata = .;
+ } > ram
+ .bss SIZEOF(.data) + ADDR(.data) :
+ {
+ sbss = . ;
+ _sbss = . ;
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ ebss = .;
+ _ebss = .;
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ .stab 0 (NOLOAD) :
+ {
+ [ .stab ]
+ }
+ .stabstr 0 (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+}
diff --git a/libgloss/sparc/ex930.ld b/libgloss/sparc/ex930.ld
new file mode 100644
index 0000000..b501b2e
--- /dev/null
+++ b/libgloss/sparc/ex930.ld
@@ -0,0 +1,160 @@
+/*
+ *uncomment this if you want the linker to output srecords.
+OUTPUT_FORMAT(srec)
+ *
+ */
+ENTRY(_start)
+STARTUP(crt0.o)
+OUTPUT_ARCH(sparc)
+SEARCH_DIR(.)
+__DYNAMIC = 0;
+GROUP (-lc -lslite930 -lgcc)
+
+/*
+ * The memory map looks like this:
+ * +--------------------+ <- low memory
+ * | .text |
+ * | _stext |
+ * | _etext |
+ * | ctor list | the ctor and dtor lists are for
+ * | dtor list | C++ support
+ * | _end_text |
+ * +--------------------+
+ * | .data | initialized data goes here
+ * | _sdata |
+ * | _edata |
+ * +--------------------+
+ * | .bss |
+ * | __bss_start | start of bss, cleared by crt0
+ * | _end | start of heap, used by sbrk()
+ * +--------------------+
+ * | heap space |
+ * | _ENDHEAP |
+ * | stack space |
+ * | __stack | top of stack
+ * +--------------------+ <- high memory
+ */
+
+_STACK_SIZE = (16 * 1024);
+_RAM_SIZE = 2M;
+_RAM_START = 0x40000000;
+_RAM_END = _RAM_START + _RAM_SIZE;
+
+/*
+ * Base address of the on-CPU peripherals. This is for compatability
+ * with the simulator.
+ */
+
+_ERC32_MEC = 0x0;
+
+/*
+ * Setup the memory map of the MB86931-EB Board (ex931)
+ * stack grows down towards low memory.
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x40000000, LENGTH = 2M
+}
+
+__stack = _RAM_START + _RAM_SIZE - 4 * 16;
+__trap_stack = (_RAM_START + _RAM_SIZE - 4 * 16) - _STACK_SIZE;
+
+/*
+ * All the symbols that might be accessed from C code need to be
+ * listed twice, once with an additional underscore. aout format needs
+ * and extra underscore, whereas coff & elf doesn't. This is to work
+ * with both.
+ */
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we cover a.out (which prepends
+ * an underscore) and coff object file formats.
+ */
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (_hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+PROVIDE (_software_init_hook = 0);
+SECTIONS
+{
+ .text : {
+ stext = .;
+ _stext = .;
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ __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__ = .;
+ _etext = .;
+ *(.lit)
+ *(.shdata)
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .talias : { } > ram
+ .data : {
+ sdata = .;
+ _sdata = .;
+ *(.data)
+ edata = .;
+ _edata = .;
+ } > ram
+ .bss SIZEOF(.data) + ADDR(.data) : {
+ sbss = . ;
+ _sbss = . ;
+ __bss_start = ALIGN(0x8);
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ ebss = .;
+ _ebss = .;
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ .stab 0 (NOLOAD) : {
+ [ .stab ]
+ }
+ .stabstr 0 (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/libgloss/sparc/ex931.ld b/libgloss/sparc/ex931.ld
new file mode 100644
index 0000000..26ffb4d
--- /dev/null
+++ b/libgloss/sparc/ex931.ld
@@ -0,0 +1,160 @@
+/*
+ *uncomment this if you want the linker to output srecords.
+OUTPUT_FORMAT(srec)
+ *
+ */
+ENTRY(_start)
+STARTUP(crt0.o)
+OUTPUT_ARCH(sparc)
+SEARCH_DIR(.)
+__DYNAMIC = 0;
+GROUP (-lc -lslite931 -lgcc)
+
+/*
+ * The memory map looks like this:
+ * +--------------------+ <- low memory
+ * | .text |
+ * | _stext |
+ * | _etext |
+ * | ctor list | the ctor and dtor lists are for
+ * | dtor list | C++ support
+ * | _end_text |
+ * +--------------------+
+ * | .data | initialized data goes here
+ * | _sdata |
+ * | _edata |
+ * +--------------------+
+ * | .bss |
+ * | __bss_start | start of bss, cleared by crt0
+ * | _end | start of heap, used by sbrk()
+ * +--------------------+
+ * | heap space |
+ * | _ENDHEAP |
+ * | stack space |
+ * | __stack | top of stack
+ * +--------------------+ <- high memory
+ */
+
+_STACK_SIZE = (16 * 1024);
+_RAM_SIZE = 2M;
+_RAM_START = 0x40000000;
+_RAM_END = _RAM_START + _RAM_SIZE;
+
+/*
+ * Base address of the on-CPU peripherals. This is for compatability
+ * with the simulator.
+ */
+
+_ERC32_MEC = 0x0;
+
+/*
+ * Setup the memory map of the MB86931-EB Board (ex931)
+ * stack grows down towards low memory.
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x40000000, LENGTH = 2M
+}
+
+__stack = _RAM_START + _RAM_SIZE - 4 * 16;
+__trap_stack = (_RAM_START + _RAM_SIZE - 4 * 16) - _STACK_SIZE;
+
+/*
+ * All the symbols that might be accessed from C code need to be
+ * listed twice, once with an additional underscore. aout format needs
+ * and extra underscore, whereas coff & elf doesn't. This is to work
+ * with both.
+ */
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we cover a.out (which prepends
+ * an underscore) and coff object file formats.
+ */
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (_hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+PROVIDE (_software_init_hook = 0);
+SECTIONS
+{
+ .text : {
+ stext = .;
+ _stext = .;
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ __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__ = .;
+ _etext = .;
+ *(.lit)
+ *(.shdata)
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .talias : { } > ram
+ .data : {
+ sdata = .;
+ _sdata = .;
+ *(.data)
+ edata = .;
+ _edata = .;
+ } > ram
+ .bss SIZEOF(.data) + ADDR(.data) : {
+ sbss = . ;
+ _sbss = . ;
+ __bss_start = ALIGN(0x8);
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ ebss = .;
+ _ebss = .;
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ .stab 0 (NOLOAD) : {
+ [ .stab ]
+ }
+ .stabstr 0 (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/libgloss/sparc/ex934.ld b/libgloss/sparc/ex934.ld
new file mode 100644
index 0000000..7d1d5ed
--- /dev/null
+++ b/libgloss/sparc/ex934.ld
@@ -0,0 +1,160 @@
+/*
+ *uncomment this if you want the linker to output srecords.
+OUTPUT_FORMAT(srec)
+ *
+ */
+ENTRY(_start)
+STARTUP(crt0.o)
+OUTPUT_ARCH(sparc)
+SEARCH_DIR(.)
+__DYNAMIC = 0;
+GROUP (-lc -lslite934 -lgcc)
+
+/*
+ * The memory map looks like this:
+ * +--------------------+ <- low memory
+ * | .text |
+ * | _stext |
+ * | _etext |
+ * | ctor list | the ctor and dtor lists are for
+ * | dtor list | C++ support
+ * | _end_text |
+ * +--------------------+
+ * | .data | initialized data goes here
+ * | _sdata |
+ * | _edata |
+ * +--------------------+
+ * | .bss |
+ * | __bss_start | start of bss, cleared by crt0
+ * | _end | start of heap, used by sbrk()
+ * +--------------------+
+ * | heap space |
+ * | _ENDHEAP |
+ * | stack space |
+ * | __stack | top of stack
+ * +--------------------+ <- high memory
+ */
+
+_STACK_SIZE = (16 * 1024);
+_RAM_SIZE = 2M;
+_RAM_START = 0x40010000;
+_RAM_END = _RAM_START + _RAM_SIZE;
+
+/*
+ * Base address of the on-CPU peripherals. This is for compatability
+ * with the simulator.
+ */
+
+_ERC32_MEC = 0x0;
+
+/*
+ * Setup the memory map of the MB86931-EB Board (ex931)
+ * stack grows down towards low memory.
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x40010000, LENGTH = 2M
+}
+
+__stack = _RAM_START + _RAM_SIZE - 4 * 16;
+__trap_stack = (_RAM_START + _RAM_SIZE - 4 * 16) - _STACK_SIZE;
+
+/*
+ * All the symbols that might be accessed from C code need to be
+ * listed twice, once with an additional underscore. aout format needs
+ * and extra underscore, whereas coff & elf doesn't. This is to work
+ * with both.
+ */
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we cover a.out (which prepends
+ * an underscore) and coff object file formats.
+ */
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (_hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+PROVIDE (_software_init_hook = 0);
+SECTIONS
+{
+ .text : {
+ stext = .;
+ _stext = .;
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ __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__ = .;
+ _etext = .;
+ *(.lit)
+ *(.shdata)
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .talias : { } > ram
+ .data : {
+ sdata = .;
+ _sdata = .;
+ *(.data)
+ edata = .;
+ _edata = .;
+ } > ram
+ .bss SIZEOF(.data) + ADDR(.data) : {
+ sbss = . ;
+ _sbss = . ;
+ __bss_start = ALIGN(0x8);
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ ebss = .;
+ _ebss = .;
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ .stab 0 (NOLOAD) : {
+ [ .stab ]
+ }
+ .stabstr 0 (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/libgloss/sparc/fixctors.c b/libgloss/sparc/fixctors.c
new file mode 100644
index 0000000..484023c
--- /dev/null
+++ b/libgloss/sparc/fixctors.c
@@ -0,0 +1,54 @@
+/* Code to byte-swap static constructor/destructor tables on
+ broken a.out little-endian targets. The startup code should call
+ __fix_ctors just before calling main. It is safe to use on non-broken
+ or big-endian targets. */
+
+extern long __CTOR_LIST__[];
+extern long __DTOR_LIST__[];
+
+static void
+byte_swap (long *entry)
+{
+ unsigned char *p = (unsigned char *)entry;
+ unsigned char tmp;
+
+ tmp = p[0];
+ p[0] = p[3];
+ p[3] = tmp;
+ tmp = p[1];
+ p[1] = p[2];
+ p[2] = tmp;
+}
+
+static void
+fix_table (long *table)
+{
+ long len = table[0];
+
+ /* The heuristic for deciding if a table is broken is to examine
+ the word at the start of the table, which contains the number
+ of function pointers immediately following. If the low word
+ is zero, and the high word is non-zero, it's very likely that
+ it is byte-swapped. This test will fail if the program has
+ an exact multiple of 64K static constructors or destructors, a very
+ unlikely situation. */
+ if ((len & 0xffff) == 0 && (len & 0xffff0000) != 0)
+ {
+
+ /* The table looks broken. Byte-swap all the words in the table, up
+ to a NULL entry, which marks the end of the table. */
+ do
+ {
+ byte_swap (table);
+ table++;
+ }
+ while (*table);
+ }
+}
+
+void
+__fix_ctors (void)
+{
+ fix_table (__CTOR_LIST__);
+ fix_table (__DTOR_LIST__);
+}
diff --git a/libgloss/sparc/libsys/Makefile.in b/libgloss/sparc/libsys/Makefile.in
new file mode 100644
index 0000000..f3a036f
--- /dev/null
+++ b/libgloss/sparc/libsys/Makefile.in
@@ -0,0 +1,167 @@
+# Makefile for libgloss/sparc/libsys
+# Copyright (c) 1996 Cygnus Support.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that the above copyright notice and this paragraph are
+# duplicated in all such forms and that any documentation,
+# advertising materials, and other materials related to such
+# distribution and use acknowledge that the software was developed
+# at Cygnus Support, Inc. Cygnus Support, Inc. may not be used to
+# endorse or promote products derived from this software without
+# specific prior written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+objdir = .
+srcroot = $(srcdir)/../..
+objroot = $(objdir)/../..
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+host_alias = @host_alias@
+target_alias = @target_alias@
+
+bindir = @bindir@
+libdir = @libdir@
+tooldir = $(exec_prefix)/$(target_alias)
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+
+SHELL = /bin/sh
+
+CC = @CC@
+
+AS = @AS@
+AR = @AR@
+LD = @LD@
+RANLIB = @RANLIB@
+
+# _r.o is for the reentrant syscall stubs.
+# The .S_r.o/.c_r.o rules are from host/any.
+
+.SUFFIXES: .c .S .o _r.o
+
+.S_r.o:
+ $(CC) $(CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) $(NEWLIB_CFLAGS) -DREENT $(INCLUDES) -c $< -o $@
+.c_r.o:
+ $(CC) $(CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) $(NEWLIB_CFLAGS) -DREENT $(INCLUDES) -c $< -o $@
+
+# CFILES_R, SFILES_R, and TEMPLATE_SFILES_R define those system calls that are
+# needed by the ANSI C part of newlib when REENTRANT_SYSCALLS_PROVIDED is
+# defined.
+
+CFILES = isatty.c
+
+CFILES_R =
+
+SFILES = cerror.S _exit.S
+
+SFILES_R = sbrk.S
+
+# List of files built from template.S (with an '_' suffix).
+
+TEMPLATE_SFILES = chdir_ lstat_
+
+TEMPLATE_SFILES_R = close_ fstat_ getpid_ kill_ \
+ lseek_ open_ read_ stat_ unlink_ write_
+
+# If newlib defines REENTRANT_SYSCALLS_PROVIDED, then these are used as well.
+REENTRANT_OFILES = $(SFILES_R:.S=_r.o) $(TEMPLATE_SFILES_R:_=_r.o) \
+ $(CFILES_R:.c=_r.o)
+
+OFILES = $(SFILES:.S=.o) $(SFILES_R:.S=.o) \
+ $(TEMPLATE_SFILES:_=.o) $(TEMPLATE_SFILES_R:_=.o) \
+ $(CFILES:.c=.o) $(CFILES_R:.c=.o) \
+ $(REENTRANT_OFILES)
+
+#### Host specific Makefile fragment comes in here.
+@host_makefile_frag@
+
+all: libsys.a libsys-crt0.o
+
+libsys.a: $(OFILES)
+ rm -f $@
+ $(AR) $(AR_FLAGS) $@ $(OFILES)
+
+install:
+ $(INSTALL_DATA) libsys-crt0.o $(tooldir)/lib/libsys-crt0.o
+ $(INSTALL_DATA) libsys.a $(tooldir)/lib/libsys.a
+
+doc:
+
+.PHONY: info install-info clean-info
+info:
+install-info:
+clean-info:
+
+clean mostlyclean:
+ rm -f *.o *.a *.s stamp-srcs
+
+distclean maintainer-clean realclean: clean
+ rm -f Makefile config.status
+
+Makefile: Makefile.in config.status @host_makefile_frag_path@
+ $(SHELL) config.status
+
+config.status: configure
+ $(SHELL) config.status --recheck
+
+stamp-srcs: Makefile template.S template_r.S
+ for f in $(TEMPLATE_SFILES:_=) ; \
+ do \
+ $(CC) -E -Dfunc=$$f \
+ $(CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) $(NEWLIB_CFLAGS) $(INCLUDES) \
+ $(srcdir)/template.S >$$f.S ; \
+ done
+ for f in $(TEMPLATE_SFILES_R:_=) ; \
+ do \
+ $(CC) -E -Dfunc=$$f \
+ $(CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) $(NEWLIB_CFLAGS) $(INCLUDES) \
+ $(srcdir)/template_r.S | sed -e 's/^_/#/' >$$f.S ; \
+ done
+ touch stamp-srcs
+
+# Make a dependency for each file built from a template.
+
+$(TEMPLATE_SFILES:_=.S) $(TEMPLATE_SFILES_R:_=.S): stamp-srcs
+
+# To support SunOS broken VPATH (sigh).
+
+_exit.o: _exit.S
+cerror.o: cerror.S
+chdir.o: chdir.S
+close.o: close.S
+fstat.o: fstat.S
+getpid.o: getpid.S
+isatty.o: isatty.c
+kill.o: kill.S
+libsys-crt0.o: libsys-crt0.S
+lseek.o: lseek.S
+lstat.o: lstat.S
+open.o: open.S
+read.o: read.S
+sbrk.o: sbrk.S
+stat.o: stat.S
+write.o: write.S
+
+# Reentrant versions ...
+# These are all needed to support the ANSI C library routines.
+
+close_r.o: close.S
+fstat_r.o: fstat.S
+getpid_r.o: getpid.S
+kill_r.o: kill.S
+lseek_r.o: lseek.S
+open_r.o: open.S
+read_r.o: read.S
+sbrk_r.o: sbrk.S
+stat_r.o: stat.S
+unlink_r.o: unlink.S
+write_r.o: write.S
diff --git a/libgloss/sparc/libsys/_exit.S b/libgloss/sparc/libsys/_exit.S
new file mode 100644
index 0000000..52c5c14
--- /dev/null
+++ b/libgloss/sparc/libsys/_exit.S
@@ -0,0 +1,14 @@
+! _exit() system call
+
+#include "syscallasm.h"
+
+ TEXT_SECTION
+ ALIGN (4)
+ GLOBAL (ASM_SYMBOL (_exit))
+ASM_SYMBOL (_exit):
+ mov SYS_exit,%g1
+ ta SYSCALL_TRAP
+
+! If that returns (yikes!), try an illegal insn ...
+
+ WORD (0) \ No newline at end of file
diff --git a/libgloss/sparc/libsys/cerror.S b/libgloss/sparc/libsys/cerror.S
new file mode 100644
index 0000000..8ad99c2
--- /dev/null
+++ b/libgloss/sparc/libsys/cerror.S
@@ -0,0 +1,47 @@
+! Set errno.
+! This function is called by all the syscall stubs.
+!
+! FIXME: We assume errno is the first member of struct _reent.
+! Not sure what to do about this.
+
+#include "syscallasm.h"
+
+ DATA_SECTION
+ ALIGN (4)
+ GLOBAL (ASM_SYMBOL (errno)) ! FIXME: ASM_PRIVATE_SYMBOL ?
+ASM_SYMBOL (errno):
+ WORD (0)
+
+ TEXT_SECTION
+ ALIGN (4)
+
+ GLOBAL (ASM_PRIVATE_SYMBOL (cerror))
+ASM_PRIVATE_SYMBOL (cerror):
+ sethi %hi (ASM_SYMBOL (errno)),%g1
+ st %o0,[%g1+%lo (ASM_SYMBOL (errno))]
+ jmpl %o7+8,%g0
+ mov -1,%o0
+
+ GLOBAL (ASM_PRIVATE_SYMBOL (cerror_r))
+ASM_PRIVATE_SYMBOL (cerror_r):
+ st %o0,[%o1]
+ jmpl %o7+8,%g0
+ mov -1,%o0
+
+! Since all system calls need this file, we put various state globals
+! here as well.
+
+ DATA_SECTION
+
+! CURBRK contains the current top of allocated space.
+! END is a private symbol in svr4, but a public one in sunos4.
+! FIXME: CURBRK is 4 bytes for now.
+
+ ALIGN (4)
+ GLOBAL (ASM_PRIVATE_SYMBOL (curbrk))
+ASM_PRIVATE_SYMBOL (curbrk):
+#ifdef SVR4
+ WORD (ASM_PRIVATE_SYMBOL (end))
+#else
+ WORD (ASM_SYMBOL (end))
+#endif
diff --git a/libgloss/sparc/libsys/configure b/libgloss/sparc/libsys/configure
new file mode 100755
index 0000000..3702cce
--- /dev/null
+++ b/libgloss/sparc/libsys/configure
@@ -0,0 +1,991 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.10
+# 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=
+
+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.10"
+ 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 LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; 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=libsys-crt0.S
+
+# 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'
+
+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
+# 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
+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.
+ for ac_prog in ginstall installbsd 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.
+ # OSF/1 installbsd also uses dspmsg, but is usable.
+ :
+ 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'
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:707: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ if test "${CFLAGS+set}" != set; then
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_gcc_g=yes
+else
+ ac_cv_prog_gcc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
+ if test $ac_cv_prog_gcc_g = yes; then
+ CFLAGS="-g -O"
+ else
+ CFLAGS="-O"
+ fi
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+AS=${AS-as}
+
+AR=${AR-ar}
+
+LD=${LD-ld}
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+host_makefile_frag=${srcdir}/../../config/default.mh
+
+host_makefile_frag_path=$host_makefile_frag
+
+
+
+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
+# 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 |
+ sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
+ >> 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.10"
+ 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%@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
+s%@CC@%$CC%g
+s%@AS@%$AS%g
+s%@AR@%$AR%g
+s%@LD@%$LD%g
+s%@RANLIB@%$RANLIB%g
+s%@host_makefile_frag_path@%$host_makefile_frag_path%g
+/@host_makefile_frag@/r $host_makefile_frag
+s%@host_makefile_frag@%%g
+
+CEOF
+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]", 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 relative srcdir, etc. 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
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+fi; done
+rm -f conftest.subs
+
+
+
+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/sparc/libsys/configure.in b/libgloss/sparc/libsys/configure.in
new file mode 100644
index 0000000..cf3f496
--- /dev/null
+++ b/libgloss/sparc/libsys/configure.in
@@ -0,0 +1,50 @@
+# Configure.in for libgloss/sparc/libsys
+# Copyright (c) 1996 Cygnus Support
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that the above copyright notice and this paragraph are
+# duplicated in all such forms and that any documentation,
+# advertising materials, and other materials related to such
+# distribution and use acknowledge that the software was developed
+# at Cygnus Support, Inc. Cygnus Support, Inc. may not be used to
+# endorse or promote products derived from this software without
+# specific prior written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ(2.5)dnl
+AC_INIT(libsys-crt0.S)
+
+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_PROG_CC
+AS=${AS-as}
+AC_SUBST(AS)
+AR=${AR-ar}
+AC_SUBST(AR)
+LD=${LD-ld}
+AC_SUBST(LD)
+AC_PROG_RANLIB
+
+host_makefile_frag=${srcdir}/../../config/default.mh
+
+dnl We have to assign the same value to other variables because autoconf
+dnl doesn't provide a mechanism to substitute a replacement keyword with
+dnl arbitrary data or pathnames.
+dnl
+host_makefile_frag_path=$host_makefile_frag
+AC_SUBST(host_makefile_frag_path)
+AC_SUBST_FILE(host_makefile_frag)
+
+AC_OUTPUT(Makefile)
diff --git a/libgloss/sparc/libsys/isatty.c b/libgloss/sparc/libsys/isatty.c
new file mode 100644
index 0000000..3c64647
--- /dev/null
+++ b/libgloss/sparc/libsys/isatty.c
@@ -0,0 +1,17 @@
+/* isatty.c */
+
+/* Dumb implementation so programs will at least run. */
+
+#include <sys/stat.h>
+
+int
+isatty (int fd)
+{
+ struct stat buf;
+
+ if (fstat (fd, &buf) < 0)
+ return 0;
+ if (S_ISCHR (buf.st_mode))
+ return 1;
+ return 0;
+}
diff --git a/libgloss/sparc/libsys/libsys-crt0.S b/libgloss/sparc/libsys/libsys-crt0.S
new file mode 100644
index 0000000..ef1b29d
--- /dev/null
+++ b/libgloss/sparc/libsys/libsys-crt0.S
@@ -0,0 +1,127 @@
+! C run time start off
+
+! This file supports:
+!
+! - both 32bit pointer and 64bit pointer environments (at compile time)
+! - an imposed stack bias (of 2047) (at run time)
+! - medium/low and medium/anywhere code models (at run time)
+
+! Initial stack setup:
+!
+! bottom of stack (higher memory address)
+! ...
+! text of environment strings
+! text of argument strings
+! envp[envc] = 0 (4/8 bytes)
+! ...
+! env[0] (4/8 bytes)
+! argv[argc] = 0 (4/8 bytes)
+! ...
+! argv[0] (4/8 bytes)
+! argc (4/8 bytes)
+! register save area (64 bits by 16 registers = 128 bytes)
+! top of stack (%sp)
+
+! Stack Bias:
+!
+! It is the responsibility of the o/s to set this up.
+! We handle both a 0 and 2047 value for the stack bias.
+
+! Medium/Anywhere code model support:
+!
+! In this model %g4 points to the start of the data segment.
+! The text segment can go anywhere, but %g4 points to the *data* segment.
+! It is up to the compiler/linker to get this right.
+!
+! Since this model is statically linked the start of the data segment
+! is known at link time. Eg:
+!
+! sethi %hh(data_start), %g1
+! sethi %lm(data_start), %g4
+! or %g1, %hm(data_start), %g1
+! or %g4, %lo(data_start), %g4
+! sllx %g1, 32, %g1
+! or %g4, %g1, %g4
+!
+! FIXME: For now we just assume 0.
+
+! FIXME: if %g1 contains a non-zero value, atexit() should be invoked
+! with this value.
+
+#include "syscallasm.h"
+
+#ifndef TARGET_PTR_SIZE
+#define TARGET_PTR_SIZE 32
+#endif
+
+ TEXT_SECTION
+ ALIGN (4)
+ GLOBAL (ASM_PRIVATE_SYMBOL (start))
+ASM_PRIVATE_SYMBOL (start):
+ clr %fp
+
+! We use %g4 even if the code model is Medium/Low (simplifies the code).
+
+ clr %g4 ! Medium/Anywhere base reg
+
+! If there is a stack bias in effect, account for it in %g5. Then always
+! add %g5 to stack references below. This way the code can be used with
+! or without an imposed bias.
+
+ andcc %sp, 1, %g5
+ bnz,a .LHaveBias
+ mov 2047, %g5
+.LHaveBias:
+ add %sp, %g5, %sp
+
+#if TARGET_PTR_SIZE == 32
+ ! FIXME: We apparently assume here that there is no reserved word.
+ ! This is probably correct, but try to verify it.
+ ld [%sp + 0x80], %o0 ! argc
+ add %sp, 0x84, %o1 ! argv
+ add %o0, 1, %o2
+ sll %o2, 2, %o2
+#else /* TARGET_PTR_SIZE == 64 */
+ ld [%sp + 0x8c], %o0 ! argc.lo
+ add %sp, 0x90, %o1 ! argv
+ add %o0, 1, %o2
+ sll %o2, 3, %o2
+#endif
+ add %o1, %o2, %o2 ! envp
+ sethi %hi (ASM_SYMBOL (environ)), %o3
+ or %o3, %lo (ASM_SYMBOL (environ)), %o3
+#if TARGET_PTR_SIZE == 32
+ st %o2, [%o3 + %g4]
+#else /* TARGET_PTR_SIZE == 64 */
+ stx %o2, [%o3 + %g4]
+#endif
+
+! Restore any stack bias before we call main() ...
+
+ sub %sp, %g5, %sp
+
+ GLOBAL (ASM_SYMBOL (main))
+ call ASM_SYMBOL (main)
+
+! FIXME: Not sure if this is needed anymore.
+#if TARGET_PTR_SIZE == 32
+ sub %sp, 0x20, %sp ! room to push args
+#else /* TARGET_PTR_SIZE == 64 */
+ sub %sp, 0x30, %sp ! room to push args
+#endif
+
+ GLOBAL (ASM_SYMBOL (exit))
+ call ASM_SYMBOL (exit)
+ nop
+
+ GLOBAL (ASM_SYMBOL (_exit))
+ call ASM_SYMBOL (_exit)
+ nop
+
+ set SYS_exit, %g1
+ ta SYSCALL_TRAP ! in case user redefines __exit
+
+! If all the above methods fail to terminate the program, try an illegal insn.
+! If that does not work, the o/s is hosed more than we are.
+
+ WORD (0)
diff --git a/libgloss/sparc/libsys/sbrk.S b/libgloss/sparc/libsys/sbrk.S
new file mode 100644
index 0000000..b862621
--- /dev/null
+++ b/libgloss/sparc/libsys/sbrk.S
@@ -0,0 +1,66 @@
+! sbrk() system call
+
+#include "syscallasm.h"
+
+ TEXT_SECTION
+ ALIGN (4)
+#ifdef REENT
+ GLOBAL (ASM_SYMBOL (_sbrk_r))
+ASM_SYMBOL (_sbrk_r):
+ mov %o0,%o5
+ mov %o1,%o0
+#else
+ GLOBAL (ASM_SYMBOL (sbrk))
+ASM_SYMBOL (sbrk):
+#endif
+ add %o0,7,%o0
+ andn %o0,7,%o0
+ sethi %hi (ASM_PRIVATE_SYMBOL (curbrk)),%o2
+#ifdef __sparc_v9__
+ lduw [%o2+%lo (ASM_PRIVATE_SYMBOL (curbrk))],%o3
+#else
+ ld [%o2+%lo (ASM_PRIVATE_SYMBOL (curbrk))],%o3
+#endif
+ add %o3,7,%o3
+ andn %o3,7,%o3
+ add %o3,%o0,%o0
+ mov %o0,%o4
+ mov SYS_brk,%g1
+ ta SYSCALL_TRAP
+ bcs err
+ nop
+ st %o4,[%o2+%lo (ASM_PRIVATE_SYMBOL (curbrk))]
+ jmpl %o7+8,%g0
+ mov %o3,%o0
+
+#ifdef REENT
+ GLOBAL (ASM_SYMBOL (_brk_r))
+ASM_SYMBOL (_brk_r):
+ mov %o0,%o5
+ mov %o1,%o0
+#else
+ GLOBAL (ASM_SYMBOL (brk))
+ASM_SYMBOL (brk):
+#endif
+ add %o0,7,%o0
+ andn %o0,7,%o0
+ mov %o0,%o2
+ mov SYS_brk,%g1
+ ta SYSCALL_TRAP
+ bcs err
+ nop
+ sethi %hi (ASM_PRIVATE_SYMBOL (curbrk)),%o3
+ st %o2,[%o3+%lo (ASM_PRIVATE_SYMBOL (curbrk))]
+ retl
+ mov %g0,%o0
+
+err:
+#ifdef REENT
+ sethi %hi (ASM_PRIVATE_SYMBOL (cerror_r)),%g1
+ or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror_r)),%g1
+#else
+ sethi %hi (ASM_PRIVATE_SYMBOL (cerror)),%g1
+ or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror)),%g1
+#endif
+ jmpl %g1,%g0
+ mov %o5,%o1
diff --git a/libgloss/sparc/libsys/syscall.h b/libgloss/sparc/libsys/syscall.h
new file mode 100644
index 0000000..457fe3a
--- /dev/null
+++ b/libgloss/sparc/libsys/syscall.h
@@ -0,0 +1,39 @@
+#ifndef _SYSCALL_H_
+#define _SYSCALL_H_
+
+/*
+ * This file defines the minimal set of system calls needed
+ * by newlib for both sunos4 and solaris2.
+ *
+ * WARNING: This file can be included by assembler files.
+ */
+
+/* Process control. */
+#define SYS_exit 1
+#define SYS_getpid 20
+#define SYS_kill 37
+
+/* File stuff. */
+#define SYS_read 3
+#define SYS_write 4
+#define SYS_open 5
+#define SYS_close 6
+#define SYS_lseek 19
+
+/* Memory stuff. */
+#define SYS_brk 17
+
+/* Directory stuff. */
+#define SYS_unlink 10
+#define SYS_chdir 12
+#ifdef SVR4
+#define SYS_stat 18
+#define SYS_fstat 28
+#define SYS_lstat 88
+#else
+#define SYS_stat 38
+#define SYS_fstat 62
+#define SYS_lstat 40
+#endif
+
+#endif /* _SYSCALL_H_ */
diff --git a/libgloss/sparc/libsys/syscallasm.h b/libgloss/sparc/libsys/syscallasm.h
new file mode 100644
index 0000000..55f25cd
--- /dev/null
+++ b/libgloss/sparc/libsys/syscallasm.h
@@ -0,0 +1,93 @@
+#ifndef _SYSCALLASM_H_
+#define _SYSCALLASM_H_
+
+/*
+ * This file defines the system calls for SPARC for the assembler.
+ * Anything C-ish is not allowed in this file.
+ * C files should include syscall.h.
+ */
+
+#include "syscall.h"
+
+/* Some macros for writing assember syscall stubs. */
+
+#ifdef SVR4
+#define TEXT_SECTION .section ".text"
+#define DATA_SECTION .section ".data"
+#define ALIGN(x) .align x
+#define GLOBAL(sym) .global sym
+#define WORD(x) .long x
+#define ASM_SYMBOL(name) name
+#define ASM_PRIVATE_SYMBOL(name) _##name
+#define SYSCALL_TRAP 8
+#else
+#define TEXT_SECTION .text
+#define DATA_SECTION .data
+#define ALIGN(x) .align x
+#define GLOBAL(sym) .global sym
+#define WORD(x) .word x
+#define ASM_SYMBOL(name) _##name
+#define ASM_PRIVATE_SYMBOL(name) name
+#define SYSCALL_TRAP 0
+#endif
+
+#define defsyscall(name, n) \
+ TEXT_SECTION ; \
+ ALIGN (4) ; \
+ GLOBAL (ASM_SYMBOL (name)) ; \
+ASM_SYMBOL (name): \
+ mov n,%g1 ; \
+ ta SYSCALL_TRAP ; \
+ bcc noerr ; \
+ sethi %hi (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \
+ or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \
+ jmpl %g1+%g0,%g0 ; \
+ nop ; \
+noerr: \
+ jmpl %o7+8,%g0 ; \
+ nop
+
+/* Support for reentrant syscalls. The "struct _reent *" arg is always the
+ the first one. After that we allow up to four additional args. We could
+ allow more, but that's all we need for now.
+
+ It may seem inefficient to have the reent arg be the first one as it means
+ copying all the other args into place (as opposed to making the reent arg
+ the last one in which case there wouldn't be any copying). I chose a clean
+ design over an extra four instructions in a system call. All other
+ reentrant functions use the first arg this way.
+ ??? Of course this scheme breaks down if we need to support 6 or more args.
+
+ And of course the system calls aren't *really* reentrant. The intent
+ is to exercise the reentrancy framework rather than provide/claim
+ real reentrancy for this port.
+*/
+
+#define defsyscall_r(name, n) \
+ TEXT_SECTION ; \
+ ALIGN (4) ; \
+ GLOBAL (ASM_SYMBOL (name)) ; \
+ASM_SYMBOL (name): \
+ mov n,%g1 ; \
+ mov %o0,%o5 ; \
+ mov %o1,%o0 ; \
+ mov %o2,%o1 ; \
+ mov %o3,%o2 ; \
+ mov %o4,%o3 ; \
+ ta SYSCALL_TRAP ; \
+ bcc noerr ; \
+ sethi %hi (ASM_PRIVATE_SYMBOL (cerror_r)),%g1 ; \
+ or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror_r)),%g1 ; \
+ jmpl %g1+%g0,%g0 ; \
+ mov %o5,%o1 ; \
+noerr: \
+ jmpl %o7+8,%g0 ; \
+ nop
+
+#define seterrno() \
+ sethi %hi (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \
+ or %g1,%lo (ASM_PRIVATE_SYMBOL (cerror)),%g1 ; \
+ jmpl %g1+%g0,%g0 ; \
+ nop
+
+#endif /* _SYSCALLASM_H_ */
diff --git a/libgloss/sparc/libsys/template.S b/libgloss/sparc/libsys/template.S
new file mode 100644
index 0000000..e1b437b
--- /dev/null
+++ b/libgloss/sparc/libsys/template.S
@@ -0,0 +1,14 @@
+/* system call template */
+
+/* Lots of system calls are trivial functions, so we build their source files
+ from a template. New syscalls can be added simply by editing the
+ Makefile!
+
+ Usage: Compile this file with "func" set to the name of the syscall. */
+
+#include "syscallasm.h"
+
+#define concat(a,b) a##b
+#define makesys(a) concat (SYS_, a)
+
+ defsyscall (func, makesys(func))
diff --git a/libgloss/sparc/libsys/template_r.S b/libgloss/sparc/libsys/template_r.S
new file mode 100644
index 0000000..3a9b5f8
--- /dev/null
+++ b/libgloss/sparc/libsys/template_r.S
@@ -0,0 +1,26 @@
+/* reentrant system call template */
+
+/* Lots of system calls are trivial functions, so we build their source files
+ from a template. New syscalls can be added simply by editing the
+ Makefile!
+
+ The system calls aren't necessarily reentrant. If we were being used in
+ an embedded system they could be. Reentrant syscalls are also used,
+ however, to provide ANSI C namespace clean access to the host o/s.
+
+ Usage: Compile this file with "func" set to the name of the syscall. */
+
+#include "syscallasm.h"
+
+#define concat(a,b) a##b
+#define concat3(a,b,c) a##b##c
+#define makesys(a) concat (SYS_, a)
+#define make_r_fn(a) concat3 (_, a, _r)
+
+/* The leading _'s get turned into #'s by the Makefile. */
+
+_ifdef REENT
+ defsyscall_r (make_r_fn (func), makesys (func))
+_else
+ defsyscall (func, makesys (func))
+_endif
diff --git a/libgloss/sparc/salib-701.c b/libgloss/sparc/salib-701.c
new file mode 100644
index 0000000..404ad6c
--- /dev/null
+++ b/libgloss/sparc/salib-701.c
@@ -0,0 +1,288 @@
+/* Stand-alone library for Sparclet 701 board
+ *
+ * Copyright (c) 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.
+ */
+
+#define RAM_BASE ((unsigned char *)0x12000000) /* Start of cacheable dram */
+#define DCACHE_LINES 128 /* Number of lines in data cache */
+#define DCACHE_LINE_SIZE 16 /* Bytes per data cache line */
+#define DCACHE_BANKS 4 /* 4-way associative */
+#define CACHE_INST_TAG_ADDR ((unsigned char *)0xc0020000) /* I-Cache tag base address */
+#define ALL_BANKS 0x0000f000 /* Selects all 4 cache banks */
+#define ICACHE_LINES 128 /* Number of lines in inst cache */
+#define ICACHE_LINE_SIZE 32 /* Bytes per inst cache line */
+
+/* I/O Base addresses */
+#define CACHE_INST_BASE_ADD 0xc0000000
+#define CACHE_DATA_BASE_ADD 0xc8000000
+#define _InstrCacheCtlBase 0xc0000000
+#define _DataCacheCtlBase 0xc8000000
+
+#define USART_BASE_ADD 0x92000000
+#define USART_BASE_ADRS(n) (USART_BASE_ADD + ((n)<<21)) /*0..3*/
+
+/* Serial receiver definitions */
+#define USART_RX_CHAR(n) (*(unsigned char *) (USART_BASE_ADRS(n) +(2<<19)))
+#define USART_RX_CTRL_BASE_ADRS(n) (USART_BASE_ADRS(n)+(3<<19))
+#define URSTR(n) (*(unsigned int *) (USART_RX_CTRL_BASE_ADRS(n)+(2<<15)))
+#define URSTR_CHAR_NUM 0x1f00 /* Bits 8-12 */
+
+/* Serial receiver definitions */
+#define USART_TX_CHAR(n) (*(unsigned char *) (USART_BASE_ADRS(n)+3))
+#define USART_TX_CTRL_BASE_ADRS(n) (USART_BASE_ADRS(n)+(1<<19))
+#define UTSTR(n) (*(unsigned int *) (USART_TX_CTRL_BASE_ADRS(n)+(2<<15)))
+#define UTSTR_CHAR_FREE 0x1f0 /* Bits 4-8 */
+
+/* Cache definitions */
+#define DCCA_NB_LINES 128 /* Nb of lines of the cache */
+/* Bank number, used for Cache Memory and Cache Tag */
+#define ICCA_B3 0x000008000 /* Bit 15 - 1:Bank3 selected */
+#define ICCA_B2 0x000004000 /* Bit 14 - 1:Bank2 selected */
+#define ICCA_B1 0x000002000 /* Bit 13 - 1:Bank1 selected */
+#define ICCA_B0 0x000001000 /* Bit 12 - 1:Bank0 selected */
+/* Register address, show which register is to be checked/updated */
+#define ICCACR 0x00000000 /* Bits 17 - 16 - Control register */
+#define ICCAMEM 0x00010000 /* Bits 17 - 16 - Cache memory */
+#define DCCACR 0x00000000 /* Bits 16 - 15 - Control register */
+/* Instruction Cache Controller Register */
+#define ICCR_DISABLE 0xfffffffe /* Reset enable bit */
+
+/* Serial I/O routines */
+
+#define STUB_PORT 1 /* 0 = serial port A; 1 = serial port B */
+
+static volatile unsigned char *rx_fifo = &USART_RX_CHAR(STUB_PORT);
+static volatile unsigned int *rx_status = &URSTR(STUB_PORT);
+
+static volatile unsigned char *tx_fifo = &USART_TX_CHAR(STUB_PORT);
+static volatile unsigned int *tx_status = &UTSTR(STUB_PORT);
+
+/* library-free debug reoutines */
+#ifdef XDEBUG
+#define XDBG_MSG(x) pmsg(x)
+#define XDBG_HEX(x) phex(x)
+#else
+#define XDBG_MSG(x)
+#define XDBG_HEX(x)
+#endif
+
+static int
+rx_rdy()
+{
+ return (*rx_status & URSTR_CHAR_NUM);
+}
+
+static unsigned char
+rx_char()
+{
+ return *rx_fifo;
+}
+
+void
+tx_char(char c)
+{
+ *tx_fifo = c;
+}
+
+static int
+tx_rdy()
+{
+ return (*tx_status & UTSTR_CHAR_FREE);
+}
+
+int
+getDebugChar()
+{
+ while (!rx_rdy())
+ ;
+ return rx_char();
+}
+
+void
+putDebugChar(int c)
+{
+ while (!tx_rdy())
+ ;
+ tx_char(c);
+}
+
+#ifdef XDEBUG
+/* library-free debug reoutines */
+/* print a string */
+void pmsg(char *p)
+{
+ while (*p)
+ {
+ if (*p == '\n')
+ putDebugChar('\r');
+ putDebugChar(*p++);
+ }
+}
+
+/* print a hex number */
+void phex(long x)
+{
+ char buf[9];
+ int i;
+
+ buf[8] = '\0';
+ for (i = 7; i >= 0; i--)
+ {
+ char c = x & 0x0f;
+ buf[i] = c < 10 ? c + '0' : c - 10 + 'A';
+ x >>= 4;
+ }
+ pmsg(buf);
+}
+#endif
+
+/* rdtbr() - read the trap base register */
+
+unsigned long rdtbr();
+
+asm("
+ .text
+ .align 4
+ .globl _rdtbr
+_rdtbr:
+ retl
+ mov %tbr, %o0
+");
+
+/* wrtbr() - write the trap base register */
+
+void wrtbr(unsigned long);
+
+asm("
+ .text
+ .align 4
+ .globl _wrtbr
+_wrtbr:
+ retl
+ mov %o0, %tbr
+");
+
+/* Each entry in the trap vector occupies four words. */
+
+struct trap_entry
+{
+ unsigned sethi_filler:10;
+ unsigned sethi_imm22:22;
+ unsigned jmpl_filler:19;
+ unsigned jmpl_simm13:13;
+ unsigned long filler[2];
+};
+
+extern struct trap_entry fltr_proto;
+asm ("
+ .data
+ .globl _fltr_proto
+ .align 4
+_fltr_proto: ! First level trap routine prototype
+ sethi 0, %l0
+ jmpl 0+%l0, %g0
+ nop
+ nop
+
+ .text
+ .align 4
+");
+
+/* copy_vectors - Copy the trap vectors from ROM to RAM, set the TBR register
+ to point to the RAM vectors, and return the address of the RAM vectors. */
+
+extern struct trap_entry __trap_vectors[256]; /* defined in matra.ld */
+
+struct trap_entry *copy_vectors()
+{
+ int i;
+ struct trap_entry *old = (struct trap_entry *) (rdtbr() & ~0xfff);
+
+ XDBG_MSG("Copying vectors...\n");
+ for (i = 0; i < 256; i++)
+ __trap_vectors[i] = old[i];
+ wrtbr ((unsigned long)__trap_vectors);
+ XDBG_MSG("Done\n");
+ return __trap_vectors;
+}
+
+
+void
+disable_cache()
+{
+ unsigned long *ptr;
+ static unsigned long CACHE_shadow_iccr = 0; /* Because CR cannot be read */
+ static unsigned long CACHE_shadow_dccr = 0; /* Because CR cannot be read */
+
+ XDBG_MSG("Disabling cache...\n");
+ ptr = (unsigned long*)(CACHE_INST_BASE_ADD | ICCACR);
+ CACHE_shadow_iccr = CACHE_shadow_iccr & ICCR_DISABLE;
+ *ptr = CACHE_shadow_iccr;
+
+ ptr = (unsigned long*)(CACHE_DATA_BASE_ADD | DCCACR);
+ CACHE_shadow_dccr = CACHE_shadow_dccr & ICCR_DISABLE;
+ *ptr = CACHE_shadow_dccr;
+ XDBG_MSG("Done\n");
+}
+
+/* Flush the instruction cache. We need to do this for the debugger stub so
+ that breakpoints, et. al. become visible to the instruction stream after
+ storing them in memory. FIXME!!
+ */
+
+void
+flush_i_cache ()
+{
+ volatile unsigned char *addr;
+
+ /* First, force all dirty items in the data cache to be moved out to real
+ memory. This is done by making read refs to alternate addresses that will
+ fill up all four banks for each line. Note that we actually have to
+ reference 8 locs per line just in case the region of memory we use is one
+ of the areas that needs to be flushed. */
+
+ for (addr = RAM_BASE;
+ addr < RAM_BASE + (DCACHE_LINES * DCACHE_LINE_SIZE * DCACHE_BANKS) * 2;
+ addr += DCACHE_LINE_SIZE)
+ *addr; /* Read the loc */
+
+ /* Now, flush the instruction cache. */
+
+ for (addr = CACHE_INST_TAG_ADDR + ALL_BANKS;
+ addr <= CACHE_INST_TAG_ADDR + ALL_BANKS + ICACHE_LINES * ICACHE_LINE_SIZE;
+ addr += ICACHE_LINE_SIZE)
+ *(unsigned long *)addr = 0; /* Clr tag entry for all banks on this line */
+}
+
+/* Setup trap TT to go to ROUTINE. */
+
+void
+exceptionHandler (int tt, unsigned long routine)
+{
+ static struct trap_entry *tb; /* Trap vector base address */
+
+ if (!tb)
+ {
+ tb = copy_vectors(); /* Copy trap vectors to RAM */
+ disable_cache(); /* Disable cache FIXME!! */
+ }
+
+ XDBG_MSG("Setting exception handler for trap...\n");
+
+ tb[tt] = fltr_proto;
+
+ tb[tt].sethi_imm22 = routine >> 10;
+ tb[tt].jmpl_simm13 = routine & 0x3ff;
+
+ XDBG_MSG("Done\n");
+}
diff --git a/libgloss/sparc/salib.c b/libgloss/sparc/salib.c
new file mode 100644
index 0000000..8076a6b
--- /dev/null
+++ b/libgloss/sparc/salib.c
@@ -0,0 +1,388 @@
+/* Stand-alone library for SPARClite
+ *
+ * Copyright (c) 1995 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include "sparclite.h"
+#include "asm.h"
+
+/* LED blinking pattern can be changed by modifying __led_algorithm. */
+
+enum ledtype
+{
+ led_marching, /* marching pattern, only one led on at a time */
+ led_random, /* pseudo-random pattern */
+ led_blinking, /* all leds blink on and off */
+ led_none /* leds off all the time */
+};
+
+enum ledtype __led_algorithm = led_marching;
+
+
+/* Pointer to hook for outbyte, set by stub's exception handler. */
+void (*__outbyte_hook) (int c);
+
+#ifdef SL931
+#define SDTR_BASE 0x200
+#define SDTR_ASI 1
+#define SDTR_SHIFT 0
+#else
+#define SDTR_BASE 0x10000000
+#define SDTR_ASI 4
+#define SDTR_SHIFT 16
+#endif
+
+#define get_uart_status(PORT) \
+ (read_asi (SDTR_ASI, SDTR_BASE + 0x24 + (PORT) * 0x10) >> SDTR_SHIFT)
+
+#define xmt_char(PORT, C) \
+ write_asi (SDTR_ASI, SDTR_BASE + 0x20 + (PORT) * 0x10, (C) << SDTR_SHIFT)
+
+#define rcv_char(PORT) \
+ (read_asi (SDTR_ASI, SDTR_BASE + 0x20 + (PORT) * 0x10) >> SDTR_SHIFT)
+
+void putDebugChar();
+
+#if 0
+void
+set_uart (cmd)
+ int cmd;
+{
+ write_asi (SDTR_ASI, SDTR_BASE + 0x24, cmd << SDTR_SHIFT);
+}
+
+void
+set_timer_3 (val)
+ int val;
+{
+ write_asi (SDTR_ASI, SDTR_BASE + 0x78, val << SDTR_SHIFT);
+}
+#endif
+
+
+asm("
+ .text
+ .align 4
+
+! Register window overflow handler. Come here when save would move us
+! into the invalid window. This routine runs with traps disabled, and
+! must be careful not to touch the condition codes, as PSR is never
+! restored.
+!
+! We are called with %l0 = wim, %l1 = pc, %l2 = npc
+
+ .globl " STRINGSYM(win_ovf) "
+" STRINGSYM(win_ovf) ":
+ mov %g1, %l3 ! Save g1, we use it to hold the wim
+ srl %l0, 1, %g1 ! Rotate wim right
+ sll %l0, __WINSIZE-1, %l0
+ or %l0, %g1, %g1
+
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l3, %g1 ! Restore %g1
+
+ jmpl %l1, %g0
+ rett %l2
+
+! Register window underflow handler. Come here when restore would move us
+! into the invalid window. This routine runs with traps disabled, and
+! must be careful not to touch the condition codes, as PSR is never
+! restored.
+!
+! We are called with %l0 = wim, %l1 = pc, %l2 = npc
+
+ .globl " STRINGSYM(win_unf) "
+" STRINGSYM(win_unf) ":
+ sll %l0, 1, %l3 ! Rotate wim left
+ srl %l0, __WINSIZE-1, %l0
+ or %l0, %l3, %l0
+
+ mov %l0, %wim ! Install the new wim
+
+ restore ! User's window
+ restore ! His caller's window
+
+ ldd [%sp + 0 * 4], %l0 ! restore L & I registers
+ ldd [%sp + 2 * 4], %l2
+ ldd [%sp + 4 * 4], %l4
+ ldd [%sp + 6 * 4], %l6
+
+ ldd [%sp + 8 * 4], %i0
+ ldd [%sp + 10 * 4], %i2
+ ldd [%sp + 12 * 4], %i4
+ ldd [%sp + 14 * 4], %i6
+
+ save %g0, %g0, %g0 ! Back to trap window
+ save %g0, %g0, %g0
+
+ jmpl %l1, %g0
+ rett %l2
+
+! Read the TBR.
+
+ .globl " STRINGSYM(rdtbr) "
+" STRINGSYM(rdtbr) ":
+ retl
+ mov %tbr, %o0
+
+");
+
+extern unsigned long rdtbr();
+
+void
+die(val)
+ int val;
+{
+ static unsigned char *leds = (unsigned char *)0x02000003;
+
+ *leds = val;
+
+ while (1) ;
+}
+
+/* Each entry in the trap vector occupies four words. */
+
+struct trap_entry
+{
+ unsigned sethi_filler:10;
+ unsigned sethi_imm22:22;
+ unsigned jmpl_filler:19;
+ unsigned jmpl_simm13:13;
+ unsigned long filler[2];
+};
+
+extern struct trap_entry fltr_proto;
+asm ("
+ .data
+ .globl " STRINGSYM(fltr_proto) "
+ .align 4
+" STRINGSYM(fltr_proto) ": ! First level trap routine prototype
+ sethi 0, %l0
+ jmpl 0+%l0, %g0
+ nop
+ nop
+
+ .text
+ .align 4
+");
+
+/* Setup trap TT to go to ROUTINE. If TT is between 0 and 255 inclusive, the
+ normal trap vector will be used. If TT is 256, then it's for the SPARClite
+ DSU, and that always vectors off to 255 unrelocated.
+*/
+
+void
+exceptionHandler (tt, routine)
+ int tt;
+ unsigned long routine;
+{
+ struct trap_entry *tb; /* Trap vector base address */
+
+ if (tt != 256)
+ tb = (struct trap_entry *) (rdtbr() & ~0xfff);
+ else
+ {
+ tt = 255;
+ tb = (struct trap_entry *) 0;
+ }
+
+ tb[tt] = fltr_proto;
+
+ tb[tt].sethi_imm22 = routine >> 10;
+ tb[tt].jmpl_simm13 = routine & 0x3ff;
+}
+
+void
+update_leds()
+{
+ static unsigned char *leds = (unsigned char *)0x02000003;
+ static enum ledtype prev_algorithm = led_none;
+
+ if (prev_algorithm != __led_algorithm)
+ {
+ *leds = 0xff; /* turn the LEDs off */
+ prev_algorithm = __led_algorithm;
+ }
+
+ switch (__led_algorithm)
+ {
+ case led_marching:
+ {
+ static unsigned char curled = 1;
+ static unsigned char dir = 0;
+
+ *leds = ~curled;
+
+ if (dir)
+ curled <<= 1;
+ else
+ curled >>= 1;
+
+ if (curled == 0)
+ {
+ if (dir)
+ curled = 0x80;
+ else
+ curled = 1;
+ dir = ~dir;
+ }
+ break;
+ }
+
+ case led_random:
+ {
+ static unsigned int next = 0;
+ *leds = next & 0xff;
+ next = (next * 1103515245 + 12345) & 0x7fff;
+ break;
+ }
+
+ case led_blinking:
+ {
+ static unsigned char next = 0;
+ *leds = next;
+ next = ~next;
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+ /* 1/5th of a second? */
+
+#define LEDTIME (20000000 / 500)
+
+unsigned long ledtime = LEDTIME;
+
+int
+inbyte()
+{
+ return (getDebugChar());
+}
+
+int
+getDebugChar()
+{
+ unsigned long countdown = ledtime;
+
+ update_leds();
+
+ while (1)
+ {
+ if ((get_uart_status(0) & 2) != 0) break;
+
+ if (countdown-- == 0)
+ {
+ countdown = ledtime;
+ update_leds();
+ }
+ }
+
+ return rcv_char(0);
+}
+
+/* Output one character to the serial port */
+void
+outbyte(c)
+ int c;
+{
+ if (__outbyte_hook)
+ __outbyte_hook (c);
+ else
+ putDebugChar(c);
+}
+
+void
+putDebugChar(c)
+ int c;
+{
+ update_leds();
+
+ while ((get_uart_status(0) & 1) == 0) ;
+
+ xmt_char(0, c);
+}
+
+#if 0
+int
+write(fd, data, length)
+ int fd;
+ unsigned char *data;
+ int length;
+{
+ int olength = length;
+
+ while (length--)
+ putDebugChar(*data++);
+
+ return olength;
+}
+
+int
+read(fd, data, length)
+ int fd;
+ unsigned char *data;
+ int length;
+{
+ int olength = length;
+ int c;
+
+ while (length--)
+ *data++ = getDebugChar();
+
+ return olength;
+}
+#endif
+
+/* Set the baud rate for the serial port, returns 0 for success,
+ -1 otherwise */
+
+#if 0
+int
+set_baud_rate(baudrate)
+ int baudrate;
+{
+ /* Convert baud rate to uart clock divider */
+ switch (baudrate)
+ {
+ case 38400:
+ baudrate = 16;
+ break;
+ case 19200:
+ baudrate = 33;
+ break;
+ case 9600:
+ baudrate = 65;
+ break;
+ default:
+ return -1;
+ }
+
+ set_timer_3(baudrate); /* Set it */
+}
+#endif
diff --git a/libgloss/sparc/slite.h b/libgloss/sparc/slite.h
new file mode 100644
index 0000000..4762e3f
--- /dev/null
+++ b/libgloss/sparc/slite.h
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#define STACK_SIZE 16 * 1024
+#define TRAP_STACK_SIZE 4 * 1024
+#define NUM_REGS 20
+
+#ifdef SL933
+#define NUMBER_OF_REGISTER_WINDOWS 6
+#else
+#define NUMBER_OF_REGISTER_WINDOWS 8
+#endif
+
+#if (NUMBER_OF_REGISTER_WINDOWS == 8)
+#define SPARC_PSR_CWP_MASK 0x07 /* bits 0 - 4 */
+#elif (NUMBER_OF_REGISTER_WINDOWS == 16)
+#define SPARC_PSR_CWP_MASK 0x0F /* bits 0 - 4 */
+#elif (NUMBER_OF_REGISTER_WINDOWS == 32)
+#define SPARC_PSR_CWP_MASK 0x1F /* bits 0 - 4 */
+#else
+#error "Unsupported number of register windows for this cpu"
+#endif
+
+/* The traptable has to be the first code in a boot PROM. */
+
+/*
+ * Entry for traps which jump to a programmer-specified trap handler.
+ */
+
+#define TRAP(_handler) \
+ sethi %hi(_handler), %l3 ; \
+ jmpl %l3+%lo(_handler), %g0 ; \
+ mov %wim, %l0 ; \
+ nop
+
+/* Unexcpected trap will halt the processor by forcing it to error state */
+#if 1
+#define BAD_TRAP ta 0; nop; nop; nop;
+#else
+#define BAD_TRAP \
+ mov %psr, l0 ; \
+ mov 0x0, %o0 ; \
+ sethi %hi(SYM(bad_trap)), l4 ; \
+ jmp l4+%lo(SYM(bad_trap));
+#endif
+
+/* Software trap. Treat as BAD_TRAP for the time being... */
+#if 1
+#define SOFT_TRAP BAD_TRAP
+#else
+#define SOFT_TRAP \
+ mov $psr, $l0 ; \
+ mov 0x0, $o0 ; \
+ sethi $hi(SYM(soft_trap)), l4 ; \
+ jmp l4+$lo(SYM(soft_trap));
+#endif
+
+#define PSR_INIT 0x10c0 /* Disable traps, set s and ps */
+#define TBR_INIT 0
+#define WIM_INIT 2
+#define SP_INIT 0x023ffff0
+
+/* Macros for reading and writing to arbitrary address spaces. Note that ASI
+ must be a constant (sorry, but the SPARC can only specify ASIs as part of an
+ instruction. */
+
+#define read_asi(ASI, LOC) \
+ ({ \
+ unsigned int val; \
+ __asm__ volatile ("lda [%r1]%2,%0" : "=r" (val) : "rJ" (LOC), "I" (ASI)); \
+ val; \
+ })
+
+#define write_asi(ASI, LOC, VAL) \
+ __asm__ volatile ("sta %0,[%r1]%2" : : "r" (VAL), "rJ" (LOC), "I" (ASI));
+
+/*
+ * Use this when modifying registers that cause memory to be modified. This
+ * will cause GCC to reload all values after this point.
+ */
+#define write_asi_volatile(ASI, LOC, VAL) \
+ __asm__ volatile ("sta %0,[%r1]%2" : : "r" (VAL), "rJ" (LOC), "I" (ASI) \
+ : "memory");
+
+#define WRITE_PC(x) registers[PC] = x; registers[NPC] = x + 4;
+
+/*
+ * Processor Status Register (psr)
+ *
+ * 31 28|27 24|23 20|19 12|11 9|7|6|5|4 0
+ * +------+-------+-------+-------+------+-+-+-+--------+
+ * | impl | ver | icc | res. | pil | | | | cwp |
+ * +------+-------+-------+-------+------+-+-+-+--------+
+ * S P E
+ * S T
+ * if ET = 1, traps are enabled, 0 means disabled.
+ * if S = 1, you're in supervisor mode, 0 means user mode.
+ * cwp points to the current window.
+ *
+ * Trap Base Register (tbr)
+ *
+ * 31 12|11 4|3 0
+ * +--------------+--------------+------+
+ * | tba | tt | null |
+ * +--------------+--------------+------+
+ *
+ * tba contains the most sig. 20 bits of the tbr base address
+ * tt is the trap number.
+ *
+ * Window Invalid Register (wim)
+ * 31 8| 7| 6| 5| 4| 3| 2| 1| 0
+ * +-------------+--+--+--+--+--+--+--+--+
+ * | res. |w7|w6|w5|w4|w3|w2|w1|w0|
+ * +-------------+--+--+--+--+--+--+--+--+
+ */
+
diff --git a/libgloss/sparc/sparc-stub.c b/libgloss/sparc/sparc-stub.c
new file mode 100644
index 0000000..fa21d72
--- /dev/null
+++ b/libgloss/sparc/sparc-stub.c
@@ -0,0 +1,848 @@
+#include "sparclite.h"
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for SPARC by Stu Grossman, Cygnus Support.
+ *
+ * This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
+ * baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <signal.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+
+extern putDebugChar(); /* write a single character */
+extern getDebugChar(); /* read and return a single char */
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 2048
+
+static int initialized = 0; /* !0 means we've been initialized */
+
+static void set_mem_fault_trap();
+
+static const char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 72
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
+ O0, O1, O2, O3, O4, O5, SP, O7,
+ L0, L1, L2, L3, L4, L5, L6, L7,
+ I0, I1, I2, I3, I4, I5, FP, I7,
+
+ F0, F1, F2, F3, F4, F5, F6, F7,
+ F8, F9, F10, F11, F12, F13, F14, F15,
+ F16, F17, F18, F19, F20, F21, F22, F23,
+ F24, F25, F26, F27, F28, F29, F30, F31,
+ Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR };
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+extern void trap_low();
+
+asm("
+ .reserve trapstack, 1000 * 4, \"bss\", 8
+
+ .data
+ .align 4
+
+in_trap_handler:
+ .word 0
+
+ .text
+ .align 4
+
+! This function is called when any SPARC trap (except window overflow or
+! underflow) occurs. It makes sure that the invalid register window is still
+! available before jumping into C code. It will also restore the world if you
+! return from handle_exception.
+
+ .globl _trap_low
+_trap_low:
+ mov %psr, %l0
+ mov %wim, %l3
+
+ srl %l3, %l0, %l4 ! wim >> cwp
+ cmp %l4, 1
+ bne window_fine ! Branch if not in the invalid window
+ nop
+
+! Handle window overflow
+
+ mov %g1, %l4 ! Save g1, we use it to hold the wim
+ srl %l3, 1, %g1 ! Rotate wim right
+ tst %g1
+ bg good_wim ! Branch if new wim is non-zero
+ nop
+
+! At this point, we need to bring a 1 into the high order bit of the wim.
+! Since we don't want to make any assumptions about the number of register
+! windows, we figure it out dynamically so as to setup the wim correctly.
+
+ not %g1 ! Fill g1 with ones
+ mov %g1, %wim ! Fill the wim with ones
+ nop
+ nop
+ nop
+ mov %wim, %g1 ! Read back the wim
+ inc %g1 ! Now g1 has 1 just to left of wim
+ srl %g1, 1, %g1 ! Now put 1 at top of wim
+ mov %g0, %wim ! Clear wim so that subsequent save
+ nop ! won't trap
+ nop
+ nop
+
+good_wim:
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l4, %g1 ! Restore %g1
+
+window_fine:
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ tst %l5
+ bg recursive_trap
+ inc %l5
+
+ set trapstack+1000*4, %sp ! Switch to trap stack
+
+recursive_trap:
+ st %l5, [%lo(in_trap_handler) + %l4]
+ sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[72] local var
+
+ std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
+ std %g2, [%sp + (24 + 2) * 4]
+ std %g4, [%sp + (24 + 4) * 4]
+ std %g6, [%sp + (24 + 6) * 4]
+
+ std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
+ std %i2, [%sp + (24 + 10) * 4]
+ std %i4, [%sp + (24 + 12) * 4]
+ std %i6, [%sp + (24 + 14) * 4]
+ ! F0->F31 not implemented
+ mov %y, %l4
+ mov %tbr, %l5
+ st %l4, [%sp + (24 + 64) * 4] ! Y
+ st %l0, [%sp + (24 + 65) * 4] ! PSR
+ st %l3, [%sp + (24 + 66) * 4] ! WIM
+ st %l5, [%sp + (24 + 67) * 4] ! TBR
+ st %l1, [%sp + (24 + 68) * 4] ! PC
+ st %l2, [%sp + (24 + 69) * 4] ! NPC
+
+ ! CPSR and FPSR not impl
+
+ or %l0, 0xf20, %l4
+ mov %l4, %psr ! Turn on traps, disable interrupts
+
+ call _handle_exception
+ add %sp, 24 * 4, %o0 ! Pass address of registers
+
+! Reload all of the registers that aren't on the stack
+
+ ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+ ldd [%sp + (24 + 2) * 4], %g2
+ ldd [%sp + (24 + 4) * 4], %g4
+ ldd [%sp + (24 + 6) * 4], %g6
+
+ ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+ ldd [%sp + (24 + 10) * 4], %i2
+ ldd [%sp + (24 + 12) * 4], %i4
+ ldd [%sp + (24 + 14) * 4], %i6
+
+ ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+ ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
+
+ restore ! Ensure that previous window is valid
+ save %g0, %g0, %g0 ! by causing a window_underflow trap
+
+ mov %l0, %y
+ mov %l1, %psr ! Make sure that traps are disabled
+ ! for rett
+
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ dec %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ jmpl %l2, %g0 ! Restore old PC
+ rett %l3 ! Restore old nPC
+");
+
+/* Convert ch from a hex digit to an int */
+
+static int
+hex(ch)
+ unsigned char ch;
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch-'a'+10;
+ if (ch >= '0' && ch <= '9')
+ return ch-'0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch-'A'+10;
+ return -1;
+}
+
+/* scan for the sequence $<data>#<checksum> */
+
+static void
+getpacket(buffer)
+ char *buffer;
+{
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int i;
+ int count;
+ unsigned char ch;
+
+ do
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = (getDebugChar() & 0x7f)) != '$') ;
+
+ checksum = 0;
+ xmitcsum = -1;
+
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar() & 0x7f;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+
+ if (count >= BUFMAX)
+ continue;
+
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ xmitcsum = hex(getDebugChar() & 0x7f) << 4;
+ xmitcsum |= hex(getDebugChar() & 0x7f);
+#if 0
+ /* Humans shouldn't have to figure out checksums to type to it. */
+ putDebugChar ('+');
+ return;
+#endif
+ if (checksum != xmitcsum)
+ putDebugChar('-'); /* failed checksum */
+ else
+ {
+ putDebugChar('+'); /* successful transfer */
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar(buffer[0]);
+ putDebugChar(buffer[1]);
+ /* remove sequence chars from buffer */
+ count = strlen(buffer);
+ for (i=3; i <= count; i++)
+ buffer[i-3] = buffer[i];
+ }
+ }
+ }
+ }
+ while (checksum != xmitcsum);
+}
+
+/* send the packet in buffer. */
+
+static void
+putpacket(buffer)
+ unsigned char *buffer;
+{
+ unsigned char checksum;
+ int count;
+ unsigned char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch = buffer[count])
+ {
+ if (! putDebugChar(ch))
+ return;
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum & 0xf]);
+
+ }
+ while ((getDebugChar() & 0x7f) != '+');
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+static volatile int mem_err = 0;
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ * If MAY_FAULT is non-zero, then we will handle memory faults by returning
+ * a 0, else treat a fault like any other fault in the stub.
+ */
+
+static unsigned char *
+mem2hex(mem, buf, count, may_fault)
+ unsigned char *mem;
+ unsigned char *buf;
+ int count;
+ int may_fault;
+{
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ while (count-- > 0)
+ {
+ ch = *mem++;
+ if (mem_err)
+ return 0;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+
+ *buf = 0;
+
+ set_mem_fault_trap(0);
+
+ return buf;
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written */
+
+static char *
+hex2mem(buf, mem, count, may_fault)
+ unsigned char *buf;
+ unsigned char *mem;
+ int count;
+ int may_fault;
+{
+ int i;
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ for (i=0; i<count; i++)
+ {
+ ch = hex(*buf++) << 4;
+ ch |= hex(*buf++);
+ *mem++ = ch;
+ if (mem_err)
+ return 0;
+ }
+
+ set_mem_fault_trap(0);
+
+ return mem;
+}
+
+/* This table contains the mapping between SPARC hardware trap types, and
+ signals, which are primarily what GDB understands. It also indicates
+ which hardware traps we need to commandeer when initializing the stub. */
+
+static struct hard_trap_info
+{
+ unsigned char tt; /* Trap type code for SPARClite */
+ unsigned char signo; /* Signal that we map this trap into */
+} hard_trap_info[] = {
+ {1, SIGSEGV}, /* instruction access error */
+ {2, SIGILL}, /* privileged instruction */
+ {3, SIGILL}, /* illegal instruction */
+ {4, SIGEMT}, /* fp disabled */
+ {36, SIGEMT}, /* cp disabled */
+ {7, SIGBUS}, /* mem address not aligned */
+ {9, SIGSEGV}, /* data access exception */
+ {10, SIGEMT}, /* tag overflow */
+ {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
+ {0, 0} /* Must be last */
+};
+
+/* Set up exception handlers for tracing and breakpoints */
+
+void
+set_debug_traps()
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ exceptionHandler(ht->tt, trap_low);
+
+ /* In case GDB is started before us, ack any packets (presumably
+ "$?#xx") sitting there. */
+
+ putDebugChar ('+');
+
+ initialized = 1;
+}
+
+asm ("
+! Trap handler for memory errors. This just sets mem_err to be non-zero. It
+! assumes that %l1 is non-zero. This should be safe, as it is doubtful that
+! 0 would ever contain code that could mem fault. This routine will skip
+! past the faulting instruction after setting mem_err.
+
+ .text
+ .align 4
+
+_fltr_set_mem_err:
+ sethi %hi(_mem_err), %l0
+ st %l1, [%l0 + %lo(_mem_err)]
+ jmpl %l2, %g0
+ rett %l2+4
+");
+
+static void
+set_mem_fault_trap(enable)
+ int enable;
+{
+ extern void fltr_set_mem_err();
+ mem_err = 0;
+
+ if (enable)
+ exceptionHandler(9, fltr_set_mem_err);
+ else
+ exceptionHandler(9, trap_low);
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+
+static int
+computeSignal(tt)
+ int tt;
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ if (ht->tt == tt)
+ return ht->signo;
+
+ return SIGHUP; /* default for things we don't know about */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+
+static unsigned int
+hexToInt(char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue < 0)
+ break;
+
+ *intValue = (*intValue << 4) | hexValue;
+ numChars ++;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb. It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+
+extern void breakinst();
+
+static void
+handle_exception (registers)
+ unsigned long *registers;
+{
+ int tt; /* Trap type */
+ int sigval;
+ unsigned int addr;
+ int length;
+ char *ptr;
+ unsigned long *sp;
+
+/* First, we must force all of the windows to be spilled out */
+
+ asm(" save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+");
+
+ if (registers[PC] == (unsigned long)breakinst)
+ {
+ registers[PC] = registers[NPC];
+ registers[NPC] += 4;
+ }
+
+ sp = (unsigned long *)registers[SP];
+
+ tt = (registers[TBR] >> 4) & 0xff;
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal(tt);
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T';
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[FP >> 4];
+ *ptr++ = hexchars[FP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[SP >> 4];
+ *ptr++ = hexchars[SP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&sp, ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[NPC >> 4];
+ *ptr++ = hexchars[NPC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[O7 >> 4];
+ *ptr++ = hexchars[O7 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = 0;
+
+ putpacket(remcomOutBuffer);
+
+ while (1)
+ {
+ remcomOutBuffer[0] = 0;
+
+ getpacket(remcomInBuffer);
+ switch (remcomInBuffer[0])
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval & 0xf];
+ remcomOutBuffer[3] = 0;
+ break;
+
+ case 'd':
+ /* toggle debug flag */
+ break;
+
+ case 'g': /* return the value of the CPU registers */
+ {
+ ptr = remcomOutBuffer;
+ ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */
+ ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */
+ memset(ptr, '0', 32 * 8); /* Floating point */
+ mem2hex((char *)&registers[Y],
+ ptr + 32 * 4 * 2,
+ 8 * 4,
+ 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ }
+ break;
+
+ case 'G': /* set the value of the CPU registers - return OK */
+ {
+ unsigned long *newsp, psr;
+
+ psr = registers[PSR];
+
+ ptr = &remcomInBuffer[1];
+ hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
+ hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */
+ hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
+ 8 * 4, 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+
+ /* See if the stack pointer has moved. If so, then copy the saved
+ locals and ins to the new location. This keeps the window
+ overflow and underflow routines happy. */
+
+ newsp = (unsigned long *)registers[SP];
+ if (sp != newsp)
+ sp = memcpy(newsp, sp, 16 * 4);
+
+ /* Don't allow CWP to be modified. */
+
+ if (psr != registers[PSR])
+ registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
+ strcpy(remcomOutBuffer,"OK");
+ }
+ break;
+
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* Try to read %x,%x. */
+
+ ptr = &remcomInBuffer[1];
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length))
+ {
+ if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
+ break;
+
+ strcpy (remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer,"E01");
+ break;
+
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* Try to read '%x,%x:'. */
+
+ ptr = &remcomInBuffer[1];
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length)
+ && *ptr++ == ':')
+ {
+ if (hex2mem(ptr, (char *)addr, length, 1))
+ strcpy(remcomOutBuffer, "OK");
+ else
+ strcpy(remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer, "E02");
+ break;
+
+ case 'c': /* cAA..AA Continue at address AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr, &addr))
+ {
+ registers[PC] = addr;
+ registers[NPC] = addr + 4;
+ }
+
+/* Need to flush the instruction cache here, as we may have deposited a
+ breakpoint, and the icache probably has no way of knowing that a data ref to
+ some location may have changed something that is in the instruction cache.
+ */
+
+ flush_i_cache();
+ return;
+
+ /* kill the program */
+ case 'k' : /* do nothing */
+ break;
+#if 0
+ case 't': /* Test feature */
+ asm (" std %f30,[%sp]");
+ break;
+#endif
+ case 'r': /* Reset */
+ asm ("call 0
+ nop ");
+ break;
+
+#if 0
+Disabled until we can unscrew this properly
+
+ case 'b': /* bBB... Set baud rate to BB... */
+ {
+ int baudrate;
+ extern void set_timer_3();
+
+ ptr = &remcomInBuffer[1];
+ if (!hexToInt(&ptr, &baudrate))
+ {
+ strcpy(remcomOutBuffer,"B01");
+ break;
+ }
+
+ /* Convert baud rate to uart clock divider */
+ switch (baudrate)
+ {
+ case 38400:
+ baudrate = 16;
+ break;
+ case 19200:
+ baudrate = 33;
+ break;
+ case 9600:
+ baudrate = 65;
+ break;
+ default:
+ strcpy(remcomOutBuffer,"B02");
+ goto x1;
+ }
+
+ putpacket("OK"); /* Ack before changing speed */
+ set_timer_3(baudrate); /* Set it */
+ }
+x1: break;
+#endif
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint()
+{
+ if (!initialized)
+ return;
+
+ asm(" .globl _breakinst
+
+ _breakinst: ta 1
+ ");
+}
diff --git a/libgloss/sparc/sparc86x.ld b/libgloss/sparc/sparc86x.ld
new file mode 100644
index 0000000..e7cf27e
--- /dev/null
+++ b/libgloss/sparc/sparc86x.ld
@@ -0,0 +1,177 @@
+/*
+ *uncomment this if you want the linker to output srecords.
+OUTPUT_FORMAT(srec)
+ *
+ */
+ENTRY(_start)
+STARTUP(crt0.o)
+OUTPUT_ARCH(sparc)
+SEARCH_DIR(.)
+__DYNAMIC = 0;
+GROUP (-lc -lslite86x -lgcc)
+
+/*
+ * The memory map looks like this:
+ * +--------------------+ <- low memory
+ * | .text |
+ * | _stext |
+ * | _etext |
+ * | ctor list | the ctor and dtor lists are for
+ * | dtor list | C++ support
+ * | _end_text |
+ * +--------------------+
+ * | .data | initialized data goes here
+ * | _sdata |
+ * | _edata |
+ * +--------------------+
+ * | .bss |
+ * | __bss_start | start of bss, cleared by crt0
+ * | _end | start of heap, used by sbrk()
+ * +--------------------+
+ * | heap space |
+ * | _ENDHEAP |
+ * | stack space |
+ * | __stack | top of stack
+ * +--------------------+ <- high memory
+ */
+
+_STACK_SIZE = (16 * 1024);
+_RAM_SIZE = 2M;
+_RAM_START = 0x40010000;
+_RAM_END = _RAM_START + _RAM_SIZE;
+
+/*
+ * Base address of the on-CPU peripherals. This is for compatability
+ * with the simulator.
+ */
+
+_ERC32_MEC = 0x0;
+
+/*
+ * Setup the memory map of the MB86931-EB Board (ex931)
+ * stack grows down towards low memory.
+ */
+MEMORY
+{
+ ram (rwx) : ORIGIN = 0x40010000, LENGTH = 2M
+}
+
+__stack = _RAM_START + _RAM_SIZE - 4 * 16;
+__trap_stack = (_RAM_START + _RAM_SIZE - 4 * 16) - _STACK_SIZE;
+
+/*
+ * All the symbols that might be accessed from C code need to be
+ * listed twice, once with an additional underscore. aout format needs
+ * and extra underscore, whereas coff & elf doesn't. This is to work
+ * with both.
+ */
+/*
+ * Initalize some symbols to be zero so we can reference them in the
+ * crt0 without core dumping. These functions are all optional, but
+ * we do this so we can have our crt0 always use them if they exist.
+ * This is so BSPs work better when using the crt0 installed with gcc.
+ * We have to initalize them twice, so we cover a.out (which prepends
+ * an underscore) and coff object file formats.
+ */
+PROVIDE (hardware_init_hook = 0);
+PROVIDE (_hardware_init_hook = 0);
+PROVIDE (software_init_hook = 0);
+PROVIDE (_software_init_hook = 0);
+SECTIONS
+{
+ .text : {
+ stext = .;
+ _stext = .;
+ __EH_FRAME_BEGIN__ = .;
+
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+ LONG(0)
+ __CTOR_END__ = .;
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+ LONG(0)
+ __DTOR_END__ = .;
+
+ _etext = .;
+
+ *(.init)
+ *(.lit)
+ *(.rodata)
+ *(.shdata)
+ *(.eh_frame)
+ *(.gnu.linkonce.t*)
+ *(.gnu.linkonce.r*)
+ *(.gcc_except_table)
+ *(.fini)
+
+ } > ram
+ .shbss SIZEOF(.text) + ADDR(.text) : {
+ *(.shbss)
+ }
+ .talias : { } > ram
+ .data ALIGN(0x2000) : {
+ sdata = .;
+ _sdata = .;
+ *(.data)
+ edata = .;
+ _edata = .;
+ } > ram
+ .bss SIZEOF(.data) + ADDR(.data) : {
+ sbss = . ;
+ _sbss = . ;
+ __bss_start = ALIGN(0x8);
+ __bss_start = ALIGN(0x8);
+ *(.bss)
+ *(COMMON)
+ end = ALIGN(0x8);
+ _end = ALIGN(0x8);
+ __end = ALIGN(0x8);
+ ebss = .;
+ _ebss = .;
+ }
+ .mstack : { } > ram
+ .rstack : { } > ram
+ .stab 0 (NOLOAD) : {
+ [ .stab ]
+ }
+ .stabstr 0 (NOLOAD) :
+ {
+ [ .stabstr ]
+ }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/libgloss/sparc/sparcl-stub.c b/libgloss/sparc/sparcl-stub.c
new file mode 100644
index 0000000..634878b
--- /dev/null
+++ b/libgloss/sparc/sparcl-stub.c
@@ -0,0 +1,1005 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for SPARC by Stu Grossman, Cygnus Support.
+ * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware
+ * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support.
+ *
+ * This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
+ * baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <signal.h>
+#include "asm.h"
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+extern putDebugChar(); /* write a single character */
+extern getDebugChar(); /* read and return a single char */
+
+/* Pointer to hook for outbyte, set by stub's exception handler. */
+extern void (*__outbyte_hook)();
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 2048
+
+static int initialized = 0; /* !0 means we've been initialized */
+
+extern void breakinst();
+static void hw_breakpoint();
+static void set_mem_fault_trap();
+static void get_in_break_mode();
+
+static const char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 80
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
+ O0, O1, O2, O3, O4, O5, SP, O7,
+ L0, L1, L2, L3, L4, L5, L6, L7,
+ I0, I1, I2, I3, I4, I5, FP, I7,
+
+ F0, F1, F2, F3, F4, F5, F6, F7,
+ F8, F9, F10, F11, F12, F13, F14, F15,
+ F16, F17, F18, F19, F20, F21, F22, F23,
+ F24, F25, F26, F27, F28, F29, F30, F31,
+ Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR,
+ DIA1, DIA2, DDA1, DDA2, DDV1, DDV2, DCR, DSR };
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+extern void trap_low();
+
+asm("
+ .reserve trapstack, 1000 * 4, \"bss\", 8
+
+ .data
+ .align 4
+
+in_trap_handler:
+ .word 0
+
+ .text
+ .align 4
+
+! This function is called when any SPARC trap (except window overflow or
+! underflow) occurs. It makes sure that the invalid register window is still
+! available before jumping into C code. It will also restore the world if you
+! return from handle_exception.
+
+ .globl " STRINGSYM(trap_low) "
+" STRINGSYM(trap_low) ":
+ mov %psr, %l0
+ mov %wim, %l3
+
+ srl %l3, %l0, %l4 ! wim >> cwp
+ cmp %l4, 1
+ bne window_fine ! Branch if not in the invalid window
+ nop
+
+! Handle window overflow
+
+ mov %g1, %l4 ! Save g1, we use it to hold the wim
+ srl %l3, 1, %g1 ! Rotate wim right
+ tst %g1
+ bg good_wim ! Branch if new wim is non-zero
+ nop
+
+! At this point, we need to bring a 1 into the high order bit of the wim.
+! Since we don't want to make any assumptions about the number of register
+! windows, we figure it out dynamically so as to setup the wim correctly.
+
+ not %g1 ! Fill g1 with ones
+ mov %g1, %wim ! Fill the wim with ones
+ nop
+ nop
+ nop
+ mov %wim, %g1 ! Read back the wim
+ inc %g1 ! Now g1 has 1 just to left of wim
+ srl %g1, 1, %g1 ! Now put 1 at top of wim
+ mov %g0, %wim ! Clear wim so that subsequent save
+ nop ! won't trap
+ nop
+ nop
+
+good_wim:
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l4, %g1 ! Restore %g1
+
+window_fine:
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ tst %l5
+ bg recursive_trap
+ inc %l5
+
+ set trapstack+1000*4, %sp ! Switch to trap stack
+
+recursive_trap:
+ st %l5, [%lo(in_trap_handler) + %l4]
+ sub %sp,(16+1+6+1+80)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[72] local var
+
+ std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
+ std %g2, [%sp + (24 + 2) * 4]
+ std %g4, [%sp + (24 + 4) * 4]
+ std %g6, [%sp + (24 + 6) * 4]
+
+ std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
+ std %i2, [%sp + (24 + 10) * 4]
+ std %i4, [%sp + (24 + 12) * 4]
+ std %i6, [%sp + (24 + 14) * 4]
+ ! F0->F31 not implemented
+ mov %y, %l4
+ mov %tbr, %l5
+ st %l4, [%sp + (24 + 64) * 4] ! Y
+ st %l0, [%sp + (24 + 65) * 4] ! PSR
+ st %l3, [%sp + (24 + 66) * 4] ! WIM
+ st %l5, [%sp + (24 + 67) * 4] ! TBR
+ st %l1, [%sp + (24 + 68) * 4] ! PC
+ st %l2, [%sp + (24 + 69) * 4] ! NPC
+ ! CPSR and FPSR not impl
+ or %l0, 0xf20, %l4
+ mov %l4, %psr ! Turn on traps, disable interrupts
+ nop
+ nop
+ nop
+ call " STRINGSYM(get_in_break_mode) "
+ nop
+ nop
+ nop
+
+ sethi %hi(0xff00), %l5
+ or %l5, %lo(0xff00), %l5
+
+ lda [%l5]0x1, %l4
+ st %l4, [%sp + (24 + 72) * 4] ! DIA1, debug instr addr 1
+ add %l5, 4, %l5
+ lda [%l5]0x1, %l4
+ st %l4, [%sp + (24 + 73) * 4] ! DIA2, debug instr addr 2
+ add %l5, 4, %l5
+ lda [%l5]0x1, %l4
+ st %l4, [%sp + (24 + 74) * 4] ! DDA1, debug data addr 1
+ add %l5, 4, %l5
+ lda [%l5]0x1, %l4
+ st %l4, [%sp + (24 + 75) * 4] ! DDA2, debug data addr 2
+ add %l5, 4, %l5
+ lda [%l5]0x1, %l4
+ st %l4, [%sp + (24 + 76) * 4] ! DDV1, debug data val 1
+ add %l5, 4, %l5
+ lda [%l5]0x1, %l4
+ st %l4, [%sp + (24 + 77) * 4] ! DDV2, debug data val 2
+ add %l5, 4, %l5
+ lda [%l5]0x1, %l4
+ st %l4, [%sp + (24 + 78) * 4] ! DCR, debug control reg
+ add %l5, 4, %l5
+ lda [%l5]0x1, %l4
+ st %l4, [%sp + (24 + 79) * 4] ! DSR, debug status reg
+ nop
+ nop
+ or %l0, 0xf20, %l4
+ mov %l4, %psr ! Turn on traps, disable interrupts
+ nop
+ nop
+ nop
+ call " STRINGSYM(handle_exception) "
+ add %sp, 24 * 4, %o0 ! Pass address of registers
+
+! Reload all of the registers that aren't on the stack
+
+ ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+ ldd [%sp + (24 + 2) * 4], %g2
+ ldd [%sp + (24 + 4) * 4], %g4
+ ldd [%sp + (24 + 6) * 4], %g6
+
+ ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+ ldd [%sp + (24 + 10) * 4], %i2
+ ldd [%sp + (24 + 12) * 4], %i4
+ ldd [%sp + (24 + 14) * 4], %i6
+
+ sethi %hi(0xff00), %l2
+ or %l2, %lo(0xff00), %l2
+ ldd [%sp + (24 + 72) * 4], %l4 ! DIA1, debug instr addr 1
+ stda %l4, [%l2]0x1
+ nop
+ nop
+ nop
+ nop
+ ldd [%sp + (24 + 74) * 4], %l4 ! DDA1, debug data addr 1
+ add %l2, 8, %l2
+ stda %l4, [%l2]0x1
+ nop
+ nop
+ nop
+ nop
+ ldd [%sp + (24 + 76) * 4], %l4 ! DDV1, debug data value 1
+ add %l2, 8, %l2
+ stda %l4, [%l2]0x1
+ nop
+ nop
+ nop
+ nop
+ ld [%sp + (24 + 78) * 4], %l4 ! DCR, debug control reg
+ ld [%sp + (24 + 79) * 4], %l5 ! DSR, debug control reg
+ add %l2, 8, %l2
+ or %l4, 0x200, %l4
+ sta %l4, [%l2]0x1
+ add %l2, 4, %l2
+ sta %l5, [%l2]0x1
+ nop
+ nop
+ nop
+ nop
+
+ ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+ ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
+
+ restore ! Ensure that previous window is valid
+ save %g0, %g0, %g0 ! by causing a window_underflow trap
+
+ mov %l0, %y
+ mov %l1, %psr ! Make sure that traps are disabled
+ ! for rett
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ dec %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ jmpl %l2, %g0 ! Restore old PC
+ rett %l3 ! Restore old nPC
+");
+
+/* Convert ch from a hex digit to an int */
+
+static int
+hex(ch)
+ unsigned char ch;
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch-'a'+10;
+ if (ch >= '0' && ch <= '9')
+ return ch-'0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch-'A'+10;
+ return -1;
+}
+
+/* scan for the sequence $<data>#<checksum> */
+
+static void
+getpacket(buffer)
+ char *buffer;
+{
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int i;
+ int count;
+ unsigned char ch;
+
+ do
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = (getDebugChar() & 0x7f)) != '$') ;
+
+ checksum = 0;
+ xmitcsum = -1;
+
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar() & 0x7f;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+
+ if (count >= BUFMAX)
+ continue;
+
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ xmitcsum = hex(getDebugChar() & 0x7f) << 4;
+ xmitcsum |= hex(getDebugChar() & 0x7f);
+#if 0
+ /* Humans shouldn't have to figure out checksums to type to it. */
+ putDebugChar ('+');
+ return;
+#endif
+ if (checksum != xmitcsum)
+ putDebugChar('-'); /* failed checksum */
+ else
+ {
+ putDebugChar('+'); /* successful transfer */
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar(buffer[0]);
+ putDebugChar(buffer[1]);
+ /* remove sequence chars from buffer */
+ count = strlen(buffer);
+ for (i=3; i <= count; i++)
+ buffer[i-3] = buffer[i];
+ }
+ }
+ }
+ }
+ while (checksum != xmitcsum);
+}
+
+/* send the packet in buffer. */
+
+static void
+putpacket(buffer)
+ unsigned char *buffer;
+{
+ unsigned char checksum;
+ int count;
+ unsigned char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch = buffer[count])
+ {
+ if (! putDebugChar(ch))
+ return;
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum & 0xf]);
+
+ }
+ while ((getDebugChar() & 0x7f) != '+');
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+static volatile int mem_err = 0;
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ * If MAY_FAULT is non-zero, then we will handle memory faults by returning
+ * a 0, else treat a fault like any other fault in the stub.
+ */
+
+static unsigned char *
+mem2hex(mem, buf, count, may_fault)
+ unsigned char *mem;
+ unsigned char *buf;
+ int count;
+ int may_fault;
+{
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ while (count-- > 0)
+ {
+ ch = *mem++;
+ if (mem_err)
+ return 0;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+
+ *buf = 0;
+
+ set_mem_fault_trap(0);
+
+ return buf;
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written */
+
+static char *
+hex2mem(buf, mem, count, may_fault)
+ unsigned char *buf;
+ unsigned char *mem;
+ int count;
+ int may_fault;
+{
+ int i;
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ for (i=0; i<count; i++)
+ {
+ ch = hex(*buf++) << 4;
+ ch |= hex(*buf++);
+ *mem++ = ch;
+ if (mem_err)
+ return 0;
+ }
+
+ set_mem_fault_trap(0);
+
+ return mem;
+}
+
+/* This table contains the mapping between SPARC hardware trap types, and
+ signals, which are primarily what GDB understands. It also indicates
+ which hardware traps we need to commandeer when initializing the stub. */
+
+static struct hard_trap_info
+{
+ unsigned char tt; /* Trap type code for SPARClite */
+ unsigned char signo; /* Signal that we map this trap into */
+} hard_trap_info[] = {
+ {1, SIGSEGV}, /* instruction access error */
+ {2, SIGILL}, /* privileged instruction */
+ {3, SIGILL}, /* illegal instruction */
+ {4, SIGEMT}, /* fp disabled */
+ {36, SIGEMT}, /* cp disabled */
+ {7, SIGBUS}, /* mem address not aligned */
+ {9, SIGSEGV}, /* data access exception */
+ {10, SIGEMT}, /* tag overflow */
+ {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
+ {255, SIGTRAP}, /* hardware breakpoint */
+ {0, 0} /* Must be last */
+};
+
+/* Set up exception handlers for tracing and breakpoints */
+
+void
+set_debug_traps()
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ exceptionHandler(ht->tt, trap_low);
+
+ /* In case GDB is started before us, ack any packets (presumably
+ "$?#xx") sitting there. */
+
+ putDebugChar ('+');
+
+ initialized = 1;
+}
+
+asm ("
+! Trap handler for memory errors. This just sets mem_err to be non-zero. It
+! assumes that %l1 is non-zero. This should be safe, as it is doubtful that
+! 0 would ever contain code that could mem fault. This routine will skip
+! past the faulting instruction after setting mem_err.
+
+ .text
+ .align 4
+
+" STRINGSYM(fltr_set_mem_err) ":
+ sethi %hi(" STRINGSYM(mem_err) "), %l0
+ st %l1, [%l0 + %lo(" STRINGSYM(mem_err) ")]
+ jmpl %l2, %g0
+ rett %l2+4
+");
+
+static void
+set_mem_fault_trap(enable)
+ int enable;
+{
+ extern void fltr_set_mem_err();
+ mem_err = 0;
+
+ if (enable)
+ exceptionHandler(9, fltr_set_mem_err);
+ else
+ exceptionHandler(9, trap_low);
+}
+
+asm ("
+ .text
+ .align 4
+
+" STRINGSYM(dummy_hw_breakpoint) ":
+ jmpl %l2, %g0
+ rett %l2+4
+ nop
+ nop
+");
+
+static void
+set_hw_breakpoint_trap(enable)
+ int enable;
+{
+ extern void dummy_hw_breakpoint();
+
+ if (enable)
+ exceptionHandler(255, dummy_hw_breakpoint);
+ else
+ exceptionHandler(255, trap_low);
+}
+
+static void
+get_in_break_mode()
+{
+ set_hw_breakpoint_trap(1);
+
+ asm("
+ sethi %hi(0xff10), %l4
+ or %l4, %lo(0xff10), %l4
+ sta %g0, [%l4]0x1
+ nop
+ nop
+ nop
+ ");
+
+ set_hw_breakpoint_trap(0);
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+
+static int
+computeSignal(tt)
+ int tt;
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ if (ht->tt == tt)
+ return ht->signo;
+
+ return SIGHUP; /* default for things we don't know about */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+
+static int
+hexToInt(char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue < 0)
+ break;
+
+ *intValue = (*intValue << 4) | hexValue;
+ numChars ++;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/* Replacement for outbyte that sends a packet to GDB containing
+ the character to be output. */
+
+static void
+outbyte_stub (int c)
+{
+ static char buf[4];
+
+ buf[0] = 'O';
+ buf[1] = hexchars[(c >> 4) & 0xf];
+ buf[2] = hexchars[c % 16];
+ buf[3] = 0;
+ putpacket (buf);
+}
+
+
+/*
+ * This function does all command procesing for interfacing to gdb. It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+
+
+static void
+handle_exception (registers)
+ unsigned long *registers;
+{
+ int tt; /* Trap type */
+ int sigval;
+ int addr;
+ int length;
+ char *ptr;
+ unsigned long *sp;
+ unsigned long dsr;
+
+/* First, we must force all of the windows to be spilled out */
+
+ asm(" save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+");
+
+ if (registers[PC] == (unsigned long)breakinst)
+ {
+ registers[PC] = registers[NPC];
+ registers[NPC] += 4;
+ }
+ sp = (unsigned long *)registers[SP];
+
+ dsr = (unsigned long)registers[DSR];
+ if (dsr & 0x3c)
+ {
+ tt = 255;
+ }
+ else
+ {
+ tt = (registers[TBR] >> 4) & 0xff;
+ }
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal(tt);
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T';
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[FP >> 4];
+ *ptr++ = hexchars[FP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[SP >> 4];
+ *ptr++ = hexchars[SP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&sp, ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[NPC >> 4];
+ *ptr++ = hexchars[NPC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[O7 >> 4];
+ *ptr++ = hexchars[O7 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = 0;
+
+ putpacket(remcomOutBuffer);
+
+ __outbyte_hook = outbyte_stub;
+
+ while (1)
+ {
+ remcomOutBuffer[0] = 0;
+
+ getpacket(remcomInBuffer);
+ switch (remcomInBuffer[0])
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval & 0xf];
+ remcomOutBuffer[3] = 0;
+ break;
+
+ case 'd':
+ /* toggle debug flag */
+ break;
+
+ case 'g': /* return the value of the CPU registers */
+ {
+ ptr = remcomOutBuffer;
+ ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */
+ ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */
+ memset(ptr, '0', 32 * 8); /* Floating point */
+ ptr = mem2hex((char *)&registers[Y],
+ ptr + 32 * 4 * 2,
+ 8 * 4,
+ 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ mem2hex((char *)&registers[DIA1], ptr,
+ 8 * 4, 0); /* DIA1, DIA2, DDA1, DDA2, DDV1, DDV2, DCR, DSR */
+ }
+ break;
+
+ case 'G': /* set the value of the CPU registers - return OK */
+ {
+ unsigned long *newsp, psr;
+
+ psr = registers[PSR];
+
+ ptr = &remcomInBuffer[1];
+ hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
+ hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */
+ hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
+ 8 * 4, 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ hex2mem(ptr + 72 * 4 * 2, (char *)&registers[DIA1],
+ 8 * 4, 0); /* DIA1, DIA2, DDA1, DDA2, DDV1, DDV2, DCR, DSR */
+
+ /* See if the stack pointer has moved. If so, then copy the saved
+ locals and ins to the new location. This keeps the window
+ overflow and underflow routines happy. */
+
+ newsp = (unsigned long *)registers[SP];
+ if (sp != newsp)
+ sp = memcpy(newsp, sp, 16 * 4);
+
+ /* Don't allow CWP to be modified. */
+
+ if (psr != registers[PSR])
+ registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
+ strcpy(remcomOutBuffer,"OK");
+ }
+ break;
+
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* Try to read %x,%x. */
+
+ ptr = &remcomInBuffer[1];
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length))
+ {
+ if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
+ break;
+
+ strcpy (remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer,"E01");
+ break;
+
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* Try to read '%x,%x:'. */
+
+ ptr = &remcomInBuffer[1];
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length)
+ && *ptr++ == ':')
+ {
+ if (hex2mem(ptr, (char *)addr, length, 1))
+ strcpy(remcomOutBuffer, "OK");
+ else
+ strcpy(remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer, "E02");
+ break;
+
+ case 'c': /* cAA..AA Continue at address AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr, &addr))
+ {
+ registers[PC] = addr;
+ registers[NPC] = addr + 4;
+ }
+
+/* Need to flush the instruction cache here, as we may have deposited a
+ breakpoint, and the icache probably has no way of knowing that a data ref to
+ some location may have changed something that is in the instruction cache.
+ */
+
+ flush_i_cache();
+ return;
+
+ /* kill the program */
+ case 'k' : /* do nothing */
+ break;
+#if 0
+ case 't': /* Test feature */
+ asm (" std %f30,[%sp]");
+ break;
+#endif
+ case 'r': /* Reset */
+ asm ("call 0
+ nop ");
+ break;
+
+#if 0
+Disabled until we can unscrew this properly
+
+ case 'b': /* bBB... Set baud rate to BB... */
+ {
+ int baudrate;
+ extern void set_timer_3();
+
+ ptr = &remcomInBuffer[1];
+ if (!hexToInt(&ptr, &baudrate))
+ {
+ strcpy(remcomOutBuffer,"B01");
+ break;
+ }
+
+ /* Convert baud rate to uart clock divider */
+ switch (baudrate)
+ {
+ case 38400:
+ baudrate = 16;
+ break;
+ case 19200:
+ baudrate = 33;
+ break;
+ case 9600:
+ baudrate = 65;
+ break;
+ default:
+ strcpy(remcomOutBuffer,"B02");
+ goto x1;
+ }
+
+ putpacket("OK"); /* Ack before changing speed */
+ set_timer_3(baudrate); /* Set it */
+ }
+x1: break;
+#endif
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint()
+{
+ if (!initialized)
+ return;
+
+ asm(" .globl " STRINGSYM(breakinst) "
+
+ " STRINGSYM(breakinst) ": ta 1
+ ");
+}
+
+static void
+hw_breakpoint()
+{
+ asm("
+ ta 127
+ ");
+}
diff --git a/libgloss/sparc/sparclet-stub.c b/libgloss/sparc/sparclet-stub.c
new file mode 100644
index 0000000..a462128
--- /dev/null
+++ b/libgloss/sparc/sparclet-stub.c
@@ -0,0 +1,1233 @@
+/****************************************************************************
+
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ HP offers the following for use in the public domain. HP makes no
+ warranty with regard to the software or it's performance and the
+ user accepts the software "AS IS" with all faults.
+
+ HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
+ TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+****************************************************************************/
+
+/****************************************************************************
+ * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ * Module name: remcom.c $
+ * Revision: 1.34 $
+ * Date: 91/03/09 12:29:49 $
+ * Contributor: Lake Stevens Instrument Division$
+ *
+ * Description: low level support for gdb debugger. $
+ *
+ * Considerations: only works on target hardware $
+ *
+ * Written by: Glenn Engel $
+ * ModuleState: Experimental $
+ *
+ * NOTES: See Below $
+ *
+ * Modified for SPARC by Stu Grossman, Cygnus Support.
+ * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware
+ * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support.
+ *
+ * This code has been extensively tested on the Fujitsu SPARClite demo board.
+ *
+ * To enable debugger support, two things need to happen. One, a
+ * call to set_debug_traps() is necessary in order to allow any breakpoints
+ * or error conditions to be properly intercepted and reported to gdb.
+ * Two, a breakpoint needs to be generated to begin communication. This
+ * is most easily accomplished by a call to breakpoint(). Breakpoint()
+ * simulates a breakpoint by executing a trap #1.
+ *
+ *************
+ *
+ * The following gdb commands are supported:
+ *
+ * command function Return value
+ *
+ * g return the value of the CPU registers hex data or ENN
+ * G set the value of the CPU registers OK or ENN
+ * P set the value of a single CPU register OK or P01 (???)
+ *
+ * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
+ * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
+ *
+ * c Resume at current address SNN ( signal NN)
+ * cAA..AA Continue at address AA..AA SNN
+ *
+ * s Step one instruction SNN
+ * sAA..AA Step one instruction from AA..AA SNN
+ *
+ * k kill
+ *
+ * ? What was the last sigval ? SNN (signal NN)
+ *
+ * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
+ * baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum. A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer. '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host: Reply:
+ * $m0,10#2a +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+#include <string.h>
+#include <signal.h>
+
+/************************************************************************
+ *
+ * external low-level support routines
+ */
+
+extern putDebugChar(); /* write a single character */
+extern getDebugChar(); /* read and return a single char */
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+#define BUFMAX 2048
+
+static int initialized = 0; /* !0 means we've been initialized */
+static int remote_debug = 0; /* turn on verbose debugging */
+
+extern void breakinst();
+void _cprint();
+static void hw_breakpoint();
+static void set_mem_fault_trap();
+static void get_in_break_mode();
+static unsigned char *mem2hex();
+
+static const char hexchars[]="0123456789abcdef";
+
+#define NUMREGS 121
+
+static unsigned long saved_stack_pointer;
+
+/* Number of bytes of registers. */
+#define NUMREGBYTES (NUMREGS * 4)
+enum regnames { G0, G1, G2, G3, G4, G5, G6, G7,
+ O0, O1, O2, O3, O4, O5, SP, O7,
+ L0, L1, L2, L3, L4, L5, L6, L7,
+ I0, I1, I2, I3, I4, I5, FP, I7,
+
+ F0, F1, F2, F3, F4, F5, F6, F7,
+ F8, F9, F10, F11, F12, F13, F14, F15,
+ F16, F17, F18, F19, F20, F21, F22, F23,
+ F24, F25, F26, F27, F28, F29, F30, F31,
+
+ Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR,
+ CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR, UNUSED1,
+
+ ASR1, ASR15, ASR17, ASR18, ASR19, ASR20, ASR21, ASR22,
+ /* the following not actually implemented */
+ AWR0, AWR1, AWR2, AWR3, AWR4, AWR5, AWR6, AWR7,
+ AWR8, AWR9, AWR10, AWR11, AWR12, AWR13, AWR14, AWR15,
+ AWR16, AWR17, AWR18, AWR19, AWR20, AWR21, AWR22, AWR23,
+ AWR24, AWR25, AWR26, AWR27, AWR28, AWR29, AWR30, AWR31,
+ APSR
+};
+
+/*************************** ASSEMBLY CODE MACROS *************************/
+/* */
+
+extern void trap_low();
+
+asm("
+ .reserve trapstack, 1000 * 4, \"bss\", 8
+
+ .data
+ .align 4
+
+in_trap_handler:
+ .word 0
+
+ .text
+ .align 4
+
+! This function is called when any SPARC trap (except window overflow or
+! underflow) occurs. It makes sure that the invalid register window is still
+! available before jumping into C code. It will also restore the world if you
+! return from handle_exception.
+!
+! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly.
+
+ .globl _trap_low
+_trap_low:
+ mov %psr, %l0
+ mov %wim, %l3
+
+ srl %l3, %l0, %l4 ! wim >> cwp
+ and %l4, 0xff, %l4 ! Mask off windows 28, 29
+ cmp %l4, 1
+ bne window_fine ! Branch if not in the invalid window
+ nop
+
+! Handle window overflow
+
+ mov %g1, %l4 ! Save g1, we use it to hold the wim
+ srl %l3, 1, %g1 ! Rotate wim right
+ and %g1, 0xff, %g1 ! Mask off windows 28, 29
+ tst %g1
+ bg good_wim ! Branch if new wim is non-zero
+ nop
+
+! At this point, we need to bring a 1 into the high order bit of the wim.
+! Since we don't want to make any assumptions about the number of register
+! windows, we figure it out dynamically so as to setup the wim correctly.
+
+ ! The normal way doesn't work on the sparclet as register windows
+ ! 28 and 29 are special purpose windows.
+ !not %g1 ! Fill g1 with ones
+ !mov %g1, %wim ! Fill the wim with ones
+ !nop
+ !nop
+ !nop
+ !mov %wim, %g1 ! Read back the wim
+ !inc %g1 ! Now g1 has 1 just to left of wim
+ !srl %g1, 1, %g1 ! Now put 1 at top of wim
+
+ mov 0x80, %g1 ! Hack for sparclet
+
+ ! This doesn't work on the sparclet.
+ !mov %g0, %wim ! Clear wim so that subsequent save
+ ! won't trap
+ andn %l3, 0xff, %l5 ! Clear wim but not windows 28, 29
+ mov %l5, %wim
+ nop
+ nop
+ nop
+
+good_wim:
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l4, %g1 ! Restore %g1
+
+window_fine:
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ tst %l5
+ bg recursive_trap
+ inc %l5
+
+ set trapstack+1000*4, %sp ! Switch to trap stack
+
+recursive_trap:
+ st %l5, [%lo(in_trap_handler) + %l4]
+ sub %sp,(16+1+6+1+88)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[121]
+
+ std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
+ std %g2, [%sp + (24 + 2) * 4]
+ std %g4, [%sp + (24 + 4) * 4]
+ std %g6, [%sp + (24 + 6) * 4]
+
+ std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
+ std %i2, [%sp + (24 + 10) * 4]
+ std %i4, [%sp + (24 + 12) * 4]
+ std %i6, [%sp + (24 + 14) * 4]
+
+ ! FP regs (sparclet doesn't have fpu)
+
+ mov %y, %l4
+ mov %tbr, %l5
+ st %l4, [%sp + (24 + 64) * 4] ! Y
+ st %l0, [%sp + (24 + 65) * 4] ! PSR
+ st %l3, [%sp + (24 + 66) * 4] ! WIM
+ st %l5, [%sp + (24 + 67) * 4] ! TBR
+ st %l1, [%sp + (24 + 68) * 4] ! PC
+ st %l2, [%sp + (24 + 69) * 4] ! NPC
+ ! CPSR and FPSR not impl
+ or %l0, 0xf20, %l4
+ mov %l4, %psr ! Turn on traps, disable interrupts
+ nop
+ nop
+ nop
+
+! Save coprocessor state.
+! See SK/demo/hdlc_demo/ldc_swap_context.S.
+
+ mov %psr, %l0
+ sethi %hi(0x2000), %l5 ! EC bit in PSR
+ or %l5, %l0, %l5
+ mov %l5, %psr ! enable coprocessor
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+ crdcxt %ccsr, %l1 ! capture CCSR
+ mov 0x6, %l2
+ cwrcxt %l2, %ccsr ! set CCP state machine for CCFR
+ crdcxt %ccfr, %l2 ! capture CCOR
+ cwrcxt %l2, %ccfr ! tickle CCFR
+ crdcxt %ccfr, %l3 ! capture CCOBR
+ cwrcxt %l3, %ccfr ! tickle CCFR
+ crdcxt %ccfr, %l4 ! capture CCIBR
+ cwrcxt %l4, %ccfr ! tickle CCFR
+ crdcxt %ccfr, %l5 ! capture CCIR
+ cwrcxt %l5, %ccfr ! tickle CCFR
+ crdcxt %ccpr, %l6 ! capture CCPR
+ crdcxt %cccrcr, %l7 ! capture CCCRCR
+ st %l1, [%sp + (24 + 72) * 4] ! save CCSR
+ st %l2, [%sp + (24 + 75) * 4] ! save CCOR
+ st %l3, [%sp + (24 + 76) * 4] ! save CCOBR
+ st %l4, [%sp + (24 + 77) * 4] ! save CCIBR
+ st %l5, [%sp + (24 + 78) * 4] ! save CCIR
+ st %l6, [%sp + (24 + 73) * 4] ! save CCPR
+ st %l7, [%sp + (24 + 74) * 4] ! save CCCRCR
+ mov %l0, %psr ! restore original PSR
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+! End of saving coprocessor state.
+! Save asr regs
+
+! Part of this is silly -- we should not display ASR15 or ASR19 at all.
+
+ sethi %hi(0x01000000), %l6
+ st %l6, [%sp + (24 + 81) * 4] ! ASR15 == NOP
+ sethi %hi(0xdeadc0de), %l6
+ or %l6, %lo(0xdeadc0de), %l6
+ st %l6, [%sp + (24 + 84) * 4] ! ASR19 == DEADC0DE
+
+ rd %asr1, %l4
+ st %l4, [%sp + (24 + 80) * 4]
+! rd %asr15, %l4 ! must not read ASR15
+! st %l4, [%sp + (24 + 81) * 4] ! (illegal instr trap)
+ rd %asr17, %l4
+ st %l4, [%sp + (24 + 82) * 4]
+ rd %asr18, %l4
+ st %l4, [%sp + (24 + 83) * 4]
+! rd %asr19, %l4 ! must not read asr19
+! st %l4, [%sp + (24 + 84) * 4] ! (halts the CPU)
+ rd %asr20, %l4
+ st %l4, [%sp + (24 + 85) * 4]
+ rd %asr21, %l4
+ st %l4, [%sp + (24 + 86) * 4]
+ rd %asr22, %l4
+ st %l4, [%sp + (24 + 87) * 4]
+
+! End of saving asr regs
+
+ call _handle_exception
+ add %sp, 24 * 4, %o0 ! Pass address of registers
+
+! Reload all of the registers that aren't on the stack
+
+ ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+ ldd [%sp + (24 + 2) * 4], %g2
+ ldd [%sp + (24 + 4) * 4], %g4
+ ldd [%sp + (24 + 6) * 4], %g6
+
+ ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+ ldd [%sp + (24 + 10) * 4], %i2
+ ldd [%sp + (24 + 12) * 4], %i4
+ ldd [%sp + (24 + 14) * 4], %i6
+
+ ! FP regs (sparclet doesn't have fpu)
+
+! Update the coprocessor registers.
+! See SK/demo/hdlc_demo/ldc_swap_context.S.
+
+ mov %psr, %l0
+ sethi %hi(0x2000), %l5 ! EC bit in PSR
+ or %l5, %l0, %l5
+ mov %l5, %psr ! enable coprocessor
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+ mov 0x6, %l2
+ cwrcxt %l2, %ccsr ! set CCP state machine for CCFR
+
+ ld [%sp + (24 + 72) * 4], %l1 ! saved CCSR
+ ld [%sp + (24 + 75) * 4], %l2 ! saved CCOR
+ ld [%sp + (24 + 76) * 4], %l3 ! saved CCOBR
+ ld [%sp + (24 + 77) * 4], %l4 ! saved CCIBR
+ ld [%sp + (24 + 78) * 4], %l5 ! saved CCIR
+ ld [%sp + (24 + 73) * 4], %l6 ! saved CCPR
+ ld [%sp + (24 + 74) * 4], %l7 ! saved CCCRCR
+
+ cwrcxt %l2, %ccfr ! restore CCOR
+ cwrcxt %l3, %ccfr ! restore CCOBR
+ cwrcxt %l4, %ccfr ! restore CCIBR
+ cwrcxt %l5, %ccfr ! restore CCIR
+ cwrcxt %l6, %ccpr ! restore CCPR
+ cwrcxt %l7, %cccrcr ! restore CCCRCR
+ cwrcxt %l1, %ccsr ! restore CCSR
+
+ mov %l0, %psr ! restore PSR
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+! End of coprocessor handling stuff.
+! Update asr regs
+
+ ld [%sp + (24 + 80) * 4], %l4
+ wr %l4, %asr1
+! ld [%sp + (24 + 81) * 4], %l4 ! can't write asr15
+! wr %l4, %asr15
+ ld [%sp + (24 + 82) * 4], %l4
+ wr %l4, %asr17
+ ld [%sp + (24 + 83) * 4], %l4
+ wr %l4, %asr18
+! ld [%sp + (24 + 84) * 4], %l4 ! can't write asr19
+! wr %l4, %asr19
+! ld [%sp + (24 + 85) * 4], %l4 ! can't write asr20
+! wr %l4, %asr20
+! ld [%sp + (24 + 86) * 4], %l4 ! can't write asr21
+! wr %l4, %asr21
+ ld [%sp + (24 + 87) * 4], %l4
+ wr %l4, %asr22
+
+! End of restoring asr regs
+
+
+ ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+ ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
+
+ restore ! Ensure that previous window is valid
+ save %g0, %g0, %g0 ! by causing a window_underflow trap
+
+ mov %l0, %y
+ mov %l1, %psr ! Make sure that traps are disabled
+ ! for rett
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ dec %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ jmpl %l2, %g0 ! Restore old PC
+ rett %l3 ! Restore old nPC
+");
+
+/* Convert ch from a hex digit to an int */
+
+static int
+hex(ch)
+ unsigned char ch;
+{
+ if (ch >= 'a' && ch <= 'f')
+ return ch-'a'+10;
+ if (ch >= '0' && ch <= '9')
+ return ch-'0';
+ if (ch >= 'A' && ch <= 'F')
+ return ch-'A'+10;
+ return -1;
+}
+
+/* scan for the sequence $<data>#<checksum> */
+
+static void
+getpacket(buffer)
+ char *buffer;
+{
+ unsigned char checksum;
+ unsigned char xmitcsum;
+ int i;
+ int count;
+ unsigned char ch;
+
+ do
+ {
+ /* wait around for the start character, ignore all other characters */
+ while ((ch = (getDebugChar() & 0x7f)) != '$')
+ ;
+
+ checksum = 0;
+ xmitcsum = -1;
+
+ count = 0;
+
+ /* now, read until a # or end of buffer is found */
+ while (count < BUFMAX)
+ {
+ ch = getDebugChar() & 0x7f;
+ if (ch == '#')
+ break;
+ checksum = checksum + ch;
+ buffer[count] = ch;
+ count = count + 1;
+ }
+
+ if (count >= BUFMAX)
+ continue;
+
+ buffer[count] = 0;
+
+ if (ch == '#')
+ {
+ xmitcsum = hex(ch = getDebugChar() & 0x7f) << 4;
+ xmitcsum |= hex(ch = getDebugChar() & 0x7f);
+
+ if (checksum != xmitcsum)
+ putDebugChar('-'); /* failed checksum */
+ else
+ {
+ putDebugChar('+'); /* successful transfer */
+ /* if a sequence char is present, reply the sequence ID */
+ if (buffer[2] == ':')
+ {
+ putDebugChar(buffer[0]);
+ putDebugChar(buffer[1]);
+ /* remove sequence chars from buffer */
+ count = strlen(buffer);
+ for (i=3; i <= count; i++)
+ buffer[i-3] = buffer[i];
+ }
+ }
+ }
+ }
+ while (checksum != xmitcsum);
+}
+
+/* send the packet in buffer. */
+
+static void
+putpacket(buffer)
+ unsigned char *buffer;
+{
+ unsigned char checksum;
+ int count;
+ unsigned char ch;
+
+ /* $<packet info>#<checksum>. */
+ do
+ {
+ putDebugChar('$');
+ checksum = 0;
+ count = 0;
+
+ while (ch = buffer[count])
+ {
+ if (! putDebugChar(ch))
+ return;
+ checksum += ch;
+ count += 1;
+ }
+
+ putDebugChar('#');
+ putDebugChar(hexchars[checksum >> 4]);
+ putDebugChar(hexchars[checksum & 0xf]);
+
+ }
+ while ((getDebugChar() & 0x7f) != '+');
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+ error. */
+static volatile int mem_err = 0;
+
+/* Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null), in case of mem fault,
+ * return 0.
+ * If MAY_FAULT is non-zero, then we will handle memory faults by returning
+ * a 0, else treat a fault like any other fault in the stub.
+ */
+
+static unsigned char *
+mem2hex(mem, buf, count, may_fault)
+ unsigned char *mem;
+ unsigned char *buf;
+ int count;
+ int may_fault;
+{
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ while (count-- > 0)
+ {
+ ch = *mem++;
+ if (mem_err)
+ return 0;
+ *buf++ = hexchars[ch >> 4];
+ *buf++ = hexchars[ch & 0xf];
+ }
+
+ *buf = 0;
+
+ set_mem_fault_trap(0);
+
+ return buf;
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem
+ * return a pointer to the character AFTER the last byte written */
+
+static char *
+hex2mem(buf, mem, count, may_fault)
+ unsigned char *buf;
+ unsigned char *mem;
+ int count;
+ int may_fault;
+{
+ int i;
+ unsigned char ch;
+
+ set_mem_fault_trap(may_fault);
+
+ for (i=0; i<count; i++)
+ {
+ ch = hex(*buf++) << 4;
+ ch |= hex(*buf++);
+ *mem++ = ch;
+ if (mem_err)
+ return 0;
+ }
+
+ set_mem_fault_trap(0);
+
+ return mem;
+}
+
+/* This table contains the mapping between SPARC hardware trap types, and
+ signals, which are primarily what GDB understands. It also indicates
+ which hardware traps we need to commandeer when initializing the stub. */
+
+static struct hard_trap_info
+{
+ unsigned char tt; /* Trap type code for SPARClite */
+ unsigned char signo; /* Signal that we map this trap into */
+} hard_trap_info[] = {
+ {1, SIGSEGV}, /* instruction access exception */
+ {0x3b, SIGSEGV}, /* instruction access error */
+ {2, SIGILL}, /* illegal instruction */
+ {3, SIGILL}, /* privileged instruction */
+ {4, SIGEMT}, /* fp disabled */
+ {0x24, SIGEMT}, /* cp disabled */
+ {7, SIGBUS}, /* mem address not aligned */
+ {0x29, SIGSEGV}, /* data access exception */
+ {10, SIGEMT}, /* tag overflow */
+ {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
+ {0, 0} /* Must be last */
+};
+
+/* Set up exception handlers for tracing and breakpoints */
+
+void
+set_debug_traps()
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ exceptionHandler(ht->tt, trap_low);
+
+ /* In case GDB is started before us, ack any packets (presumably
+ "$?#xx") sitting there. */
+ putDebugChar ('+');
+
+ initialized = 1;
+}
+
+asm ("
+! Trap handler for memory errors. This just sets mem_err to be non-zero. It
+! assumes that %l1 is non-zero. This should be safe, as it is doubtful that
+! 0 would ever contain code that could mem fault. This routine will skip
+! past the faulting instruction after setting mem_err.
+
+ .text
+ .align 4
+
+_fltr_set_mem_err:
+ sethi %hi(_mem_err), %l0
+ st %l1, [%l0 + %lo(_mem_err)]
+ jmpl %l2, %g0
+ rett %l2+4
+");
+
+static void
+set_mem_fault_trap(enable)
+ int enable;
+{
+ extern void fltr_set_mem_err();
+ mem_err = 0;
+
+ if (enable)
+ exceptionHandler(0x29, fltr_set_mem_err);
+ else
+ exceptionHandler(0x29, trap_low);
+}
+
+asm ("
+ .text
+ .align 4
+
+_dummy_hw_breakpoint:
+ jmpl %l2, %g0
+ rett %l2+4
+ nop
+ nop
+");
+
+static void
+set_hw_breakpoint_trap(enable)
+ int enable;
+{
+ extern void dummy_hw_breakpoint();
+
+ if (enable)
+ exceptionHandler(255, dummy_hw_breakpoint);
+ else
+ exceptionHandler(255, trap_low);
+}
+
+static void
+get_in_break_mode()
+{
+#if 0
+ int x;
+ mesg("get_in_break_mode, sp = ");
+ phex(&x);
+#endif
+ set_hw_breakpoint_trap(1);
+
+ asm("
+ sethi %hi(0xff10), %l4
+ or %l4, %lo(0xff10), %l4
+ sta %g0, [%l4]0x1
+ nop
+ nop
+ nop
+ ");
+
+ set_hw_breakpoint_trap(0);
+}
+
+/* Convert the SPARC hardware trap type code to a unix signal number. */
+
+static int
+computeSignal(tt)
+ int tt;
+{
+ struct hard_trap_info *ht;
+
+ for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+ if (ht->tt == tt)
+ return ht->signo;
+
+ return SIGHUP; /* default for things we don't know about */
+}
+
+/*
+ * While we find nice hex chars, build an int.
+ * Return number of chars processed.
+ */
+
+static int
+hexToInt(char **ptr, int *intValue)
+{
+ int numChars = 0;
+ int hexValue;
+
+ *intValue = 0;
+
+ while (**ptr)
+ {
+ hexValue = hex(**ptr);
+ if (hexValue < 0)
+ break;
+
+ *intValue = (*intValue << 4) | hexValue;
+ numChars ++;
+
+ (*ptr)++;
+ }
+
+ return (numChars);
+}
+
+/*
+ * This function does all command procesing for interfacing to gdb. It
+ * returns 1 if you should skip the instruction at the trap address, 0
+ * otherwise.
+ */
+
+static void
+handle_exception (registers)
+ unsigned long *registers;
+{
+ int tt; /* Trap type */
+ int sigval;
+ int addr;
+ int length;
+ char *ptr;
+ unsigned long *sp;
+ unsigned long dsr;
+
+/* First, we must force all of the windows to be spilled out */
+
+ asm("
+ ! Ugh. sparclet has broken save
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ !save %sp, -64, %sp
+ save
+ add %fp,-64,%sp
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+");
+
+ if (registers[PC] == (unsigned long)breakinst)
+ {
+ registers[PC] = registers[NPC];
+ registers[NPC] += 4;
+ }
+ sp = (unsigned long *)registers[SP];
+
+ tt = (registers[TBR] >> 4) & 0xff;
+
+ /* reply to host that an exception has occurred */
+ sigval = computeSignal(tt);
+ ptr = remcomOutBuffer;
+
+ *ptr++ = 'T';
+ *ptr++ = hexchars[sigval >> 4];
+ *ptr++ = hexchars[sigval & 0xf];
+
+ *ptr++ = hexchars[PC >> 4];
+ *ptr++ = hexchars[PC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[PC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[FP >> 4];
+ *ptr++ = hexchars[FP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[SP >> 4];
+ *ptr++ = hexchars[SP & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&sp, ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[NPC >> 4];
+ *ptr++ = hexchars[NPC & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[NPC], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = hexchars[O7 >> 4];
+ *ptr++ = hexchars[O7 & 0xf];
+ *ptr++ = ':';
+ ptr = mem2hex((char *)&registers[O7], ptr, 4, 0);
+ *ptr++ = ';';
+
+ *ptr++ = 0;
+
+ putpacket(remcomOutBuffer);
+
+ while (1)
+ {
+ remcomOutBuffer[0] = 0;
+
+ getpacket(remcomInBuffer);
+ switch (remcomInBuffer[0])
+ {
+ case '?':
+ remcomOutBuffer[0] = 'S';
+ remcomOutBuffer[1] = hexchars[sigval >> 4];
+ remcomOutBuffer[2] = hexchars[sigval & 0xf];
+ remcomOutBuffer[3] = 0;
+ break;
+
+ case 'd':
+ remote_debug = !(remote_debug); /* toggle debug flag */
+ break;
+
+ case 'g': /* return the value of the CPU registers */
+ {
+ ptr = remcomOutBuffer;
+ ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */
+ ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */
+ memset(ptr, '0', 32 * 8); /* Floating point */
+ ptr = mem2hex((char *)&registers[Y],
+ ptr + 32 * 4 * 2,
+ 8 * 4,
+ 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
+ ptr = mem2hex((char *)&registers[CCSR],
+ ptr,
+ 8 * 4,
+ 0); /* CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR */
+ ptr = mem2hex((char *)&registers[ASR1],
+ ptr,
+ 8 * 4,
+ 0); /* ASR1,ASR15,ASR17,ASR18,ASR19,ASR20,ASR21,ASR22 */
+#if 0 /* not implemented */
+ ptr = mem2hex((char *) &registers[AWR0],
+ ptr,
+ 32 * 4,
+ 0); /* Alternate Window Registers */
+#endif
+ }
+ break;
+
+ case 'G': /* set value of all the CPU registers - return OK */
+ case 'P': /* set value of one CPU register - return OK */
+ {
+ unsigned long *newsp, psr;
+
+ psr = registers[PSR];
+
+ ptr = &remcomInBuffer[1];
+
+ if (remcomInBuffer[0] == 'P') /* do a single register */
+ {
+ int regno;
+
+ if (hexToInt (&ptr, &regno)
+ && *ptr++ == '=')
+ if (regno >= L0 && regno <= I7)
+ hex2mem (ptr, sp + regno - L0, 4, 0);
+ else
+ hex2mem (ptr, (char *)&registers[regno], 4, 0);
+ else
+ {
+ strcpy (remcomOutBuffer, "P01");
+ break;
+ }
+ }
+ else
+ {
+ hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */
+ hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */
+ hex2mem(ptr + 64 * 4 * 2, (char *)&registers[Y],
+ 8 * 4, 0); /* Y,PSR,WIM,TBR,PC,NPC,FPSR,CPSR */
+ hex2mem(ptr + 72 * 4 * 2, (char *)&registers[CCSR],
+ 8 * 4, 0); /* CCSR,CCPR,CCCRCR,CCOR,CCOBR,CCIBR,CCIR */
+ hex2mem(ptr + 80 * 4 * 2, (char *)&registers[ASR1],
+ 8 * 4, 0); /* ASR1 ... ASR22 */
+#if 0 /* not implemented */
+ hex2mem(ptr + 88 * 4 * 2, (char *)&registers[AWR0],
+ 8 * 4, 0); /* Alternate Window Registers */
+#endif
+ }
+ /* See if the stack pointer has moved. If so, then copy the saved
+ locals and ins to the new location. This keeps the window
+ overflow and underflow routines happy. */
+
+ newsp = (unsigned long *)registers[SP];
+ if (sp != newsp)
+ sp = memcpy(newsp, sp, 16 * 4);
+
+ /* Don't allow CWP to be modified. */
+
+ if (psr != registers[PSR])
+ registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
+
+ strcpy(remcomOutBuffer,"OK");
+ }
+ break;
+
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ /* Try to read %x,%x. */
+
+ ptr = &remcomInBuffer[1];
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length))
+ {
+ if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
+ break;
+
+ strcpy (remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer,"E01");
+ break;
+
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ /* Try to read '%x,%x:'. */
+
+ ptr = &remcomInBuffer[1];
+
+ if (hexToInt(&ptr, &addr)
+ && *ptr++ == ','
+ && hexToInt(&ptr, &length)
+ && *ptr++ == ':')
+ {
+ if (hex2mem(ptr, (char *)addr, length, 1))
+ strcpy(remcomOutBuffer, "OK");
+ else
+ strcpy(remcomOutBuffer, "E03");
+ }
+ else
+ strcpy(remcomOutBuffer, "E02");
+ break;
+
+ case 'c': /* cAA..AA Continue at address AA..AA(optional) */
+ /* try to read optional parameter, pc unchanged if no parm */
+
+ ptr = &remcomInBuffer[1];
+ if (hexToInt(&ptr, &addr))
+ {
+ registers[PC] = addr;
+ registers[NPC] = addr + 4;
+ }
+
+/* Need to flush the instruction cache here, as we may have deposited a
+ breakpoint, and the icache probably has no way of knowing that a data ref to
+ some location may have changed something that is in the instruction cache.
+ */
+
+ flush_i_cache();
+ return;
+
+ /* kill the program */
+ case 'k' : /* do nothing */
+ break;
+#if 0
+ case 't': /* Test feature */
+ asm (" std %f30,[%sp]");
+ break;
+#endif
+ case 'r': /* Reset */
+ asm ("call 0
+ nop ");
+ break;
+
+#if 0
+Disabled until we can unscrew this properly
+
+ case 'b': /* bBB... Set baud rate to BB... */
+ {
+ int baudrate;
+ extern void set_timer_3();
+
+ ptr = &remcomInBuffer[1];
+ if (!hexToInt(&ptr, &baudrate))
+ {
+ strcpy(remcomOutBuffer,"B01");
+ break;
+ }
+
+ /* Convert baud rate to uart clock divider */
+ switch (baudrate)
+ {
+ case 38400:
+ baudrate = 16;
+ break;
+ case 19200:
+ baudrate = 33;
+ break;
+ case 9600:
+ baudrate = 65;
+ break;
+ default:
+ strcpy(remcomOutBuffer,"B02");
+ goto x1;
+ }
+
+ putpacket("OK"); /* Ack before changing speed */
+ set_timer_3(baudrate); /* Set it */
+ }
+x1: break;
+#endif
+ } /* switch */
+
+ /* reply to the request */
+ putpacket(remcomOutBuffer);
+ }
+}
+
+/* This function will generate a breakpoint exception. It is used at the
+ beginning of a program to sync up with a debugger and can be used
+ otherwise as a quick means to stop program execution and "break" into
+ the debugger. */
+
+void
+breakpoint()
+{
+ if (!initialized)
+ return;
+
+ asm(" .globl _breakinst
+
+ _breakinst: ta 1
+ ");
+}
+
+static void
+hw_breakpoint()
+{
+ asm("
+ ta 127
+ ");
+}
+
+#if 0 /* experimental and never finished, left here for reference */
+static void
+splet_temp(void)
+{
+ asm(" sub %sp,(16+1+6+1+121)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[121]
+
+! Leave a trail of breadcrumbs! (save register save area for debugging)
+ mov %sp, %l0
+ add %l0, 24*4, %l0
+ sethi %hi(_debug_registers), %l1
+ st %l0, [%lo(_debug_registers) + %l1]
+
+! Save the Alternate Register Set: (not implemented yet)
+! To save the Alternate Register set, we must:
+! 1) Save the current SP in some global location.
+! 2) Swap the register sets.
+! 3) Save the Alternate SP in the Y register
+! 4) Fetch the SP that we saved in step 1.
+! 5) Use that to save the rest of the regs (not forgetting ASP in Y)
+! 6) Restore the Alternate SP from Y
+! 7) Swap the registers back.
+
+! 1) Copy the current stack pointer to global _SAVED_STACK_POINTER:
+ sethi %hi(_saved_stack_pointer), %l0
+ st %sp, [%lo(_saved_stack_pointer) + %l0]
+
+! 2) Swap the register sets:
+ mov %psr, %l1
+ sethi %hi(0x10000), %l2
+ xor %l1, %l2, %l1
+ mov %l1, %psr
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+
+! 3) Save Alternate L0 in Y
+ wr %l0, 0, %y
+
+! 4) Load former SP into alternate SP, using L0
+ sethi %hi(_saved_stack_pointer), %l0
+ or %lo(_saved_stack_pointer), %l0, %l0
+ swap [%l0], %sp
+
+! 4.5) Restore alternate L0
+ rd %y, %l0
+
+! 5) Save the Alternate Window Registers
+ st %r0, [%sp + (24 + 88) * 4] ! AWR0
+ st %r1, [%sp + (24 + 89) * 4] ! AWR1
+ st %r2, [%sp + (24 + 90) * 4] ! AWR2
+ st %r3, [%sp + (24 + 91) * 4] ! AWR3
+ st %r4, [%sp + (24 + 92) * 4] ! AWR4
+ st %r5, [%sp + (24 + 93) * 4] ! AWR5
+ st %r6, [%sp + (24 + 94) * 4] ! AWR6
+ st %r7, [%sp + (24 + 95) * 4] ! AWR7
+ st %r8, [%sp + (24 + 96) * 4] ! AWR8
+ st %r9, [%sp + (24 + 97) * 4] ! AWR9
+ st %r10, [%sp + (24 + 98) * 4] ! AWR10
+ st %r11, [%sp + (24 + 99) * 4] ! AWR11
+ st %r12, [%sp + (24 + 100) * 4] ! AWR12
+ st %r13, [%sp + (24 + 101) * 4] ! AWR13
+! st %r14, [%sp + (24 + 102) * 4] ! AWR14 (SP)
+ st %r15, [%sp + (24 + 103) * 4] ! AWR15
+ st %r16, [%sp + (24 + 104) * 4] ! AWR16
+ st %r17, [%sp + (24 + 105) * 4] ! AWR17
+ st %r18, [%sp + (24 + 106) * 4] ! AWR18
+ st %r19, [%sp + (24 + 107) * 4] ! AWR19
+ st %r20, [%sp + (24 + 108) * 4] ! AWR20
+ st %r21, [%sp + (24 + 109) * 4] ! AWR21
+ st %r22, [%sp + (24 + 110) * 4] ! AWR22
+ st %r23, [%sp + (24 + 111) * 4] ! AWR23
+ st %r24, [%sp + (24 + 112) * 4] ! AWR24
+ st %r25, [%sp + (24 + 113) * 4] ! AWR25
+ st %r26, [%sp + (24 + 114) * 4] ! AWR26
+ st %r27, [%sp + (24 + 115) * 4] ! AWR27
+ st %r28, [%sp + (24 + 116) * 4] ! AWR28
+ st %r29, [%sp + (24 + 117) * 4] ! AWR29
+ st %r30, [%sp + (24 + 118) * 4] ! AWR30
+ st %r31, [%sp + (24 + 119) * 4] ! AWR21
+
+! Get the Alternate PSR (I hope...)
+
+ rd %psr, %l2
+ st %l2, [%sp + (24 + 120) * 4] ! APSR
+
+! Don't forget the alternate stack pointer
+
+ rd %y, %l3
+ st %l3, [%sp + (24 + 102) * 4] ! AWR14 (SP)
+
+! 6) Restore the Alternate SP (saved in Y)
+
+ rd %y, %o6
+
+
+! 7) Swap the registers back:
+
+ mov %psr, %l1
+ sethi %hi(0x10000), %l2
+ xor %l1, %l2, %l1
+ mov %l1, %psr
+ nop ! 3 nops after write to %psr (needed?)
+ nop
+ nop
+");
+}
+
+#endif
diff --git a/libgloss/sparc/sparclite.h b/libgloss/sparc/sparclite.h
new file mode 100644
index 0000000..0f14d51
--- /dev/null
+++ b/libgloss/sparc/sparclite.h
@@ -0,0 +1,81 @@
+/* SPARClite defs
+ *
+ * Copyright (c) 1995 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+/* Macros for reading and writing to arbitrary address spaces. Note that ASI
+ must be a constant (sorry, but the SPARC can only specify ASIs as part of an
+ instruction. */
+
+#define read_asi(ASI, LOC) \
+ ({ \
+ unsigned int val; \
+ __asm__ volatile ("lda [%r1]%2,%0" : "=r" (val) : "rJ" (LOC), "I" (ASI)); \
+ val; \
+ })
+
+#define write_asi(ASI, LOC, VAL) \
+ __asm__ volatile ("sta %0,[%r1]%2" : : "r" (VAL), "rJ" (LOC), "I" (ASI))
+
+/* Use this when modifying registers that cause memory to be modified. This
+ will cause GCC to reload all values after this point. */
+
+#define write_asi_volatile(ASI, LOC, VAL) \
+ __asm__ volatile ("sta %0,[%r1]%2" : : "r" (VAL), "rJ" (LOC), "I" (ASI) \
+ : "memory")
+
+/* Read the PSR (processor state register). */
+
+#define read_psr() \
+ ({ \
+ unsigned int psr; \
+ __asm__ ("mov %%psr, %0" : "=r" (psr)); \
+ psr; \
+ })
+
+/* Write the PSR. */
+
+#define write_psr(VAL) \
+ __asm__ ("mov %0, %%psr \n nop \n nop \n nop" : : "r" (VAL))
+
+/* Read the specified Ancillary State Register. */
+
+#define read_asr(REG) read_asr1(REG)
+#define read_asr1(REG) \
+ ({ \
+ unsigned int val; \
+ __asm__ ("rd %%asr" #REG ",%0" : "=r" (val)); \
+ val; \
+ })
+
+/* Write the specified Ancillary State Register. */
+
+#define write_asr(REG, VAL) write_asr1(REG, VAL)
+#define write_asr1(REG, VAL) \
+ __asm__ ("wr %0, 0, %%asr" #REG : : "r" (VAL))
+
+/* Set window size for window overflow and underflow trap handlers. Better to
+ do this at at compile time than to calculate them at compile time each time
+ we get a window overflow/underflow trap. */
+
+#ifdef SL933
+ asm ("__WINSIZE=6");
+#else
+ asm ("__WINSIZE=8");
+#endif
+
+#define PSR_INIT 0x10c0 /* Disable traps, set s and ps */
+#define TBR_INIT 0
+#define WIM_INIT 2
+#define STACK_SIZE 16 * 1024
+
diff --git a/libgloss/sparc/sysc-701.c b/libgloss/sparc/sysc-701.c
new file mode 100644
index 0000000..191a08a
--- /dev/null
+++ b/libgloss/sparc/sysc-701.c
@@ -0,0 +1,55 @@
+/* more sparclet syscall support (the rest is in crt0-701.S). */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+int
+fstat(int _fd, struct stat* _sbuf)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+int
+isatty(int fd)
+{
+ if (fd < 0)
+ {
+ errno = EBADF;
+ return -1;
+ }
+ return fd <= 2;
+}
+
+int
+getpid()
+{
+ return 1;
+}
+
+int
+kill(int pid)
+{
+ /* if we knew how to nuke the board, we would... */
+ return 0;
+}
+
+int
+lseek(int _fd, off_t offset, int whence)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+extern char end;
+char*
+sbrk (int incr)
+{
+ static char* base;
+ char *b;
+ if(!base) base = &end;
+ b = base;
+ base += incr;
+ return b;
+}
diff --git a/libgloss/sparc/syscalls.c b/libgloss/sparc/syscalls.c
new file mode 100644
index 0000000..01ba501
--- /dev/null
+++ b/libgloss/sparc/syscalls.c
@@ -0,0 +1,85 @@
+/* Copyright (c) 1995 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ *
+ * fake unix routines for sparclite and remote debugger
+ * Many of these routines just substitute an appropriate error status,
+ * if you want some kind of file system access, you'll have to fill them in...
+ * sbrk on the other hand is functional (malloc uses it) but it doesn't do
+ * any checking for lack of memory.
+ * kill and _exit could get more real implementations, as well.
+ */
+
+#include <sys/stat.h>
+
+int
+fstat(int _fd, struct stat* _sbuf)
+{
+ /* this is used in a few places in stdio... */
+ /* just error, so they assume a pipe */
+ return -1;
+}
+
+int
+isatty(int _fd)
+{
+ return 1;
+}
+
+int
+close(int _fd)
+{
+ /* return value usually ignored anyhow */
+ return 0;
+}
+
+int
+open(char *filename)
+{
+ /* always fail */
+ return -1;
+}
+
+int
+getpid() {
+ return 1;
+}
+
+int
+kill(int pid) {
+ /* if we knew how to nuke the board, we would... */
+ return 0;
+}
+
+void
+_exit(int status) {
+ /* likewise... */
+ return;
+}
+
+int
+lseek(int _fd, off_t offset, int whence)
+{
+ /* nothing is ever seekable */
+ return -1;
+}
+
+extern char end;
+char*
+sbrk(int incr)
+{
+ static char* base;
+ char *b;
+ if(!base) base = &end;
+ b = base;
+ base += incr;
+ return b;
+}
diff --git a/libgloss/sparc/test.c b/libgloss/sparc/test.c
new file mode 100644
index 0000000..fc443a8
--- /dev/null
+++ b/libgloss/sparc/test.c
@@ -0,0 +1,69 @@
+#include "debug.h"
+
+char hextab[] = "0123456789abcdef";
+
+int
+foo(arg)
+ int arg;
+{
+ return arg+1;
+}
+
+int
+fact (i)
+ int i;
+{
+ if (i == 1)
+ return 1;
+ else
+ return i * fact ( i - 1);
+}
+
+main()
+{
+ unsigned char c;
+ int num;
+ char foo[100];
+
+#if 0
+ set_debug_level(2);
+
+ cache_on();
+#endif
+
+ set_debug_traps();
+ breakpoint();
+
+ print("Got to here\r\n");
+
+ while (1) {
+ c = inbyte();
+ if (c == 'c')
+ break;
+
+ if (c == 'd') {
+ set_debug_traps();
+ breakpoint();
+ break;
+ }
+
+ print("echo ");
+ outbyte(c);
+ print("\r\n");
+ }
+
+ print("Hello world\r\n");
+
+ while (1) {
+ c = inbyte();
+
+ if ((c & 0x7f) == 4)
+ break;
+
+ print("Char is ");
+ outbyte (c);
+ print("\r\n");
+ }
+
+ print("I escaped!\r\n");
+}
diff --git a/libgloss/sparc/traps.S b/libgloss/sparc/traps.S
new file mode 100644
index 0000000..b3cc966
--- /dev/null
+++ b/libgloss/sparc/traps.S
@@ -0,0 +1,651 @@
+/*
+ * Copyright (c) 1995, 1996, 1998 Cygnus Support
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+
+#include "asm.h"
+#include "slite.h"
+
+ .text
+ .align 4
+
+/*
+ * The trap table has to be the first code in a boot PROM. But because
+ * the Memory Configuration comes up thinking we only have 4K of PROM, we
+ * cannot have a full trap table and still have room left over to
+ * reprogram the Memory Configuration register correctly. This file
+ * uses an abbreviated trap which has every entry which might be used
+ * before RTEMS installs its own trap table.
+ */
+ .globl _trap_table
+_trap_table:
+ TRAP(SYM(ercinit)); ! 00 reset trap
+ BAD_TRAP; ! 01 instruction access exception
+ TRAP(SYM(no_fpu)); ! 02 illegal instruction
+ BAD_TRAP; ! 03 privileged instruction
+ BAD_TRAP; ! 04 fp disabled
+ TRAP(SYM(win_overflow)); ! 05 window overflow
+ TRAP(SYM(win_underflow)); ! 06 window underflow
+ BAD_TRAP; ! 07 memory address not aligned
+ BAD_TRAP; ! 08 fp exception
+ BAD_TRAP; ! 09 data access exception
+ BAD_TRAP; ! 0A tag overflow
+
+ /* Trap levels from 0B to 0x10 are not defined (used for MEC init) */
+
+SYM(ercinit):
+ sethi %hi(_ERC32_MEC), %g1 ! 0B
+ sethi %hi(0x001C1000), %g2
+ or %g1,%lo(0x001C1000),%g1
+ st %g2, [%g1 + 0x10]
+ st %g0, [%g1 + 0x18] ! 0C
+ nop
+ nop
+ nop
+
+ TRAP(SYM(hard_reset)); ! 0D undefined
+ BAD_TRAP; ! 0E undefined
+ BAD_TRAP; ! 0F undefined
+ BAD_TRAP; ! 10 undefined
+
+ /*
+ * ERC32 defined traps
+ */
+
+ BAD_TRAP; ! 11 masked errors
+ BAD_TRAP; ! 12 external 1
+ BAD_TRAP; ! 13 external 2
+ BAD_TRAP; ! 14 UART A RX/TX
+ BAD_TRAP; ! 15 UART B RX/TX
+ BAD_TRAP; ! 16 correctable memory error
+ BAD_TRAP; ! 17 UART error
+ BAD_TRAP; ! 18 DMA access error
+ BAD_TRAP; ! 19 DMA timeout
+ BAD_TRAP; ! 1A external 3
+ BAD_TRAP; ! 1B external 4
+ BAD_TRAP; ! 1C general purpose timer
+ BAD_TRAP; ! 1D real time clock
+ BAD_TRAP; ! 1E external 5
+ BAD_TRAP; ! 1F watchdog timeout
+
+
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 20 - 23 undefined
+ BAD_TRAP; ! 24 cp_disabled
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 25 - 27 undefined
+ BAD_TRAP; ! 28 cp_exception
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 29 - 2B undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 2C - 2F undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30 - 33 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34 - 37 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38 - 3B undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3C - 3F undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40 - 43 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44 - 47 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48 - 4B undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4C - 4F undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50 - 53 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54 - 57 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58 - 5B undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5C - 5F undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60 - 63 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64 - 67 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68 - 6B undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6C - 6F undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70 - 73 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74 - 77 undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78 - 7B undefined
+ BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7C - 7F undefined
+
+ /*
+ * Software traps
+ *
+ * NOTE: At the risk of being redundant... this is not a full
+ * table. The setjmp on the SPARC requires a window flush trap
+ * handler and RTEMS will preserve the entries that were
+ * installed before.
+ */
+
+ SOFT_TRAP; ! 80
+#if 0
+ SOFT_TRAP; ! 81
+#else
+ TRAP(SYM(trap_low)) ! 81
+#endif
+ SOFT_TRAP; ! 82
+ TRAP(SYM(win_flush)); ! 83 flush windows SW trap
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84 - 87
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88 - 8B
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8C - 8F
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90 - 93
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94 - 97
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98 - 9B
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9C - 9F
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A0 - A3
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A4 - A7
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A8 - AB
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! AC - AF
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B0 - B3
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B4 - B7
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B8 - BB
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! BC - BF
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C0 - C3
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C4 - C7
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C8 - CB
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! CC - CF
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D0 - D3
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D4 - D7
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D8 - DB
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! DC - DF
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E0 - E3
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E4 - E7
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E8 - EB
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! EC - EF
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F0 - F3
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F4 - F7
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F8 - FB
+ SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! FC - FF
+
+/*
+ * Startup code for standalone system. Wash IU and FPU (if present)
+ * registers. The registers have to be written to initiate the parity
+ * bits.
+ */
+ .globl SYM(hard_reset)
+SYM(hard_reset):
+
+ sethi %hi(0x01FE0),%o0
+ or %o0,%lo(0x01FE0),%o0
+ mov %o0, %psr ! Set valid PSR
+ nop
+
+ mov %g0, %wim ! Set window invalid mask register
+ mov %g0, %y ! Init Y-register
+ nop
+ sethi %hi(SYM(hard_reset)), %g1
+
+ mov %g1, %tbr ! Set TBR
+ sethi %hi(SP_INIT),%sp
+ or %g0, 1, %o0
+ ld [%g0], %f0 ! Check if FPU is present
+
+ tst %o0
+ bz fixiu
+ nop
+ ba fixfpu
+
+! FPU disabled trap address
+
+ clr %i0
+ jmpl %l2, %g0
+ rett %l2 + 4
+ nop
+
+
+! Wash register files (fix for 90C601E & 90C602E)
+
+fixfpu:
+
+ ld [%g0], %f0
+ ld [%g0], %f1
+ ld [%g0], %f2
+ ld [%g0], %f3
+ ld [%g0], %f4
+ ld [%g0], %f5
+ ld [%g0], %f6
+ ld [%g0], %f7
+ ld [%g0], %f8
+ ld [%g0], %f9
+ ld [%g0], %f10
+ ld [%g0], %f11
+ ld [%g0], %f12
+ ld [%g0], %f13
+ ld [%g0], %f14
+ ld [%g0], %f15
+ ld [%g0], %f16
+ ld [%g0], %f17
+ ld [%g0], %f18
+ ld [%g0], %f19
+ ld [%g0], %f20
+ ld [%g0], %f21
+ ld [%g0], %f22
+ ld [%g0], %f23
+ ld [%g0], %f24
+ ld [%g0], %f25
+ ld [%g0], %f26
+ ld [%g0], %f27
+ ld [%g0], %f28
+ ld [%g0], %f29
+ ld [%g0], %f30
+ ld [%g0], %f31
+
+fixiu:
+ clr %g1
+ clr %g2
+ clr %g3
+ clr %g4
+ clr %g5
+ clr %g6
+ clr %g7
+ set 8,%g1
+wl0:
+ clr %i0
+ clr %i1
+ clr %i2
+ clr %i3
+ clr %i4
+ clr %i5
+ clr %i6
+ clr %i7
+ clr %l0
+ clr %l1
+ clr %l2
+ clr %l3
+ clr %l4
+ clr %l5
+ clr %l6
+ clr %l7
+ save
+ subcc %g1, 1, %g1
+ bne wl0
+ nop
+
+!
+! Start the real-time clock with a tick of 150 clocks
+!
+
+rtc:
+
+ set 0x1f80000, %l0 ! MEC register base
+ set 149, %l1
+ st %l1, [%l0 + 0x84] ! RTC scaler = 149
+ set 0x0d00, %l1
+ st %l1, [%l0 + 0x98] ! Start RTC
+
+ st %g0, [%l0 + 0x64] ! Disable watchdog for now
+ ld [%l0], %g1
+ or %g1, 1, %g1
+ st %g1, [%l0] ! Enable power-down mode
+
+_init:
+ set PSR_INIT, %g1 ! Initialize psr
+ mov %g1, %psr
+ set WIM_INIT, %g1 ! Initialize WIM
+ mov %g1, %wim
+ set _trap_table, %g1 ! Initialize TBR
+ mov %g1, %tbr
+ nop;nop;nop
+
+ set PSR_INIT, %g1
+ wr %g1, 0x20, %psr ! enable traps
+ nop; nop; nop;
+
+ call SYM(start)
+ nop
+
+/*
+ * Register window overflow handler. Come here when save would move us
+ * into the invalid window. This routine runs with traps disabled, and
+ * must be careful not to touch the condition codes, as PSR is never
+ * restored.
+ *
+ * We are called with %l0 = wim, %l1 = pc, %l2 = npc
+ */
+ .globl SYM(win_overflow)
+SYM(win_overflow):
+ mov %g1, %l3 ! Save g1, we use it to hold the wim
+ srl %l0, 1, %g1 ! Rotate wim right
+ sll %l0, NUMBER_OF_REGISTER_WINDOWS - 1, %l0
+ or %l0, %g1, %g1
+
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+ nop
+ nop
+ nop
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l3, %g1 ! Restore %g1
+
+ jmpl %l1, %g0
+ rett %l2
+
+/*
+ * Register window underflow handler. Come here when restore would move us
+ * into the invalid window. This routine runs with traps disabled, and
+ * must be careful not to touch the condition codes, as PSR is never
+ * restored.
+ *
+ * We are called with %l0 = wim, %l1 = pc, %l2 = npc
+ */
+ .globl SYM(win_underflow)
+SYM(win_underflow):
+ sll %l0, 1, %l3 ! Rotate wim left
+ srl %l0, NUMBER_OF_REGISTER_WINDOWS - 1, %l0
+ or %l0, %l3, %l0
+
+ mov %l0, %wim ! Install the new wim
+
+ restore ! Users window
+ restore ! His callers window
+
+ ldd [%sp + 0 * 4], %l0 ! restore L & I registers
+ ldd [%sp + 2 * 4], %l2
+ ldd [%sp + 4 * 4], %l4
+ ldd [%sp + 6 * 4], %l6
+
+ ldd [%sp + 8 * 4], %i0
+ ldd [%sp + 10 * 4], %i2
+ ldd [%sp + 12 * 4], %i4
+ ldd [%sp + 14 * 4], %i6
+
+ save %g0, %g0, %g0 ! Back to trap window
+ save %g0, %g0, %g0
+
+ jmpl %l1, %g0
+ rett %l2
+
+/*
+ * Register window flush handler, triggered by a "ta 3" instruction.
+ * We are called with %l0 = wim, %l1 = pc, %l2 = npc
+ */
+ .globl SYM(win_flush)
+SYM(win_flush):
+ mov %psr, %l0
+ or %l0,0xf00,%l3 ! Disable interrupts
+ mov %l3,%psr
+ nop
+ nop
+ nop
+ mov %wim, %l3
+
+ srl %l3, %l0, %l4 ! wim >> cwp
+ cmp %l4, 1
+ bne flush_window_fine ! Branch if not in the invalid window
+ nop
+
+/* Handle window overflow. We can't trap here. */
+
+ mov %g1, %l4 ! Save g1, we use it to hold the wim
+ srl %l3, 1, %g1 ! Rotate wim right
+ sll %l3, NUMBER_OF_REGISTER_WINDOWS - 1, %l3
+ or %l3, %g1, %g1
+ mov %g0, %wim ! Clear wim so that subsequent save
+ nop ! wont trap
+ nop
+ nop
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l4, %g1 ! Restore %g1
+
+flush_window_fine:
+ mov %psr,%l5 ! enable traps
+ or %l5,0x20,%l5
+ mov %l5, %psr
+ nop
+ nop
+ nop
+
+ set save_buf,%l5
+ st %l2,[%l5]
+
+ ! The stack pointer currently contains a bogus value [when a trap
+ ! occurs CWP is decremented and points to an unused window].
+ ! Give it something useful before we flush every window.
+ ! This does what a "save %sp,-64,$sp" would, except that CWP has
+ ! already been decremented.
+ add %fp, -64, %sp
+
+ save %sp, -64, %sp ! Flush user register window to stack
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ save %sp, -64, %sp
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+ restore
+
+ restore ! Make sure we have a valid window
+ save %g0, %g0, %g0
+
+ set save_buf, %l2 ! Get our return address back
+ ld [%l2],%l2
+
+ mov %psr,%l5 ! disable traps for rett
+ andn %l5,0x20,%l5
+ mov %l5,%psr
+ nop
+ nop
+ nop
+
+ jmpl %l2, %g0
+ rett %l2+4
+
+/*
+ * Read the TBR.
+ */
+ .globl SYM(rdtbr)
+SYM(rdtbr):
+ mov %tbr, %o0
+ nop
+ retl
+ nop
+
+/*
+ * Read the psr
+ */
+ .globl SYM(read_psr)
+SYM(read_psr):
+ mov %psr, %o0
+ nop
+ retl
+ nop
+
+/*
+ * Write the PSR.
+ */
+
+ .globl SYM(write_psr)
+SYM(write_psr):
+ mov %i0, %psr
+ nop
+ nop
+ nop
+ retl
+ nop
+/*
+ * Come here when no fpu exists. This just skips the offending
+ * instruction.
+ */
+ .globl SYM(no_fpu)
+SYM(no_fpu):
+ jmpl %l2, %g0
+ rett %l2+4
+
+ .globl SYM(fltr_proto)
+ .align 4
+SYM(fltr_proto): ! First level trap routine prototype
+ sethi 0, %l0
+ jmpl 0+%l0, %g0
+ nop
+ nop
+
+/*
+ * Trap handler for memory errors. This just sets mem_err to be
+ * non-zero. It assumes that l1 is non-zero. This should be safe,
+ * as it is doubtful that 0 would ever contain code that could mem
+ * fault. This routine will skip past the faulting instruction after
+ * setting mem_err.
+ */
+ .globl SYM(fltr_set_mem_err)
+SYM(fltr_set_mem_err):
+ sethi %hi(SYM(mem_err)), %l0
+ st %l1, [%l0 + %lo(SYM(mem_err))]
+ jmpl %l2, %g0
+ rett %l2+4
+
+ .data
+ .align 4
+ .ascii "DaTa"
+ .long SYM(sdata)
+in_trap_handler:
+ .word 0
+save_buf:
+ .word 0 /* place to save %g1 */
+ .word 0 /* place to save %g2 */
+
+ .text
+ .align 4
+
+/*
+ * This function is called when any SPARC trap (except window overflow
+ * or underflow) occurs. It makes sure that the invalid register
+ * window is still available before jumping into C code. It will also
+ * restore the world if you return from handle_exception.
+ */
+ .globl SYM(trap_low)
+SYM(trap_low):
+ mov %psr, %l0
+ mov %wim, %l3
+
+ srl %l3, %l0, %l4 ! wim >> cwp
+ cmp %l4, 1
+ bne window_fine ! Branch if not in the invalid window
+ nop
+
+ mov %g1, %l4 ! Save g1, we use it to hold the wim
+ srl %l3, 1, %g1 ! Rotate wim right
+ sll %l3, 8-1, %l5
+ or %l5, %g1, %g1
+
+ save %g0, %g0, %g0 ! Slip into next window
+ mov %g1, %wim ! Install the new wim
+
+ std %l0, [%sp + 0 * 4] ! save L & I registers
+ std %l2, [%sp + 2 * 4]
+ std %l4, [%sp + 4 * 4]
+ std %l6, [%sp + 6 * 4]
+
+ std %i0, [%sp + 8 * 4]
+ std %i2, [%sp + 10 * 4]
+ std %i4, [%sp + 12 * 4]
+ std %i6, [%sp + 14 * 4]
+
+ restore ! Go back to trap window.
+ mov %l4, %g1 ! Restore g1
+
+window_fine:
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ tst %l5
+ bg recursive_trap
+ inc %l5
+
+ /* use the stack we set in the linker script */
+ sethi %hi(__trap_stack), %l6
+ or %l6,%lo(__trap_stack),%l6
+ mov %l6, %sp ! set the stack pointer
+
+recursive_trap:
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ sub %sp,(16+1+6+1+72)*4,%sp ! Make room for input & locals
+ ! + hidden arg + arg spill
+ ! + doubleword alignment
+ ! + registers[72] local var
+
+ std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
+ std %g2, [%sp + (24 + 2) * 4]
+ std %g4, [%sp + (24 + 4) * 4]
+ std %g6, [%sp + (24 + 6) * 4]
+
+ std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
+ std %i2, [%sp + (24 + 10) * 4]
+ std %i4, [%sp + (24 + 12) * 4]
+ std %i6, [%sp + (24 + 14) * 4]
+ ! F0->F31 not implemented
+ mov %y, %l4
+ mov %tbr, %l5
+ st %l4, [%sp + (24 + 64) * 4] ! Y
+ st %l0, [%sp + (24 + 65) * 4] ! PSR
+ st %l3, [%sp + (24 + 66) * 4] ! WIM
+ st %l5, [%sp + (24 + 67) * 4] ! TBR
+ st %l1, [%sp + (24 + 68) * 4] ! PC
+ st %l2, [%sp + (24 + 69) * 4] ! NPC
+ ! CPSR and FPSR not implemented
+
+ or %l0, 0xf20, %l4
+ mov %l4, %psr ! Turn on traps, disable interrupts
+
+ call SYM(handle_exception)
+ add %sp, 24 * 4, %o0 ! Pass address of registers
+
+/* Reload all of the registers that aren't on the stack */
+
+ ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
+ ldd [%sp + (24 + 2) * 4], %g2
+ ldd [%sp + (24 + 4) * 4], %g4
+ ldd [%sp + (24 + 6) * 4], %g6
+
+ ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
+ ldd [%sp + (24 + 10) * 4], %i2
+ ldd [%sp + (24 + 12) * 4], %i4
+ ldd [%sp + (24 + 14) * 4], %i6
+
+ ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
+ ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
+
+ restore ! Ensure that previous window is valid
+ save %g0, %g0, %g0 ! by causing a window_underflow trap
+
+ mov %l0, %y
+ mov %l1, %psr ! Make sure that traps are disabled
+ ! for rett
+
+ sethi %hi(in_trap_handler), %l4
+ ld [%lo(in_trap_handler) + %l4], %l5
+ dec %l5
+ st %l5, [%lo(in_trap_handler) + %l4]
+
+ jmpl %l2, %g0 ! Restore old PC
+ rett %l3 ! Restore old nPC
+
+
diff --git a/libgloss/sparc/tsc701.ld b/libgloss/sparc/tsc701.ld
new file mode 100644
index 0000000..bc6cd73
--- /dev/null
+++ b/libgloss/sparc/tsc701.ld
@@ -0,0 +1,55 @@
+/* must compile with -nostdlib option */
+OUTPUT_FORMAT("a.out-sunos-big", "a.out-sunos-big",
+ "a.out-sparc-little")
+OUTPUT_ARCH(sparc)
+SEARCH_DIR(/usr/local/sparclet-aout/lib)
+PROVIDE (__stack = 0);
+ENTRY (start)
+STARTUP (crt0-701.o)
+GROUP (libsplet701.a libc.a libgcc.a)
+SECTIONS
+{
+ /* Sparcmon likes to load programs starting at this address. */
+ . = 0x12010000;
+ .text :
+ {
+ CREATE_OBJECT_SYMBOLS
+ *(.text)
+ /* The next six sections are for SunOS dynamic linking. The order
+ is important. */
+ *(.dynrel)
+ *(.hash)
+ *(.dynsym)
+ *(.dynstr)
+ *(.rules)
+ *(.need)
+ _etext = .;
+ __etext = .;
+ }
+ .data :
+ {
+ /* The first three sections are for SunOS dynamic linking. */
+ *(.dynamic)
+ *(.got)
+ *(.plt)
+ *(.data)
+ *(.linux-dynamic) /* For Linux dynamic linking. */
+ CONSTRUCTORS
+ _edata = .;
+ __edata = .;
+ }
+ .bss :
+ {
+ __bss_start = .;
+ *(.bss)
+ *(COMMON)
+ _end = ALIGN(4) ;
+ __end = ALIGN(4) ;
+ }
+ /* This is the value that Sparcmon assigns to the SP at reset, minus 4K. */
+ PROVIDE(___stack = 0x123ef000);
+ PROVIDE(__stack = 0x123ef000);
+ /* Provide 4K area for copying the trap vectors from ROM to RAM. */
+ PROVIDE(___trap_vectors = 0x123f0000);
+ PROVIDE(__trap_vectors = 0x123f0000);
+}