20000317 sourceware import
This commit is contained in:
286
libgloss/sparc/Makefile.in
Normal file
286
libgloss/sparc/Makefile.in
Normal file
@ -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
|
39
libgloss/sparc/asm.h
Normal file
39
libgloss/sparc/asm.h
Normal file
@ -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
|
147
libgloss/sparc/cache.c
Normal file
147
libgloss/sparc/cache.c
Normal file
@ -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 */
|
||||
}
|
||||
}
|
||||
}
|
1201
libgloss/sparc/configure
vendored
Executable file
1201
libgloss/sparc/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
120
libgloss/sparc/configure.in
Normal file
120
libgloss/sparc/configure.in
Normal file
@ -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}
|
||||
)
|
||||
|
105
libgloss/sparc/crt0-701.S
Normal file
105
libgloss/sparc/crt0-701.S
Normal file
@ -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
|
186
libgloss/sparc/crt0.S
Normal file
186
libgloss/sparc/crt0.S
Normal file
@ -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.
|
144
libgloss/sparc/cygmon-crt0.S
Normal file
144
libgloss/sparc/cygmon-crt0.S
Normal file
@ -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
|
220
libgloss/sparc/cygmon-salib.c
Normal file
220
libgloss/sparc/cygmon-salib.c
Normal file
@ -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;
|
||||
}
|
159
libgloss/sparc/cygmon-sparc64-ld.src
Normal file
159
libgloss/sparc/cygmon-sparc64-ld.src
Normal file
@ -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 . */
|
||||
}
|
195
libgloss/sparc/cygmon.ld.src
Normal file
195
libgloss/sparc/cygmon.ld.src
Normal file
@ -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 ]
|
||||
}
|
||||
}
|
25
libgloss/sparc/dtor.C
Normal file
25
libgloss/sparc/dtor.C
Normal file
@ -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); */
|
||||
}
|
202
libgloss/sparc/elfsim.ld
Normal file
202
libgloss/sparc/elfsim.ld
Normal file
@ -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 . */
|
||||
}
|
75
libgloss/sparc/erc32-crt0.S
Normal file
75
libgloss/sparc/erc32-crt0.S
Normal file
@ -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
|
||||
|
47
libgloss/sparc/erc32-io.c
Normal file
47
libgloss/sparc/erc32-io.c
Normal file
@ -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;
|
||||
}
|
363
libgloss/sparc/erc32-stub.c
Normal file
363
libgloss/sparc/erc32-stub.c
Normal file
@ -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 *)®isters[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 *)®isters[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 *)®isters[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;
|
||||
}
|
146
libgloss/sparc/erc32.ld
Normal file
146
libgloss/sparc/erc32.ld
Normal file
@ -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 ]
|
||||
}
|
||||
}
|
160
libgloss/sparc/ex930.ld
Normal file
160
libgloss/sparc/ex930.ld
Normal file
@ -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 . */
|
||||
}
|
160
libgloss/sparc/ex931.ld
Normal file
160
libgloss/sparc/ex931.ld
Normal file
@ -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 . */
|
||||
}
|
160
libgloss/sparc/ex934.ld
Normal file
160
libgloss/sparc/ex934.ld
Normal file
@ -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 . */
|
||||
}
|
54
libgloss/sparc/fixctors.c
Normal file
54
libgloss/sparc/fixctors.c
Normal file
@ -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__);
|
||||
}
|
167
libgloss/sparc/libsys/Makefile.in
Normal file
167
libgloss/sparc/libsys/Makefile.in
Normal file
@ -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
|
14
libgloss/sparc/libsys/_exit.S
Normal file
14
libgloss/sparc/libsys/_exit.S
Normal file
@ -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)
|
47
libgloss/sparc/libsys/cerror.S
Normal file
47
libgloss/sparc/libsys/cerror.S
Normal file
@ -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
|
991
libgloss/sparc/libsys/configure
vendored
Executable file
991
libgloss/sparc/libsys/configure
vendored
Executable file
@ -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
|
||||
|
50
libgloss/sparc/libsys/configure.in
Normal file
50
libgloss/sparc/libsys/configure.in
Normal file
@ -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)
|
17
libgloss/sparc/libsys/isatty.c
Normal file
17
libgloss/sparc/libsys/isatty.c
Normal file
@ -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;
|
||||
}
|
127
libgloss/sparc/libsys/libsys-crt0.S
Normal file
127
libgloss/sparc/libsys/libsys-crt0.S
Normal file
@ -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)
|
66
libgloss/sparc/libsys/sbrk.S
Normal file
66
libgloss/sparc/libsys/sbrk.S
Normal file
@ -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
|
39
libgloss/sparc/libsys/syscall.h
Normal file
39
libgloss/sparc/libsys/syscall.h
Normal file
@ -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_ */
|
93
libgloss/sparc/libsys/syscallasm.h
Normal file
93
libgloss/sparc/libsys/syscallasm.h
Normal file
@ -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_ */
|
14
libgloss/sparc/libsys/template.S
Normal file
14
libgloss/sparc/libsys/template.S
Normal file
@ -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))
|
26
libgloss/sparc/libsys/template_r.S
Normal file
26
libgloss/sparc/libsys/template_r.S
Normal file
@ -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
|
288
libgloss/sparc/salib-701.c
Normal file
288
libgloss/sparc/salib-701.c
Normal file
@ -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");
|
||||
}
|
388
libgloss/sparc/salib.c
Normal file
388
libgloss/sparc/salib.c
Normal file
@ -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
|
127
libgloss/sparc/slite.h
Normal file
127
libgloss/sparc/slite.h
Normal file
@ -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|
|
||||
* +-------------+--+--+--+--+--+--+--+--+
|
||||
*/
|
||||
|
848
libgloss/sparc/sparc-stub.c
Normal file
848
libgloss/sparc/sparc-stub.c
Normal file
@ -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 *)®isters[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 *)®isters[NPC], ptr, 4, 0);
|
||||
*ptr++ = ';';
|
||||
|
||||
*ptr++ = hexchars[O7 >> 4];
|
||||
*ptr++ = hexchars[O7 & 0xf];
|
||||
*ptr++ = ':';
|
||||
ptr = mem2hex((char *)®isters[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 *)®isters[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 *)®isters[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
|
||||
");
|
||||
}
|
177
libgloss/sparc/sparc86x.ld
Normal file
177
libgloss/sparc/sparc86x.ld
Normal file
@ -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 . */
|
||||
}
|
1005
libgloss/sparc/sparcl-stub.c
Normal file
1005
libgloss/sparc/sparcl-stub.c
Normal file
File diff suppressed because it is too large
Load Diff
1233
libgloss/sparc/sparclet-stub.c
Normal file
1233
libgloss/sparc/sparclet-stub.c
Normal file
File diff suppressed because it is too large
Load Diff
81
libgloss/sparc/sparclite.h
Normal file
81
libgloss/sparc/sparclite.h
Normal file
@ -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
|
||||
|
55
libgloss/sparc/sysc-701.c
Normal file
55
libgloss/sparc/sysc-701.c
Normal file
@ -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;
|
||||
}
|
85
libgloss/sparc/syscalls.c
Normal file
85
libgloss/sparc/syscalls.c
Normal file
@ -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;
|
||||
}
|
69
libgloss/sparc/test.c
Normal file
69
libgloss/sparc/test.c
Normal file
@ -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");
|
||||
}
|
651
libgloss/sparc/traps.S
Normal file
651
libgloss/sparc/traps.S
Normal file
@ -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
|
||||
|
||||
|
55
libgloss/sparc/tsc701.ld
Normal file
55
libgloss/sparc/tsc701.ld
Normal file
@ -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);
|
||||
}
|
Reference in New Issue
Block a user