20000317 sourceware import
This commit is contained in:
255
libgloss/m68k/Makefile.in
Normal file
255
libgloss/m68k/Makefile.in
Normal file
@ -0,0 +1,255 @@
|
||||
# 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.
|
||||
#
|
||||
# This currently works with Motorola's MVME135 and IDP m68k based
|
||||
# target boards.
|
||||
#
|
||||
|
||||
VPATH = @srcdir@
|
||||
srcdir = @srcdir@
|
||||
objdir = .
|
||||
srcroot = $(srcdir)/../..
|
||||
objroot = $(objdir)/../..
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
host_alias = @host_alias@
|
||||
target_alias = @target_alias@
|
||||
program_transform_name = @program_transform_name@
|
||||
|
||||
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 = qv
|
||||
|
||||
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`
|
||||
|
||||
SCRIPTS = mvme162 mvme135 idp bcc
|
||||
|
||||
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
|
||||
|
||||
CFLAGS = -g
|
||||
# ARFLAGS = rv
|
||||
|
||||
CRT0 = crt0.o
|
||||
#
|
||||
# here's all the MVME135 target stuff
|
||||
#
|
||||
MVME_LDFLAGS= -L${srcdir} -Tmvme135.ld
|
||||
MVME135_BSP= libmvme135.a
|
||||
MVME162_BSP= libmvme162.a
|
||||
#MVME135_OBJS= mvme.o
|
||||
#MVME162_OBJS= mvme.o
|
||||
# Uncomment the last two objects if you want to use the GDB stub.
|
||||
# The stub is included "as is", and will likely take some hacking
|
||||
# to work on your system.
|
||||
MVME135_OBJS= cpu32bug.o # mvme-stub.o mvme135-asm.o
|
||||
MVME162_OBJS= cpu32bug.o # mvme-stub.o mvme162lx-asm.o
|
||||
|
||||
|
||||
#
|
||||
# here's all the BCC target stuff
|
||||
#
|
||||
BCC_LDFLAGS= -L${srcdir} -Tbcc.ld
|
||||
BCC_BSP= libbcc.a
|
||||
BCC_OBJS= cpu32bug.o
|
||||
|
||||
#
|
||||
# here's all the IDP target stuff
|
||||
#
|
||||
IDP_LDFLAGS= -L${srcdir} -Tidp.ld
|
||||
IDP_BSP= libidp.a
|
||||
IDP_OBJS= leds.o idp-inbyte.o idp-outbyte.o mc68ec.o
|
||||
|
||||
#
|
||||
# here's all the DBUG target stuff
|
||||
#
|
||||
DBUG_BSP= libdbug.a
|
||||
DBUG_OBJS= dbug-exit.o dbug-inbyte.o dbug-outbyte.o
|
||||
|
||||
# Host specific makefile fragment comes in here.
|
||||
@host_makefile_frag@
|
||||
|
||||
#
|
||||
# build a test program for each target board. Just trying to get
|
||||
# it to link is a good test, so we ignore all the errors for now.
|
||||
#
|
||||
all: ${CRT0} ${BCC_BSP} ${IDP_BSP} ${MVME135_BSP} ${MVME162_BSP} ${DBUG_BSP}
|
||||
|
||||
#
|
||||
# here's where we build the board support packages for each target
|
||||
#
|
||||
${BCC_BSP}: $(OBJS) ${BCC_OBJS}
|
||||
${AR} ${ARFLAGS} $@ $(OBJS) ${BCC_OBJS}
|
||||
${RANLIB} $@
|
||||
|
||||
${IDP_BSP}: $(OBJS) ${IDP_OBJS}
|
||||
${AR} ${ARFLAGS} $@ $(OBJS) ${IDP_OBJS}
|
||||
${RANLIB} $@
|
||||
|
||||
${DBUG_BSP}: $(OBJS) ${DBUG_OBJS}
|
||||
${AR} ${ARFLAGS} $@ $(OBJS) ${DBUG_OBJS}
|
||||
${RANLIB} $@
|
||||
|
||||
${MVME135_BSP}: $(OBJS) ${MVME135_OBJS}
|
||||
${AR} ${ARFLAGS} $@ $(OBJS) ${MVME135_OBJS}
|
||||
${RANLIB} $@
|
||||
|
||||
${MVME162_BSP}: $(OBJS) ${MVME162_OBJS}
|
||||
${AR} ${ARFLAGS} $@ $(OBJS) ${MVME162_OBJS}
|
||||
${RANLIB} $@
|
||||
|
||||
leds.o: ${srcdir}/leds.c
|
||||
$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -c $<
|
||||
|
||||
idp-inbyte.o: ${srcdir}/idp-inbyte.c
|
||||
$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -c $<
|
||||
|
||||
idp-outbyte.o: ${srcdir}/idp-outbyte.c
|
||||
$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -c $<
|
||||
|
||||
mc68ec.o: ${srcdir}/mc68ec.c
|
||||
$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) -c $<
|
||||
|
||||
test.o: ${srcdir}/test.c
|
||||
|
||||
#
|
||||
# Make a simple test case to test the linker script, startup code, and
|
||||
# I/O code
|
||||
#
|
||||
test: $(OBJS) idp-test.srec mvme135-test.srec bcc-test.srec \
|
||||
idp-test.dis mvme135-test.dis bcc-test.dis
|
||||
@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.
|
||||
|
||||
idp-test.x: test.o ${CRT0} Makefile ${IDP_BSP}
|
||||
${CC} $(CFLAGS_FOR_TARGET) -L${srcdir} -L${objdir} \
|
||||
test.o -o $@ $(LDFLAGS_FOR_TARGET) -N -Wl,-Tidp.ld
|
||||
idp-test.srec: idp-test.x
|
||||
$(OBJCOPY) -O srec idp-test.x $@
|
||||
idp-test.dis: idp-test.x
|
||||
@rm -fr idp-test.dis
|
||||
$(OBJDUMP) -d idp-test.x > $@
|
||||
idp-test: idp-test.srec idp-test.dis
|
||||
|
||||
mvme135-test.x: test.o ${CRT0} ${srcdir}/mvme135.ld Makefile ${MVME135_BSP}
|
||||
${CC} -L${srcdir} -L${objdir} test.o -o $@ $(LDFLAGS_FOR_TARGET) \
|
||||
-N -Wl,-Tmvme135.ld -nostdlib
|
||||
mvme135-test.srec: mvme135-test.x
|
||||
$(OBJCOPY) -O srec mvme135-test.x $@
|
||||
mvme135-test.dis: mvme135-test.x
|
||||
@rm -fr mvme135-test.dis
|
||||
$(OBJDUMP) -d mvme135-test.x > $@
|
||||
mvme135-test: mvme135-test.srec mvme135-test.dis
|
||||
|
||||
mvme162-test.x: test.o ${CRT0} ${srcdir}/mvme162.ld Makefile ${MVME162_BSP}
|
||||
${CC} -L${srcdir} -L${objdir} test.o -o $@ $(LDFLAGS_FOR_TARGET) \
|
||||
-N -Wl,-Tmvme162.ld -nostdlib
|
||||
mvme162-test.srec: mvme162-test.x
|
||||
$(OBJCOPY) -O srec mvme162-test.x $@
|
||||
mvme162-test.dis: mvme162-test.x
|
||||
@rm -fr mvme162-test.dis
|
||||
$(OBJDUMP) -d mvme162-test.x > $@
|
||||
mvme162-test: mvme162-test.srec mvme162-test.dis
|
||||
|
||||
bcc-test.x: test.o ${CRT0} ${srcdir}/bcc.ld Makefile ${BCC_BSP}
|
||||
${CC} -L${srcdir} -L${objdir} test.o -o $@ $(LDFLAGS_FOR_TARGET) \
|
||||
-N -Wl,-Tbcc.ld -nostdlib
|
||||
bcc-test.srec: bcc-test.x
|
||||
$(OBJCOPY) -O srec bcc-test.x $@
|
||||
bcc-test.dis: bcc-test.x
|
||||
@rm -fr bcc-test.dis
|
||||
$(OBJDUMP) -d bcc-test.x > $@
|
||||
bcc-test: bcc-test.srec bcc-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 ${CRT0} ${srcdir}/mvme135.ld Makefile ${MVME135_BSP}
|
||||
${CC} -L${srcdir} -L${objdir} dtor.o -o $@ $(LIBS_FOR_TARGET) \
|
||||
-N -Wl,-Tmvme135.ld -nostdlib
|
||||
|
||||
|
||||
.PHONY: install info dvi doc install-info clean-info
|
||||
install:
|
||||
$(INSTALL_PROGRAM) $(CRT0) $(tooldir)/lib${MULTISUBDIR}/$(CRT0)
|
||||
# install BCC stuff
|
||||
$(INSTALL_PROGRAM) $(BCC_BSP) $(tooldir)/lib${MULTISUBDIR}/$(BCC_BSP)
|
||||
$(INSTALL_DATA) ${srcdir}/bcc.ld $(tooldir)/lib${MULTISUBDIR}/bcc.ld
|
||||
# install IDP stuff
|
||||
$(INSTALL_PROGRAM) $(IDP_BSP) $(tooldir)/lib${MULTISUBDIR}/$(IDP_BSP)
|
||||
$(INSTALL_DATA) ${srcdir}/idp.ld $(tooldir)/lib${MULTISUBDIR}/idp.ld
|
||||
# install MVME135 stuff
|
||||
$(INSTALL_PROGRAM) $(MVME135_BSP) $(tooldir)/lib${MULTISUBDIR}/$(MVME135_BSP)
|
||||
$(INSTALL_DATA) ${srcdir}/mvme135.ld $(tooldir)/lib${MULTISUBDIR}/mvme135.ld
|
||||
# install MVME162lx stuff
|
||||
$(INSTALL_PROGRAM) $(MVME162_BSP) $(tooldir)/lib${MULTISUBDIR}/$(MVME162_BSP)
|
||||
$(INSTALL_DATA) ${srcdir}/mvme162.ld $(tooldir)/lib${MULTISUBDIR}/mvme162.ld
|
||||
# install DBUG stuff
|
||||
$(INSTALL_PROGRAM) $(DBUG_BSP) $(tooldir)/lib${MULTISUBDIR}/$(DBUG_BSP)
|
||||
$(INSTALL_DATA) ${srcdir}/sbc5204.ld $(tooldir)/lib${MULTISUBDIR}/sbc5204.ld
|
||||
$(INSTALL_DATA) ${srcdir}/sbc5206.ld $(tooldir)/lib${MULTISUBDIR}/sbc5206.ld
|
||||
|
||||
# target specific makefile fragment comes in here.
|
||||
@target_makefile_frag@
|
||||
|
||||
clean mostlyclean:
|
||||
rm -f a.out core *.i *~ *.a *.o *-test *.srec *.dis *.x *.map
|
||||
|
||||
distclean maintainer-clean realclean: clean
|
||||
rm -f Makefile config.cache config.log config.status
|
||||
|
||||
info dvi doc:
|
||||
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
|
8
libgloss/m68k/README
Normal file
8
libgloss/m68k/README
Normal file
@ -0,0 +1,8 @@
|
||||
Support for the mvme162 was written by:
|
||||
|
||||
Technische Universitaet Berlin fax: +49.30.314 21 116
|
||||
Axel Nennker, FR 2-2 phone: +49.30.314 73 114
|
||||
Franklinstr. 28-29 e-mail: nennker@cs.tu-berlin.de
|
||||
D-10587 Berlin World Wide Web: http://www.cs.tu-berlin.de/~nennker
|
||||
Germany http://www.cs.tu-berlin.de/~gnat
|
||||
|
85
libgloss/m68k/asm.h
Normal file
85
libgloss/m68k/asm.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* asm.h -- macros for m68k asm
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* XXX __USER_LABEL_PREFIX__ and __REGISTER_PREFIX__ do not work on gcc 2.7.0-3
|
||||
* XXX The following ifdef magic fixes the problem but results in a warning
|
||||
* XXX when compiling assembly code.
|
||||
*/
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
/* #define __USER_LABEL_PREFIX__ "" /* no underscore for coff */
|
||||
#define __USER_LABEL_PREFIX__ _ /* leading underscore for aout */
|
||||
#endif
|
||||
|
||||
#ifndef __REGISTER_PREFIX__
|
||||
#define __REGISTER_PREFIX__ /* never has anything prefixed */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* some assemblers choke on '#' as an immediate value. As gcc can also
|
||||
* use '&', use that in those cases.
|
||||
*/
|
||||
#ifndef __IMMEDIATE_PREFIX__
|
||||
#define __IMMEDIATE_PREFIX__ #
|
||||
#endif
|
||||
|
||||
/* ANSI concatenation macros. */
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* use the right prefix for global labels. */
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__,x)
|
||||
|
||||
/* use the right prefix for registers. */
|
||||
#define REG(x) CONCAT1 (__REGISTER_PREFIX__,x)
|
||||
|
||||
/* use the right prefix for immediate values. */
|
||||
#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__,x)
|
||||
|
||||
/* use the right prefix for register names */
|
||||
#define d0 REG (d0)
|
||||
#define d1 REG (d1)
|
||||
#define d2 REG (d2)
|
||||
#define d3 REG (d3)
|
||||
#define d4 REG (d4)
|
||||
#define d5 REG (d5)
|
||||
#define d6 REG (d6)
|
||||
#define d7 REG (d7)
|
||||
#define a0 REG (a0)
|
||||
#define a1 REG (a1)
|
||||
#define a2 REG (a2)
|
||||
#define a3 REG (a3)
|
||||
#define a4 REG (a4)
|
||||
#define a5 REG (a5)
|
||||
#define a6 REG (a6)
|
||||
#define a7 REG (a7)
|
||||
#define fp REG (fp)
|
||||
#define fp0 REG (fp0)
|
||||
#define fp1 REG (fp1)
|
||||
#define fp2 REG (fp2)
|
||||
#define fp3 REG (fp3)
|
||||
#define fp4 REG (fp4)
|
||||
#define fp5 REG (fp5)
|
||||
#define fp6 REG (fp6)
|
||||
#define fp7 REG (fp7)
|
||||
#define sp REG (sp)
|
||||
#define usp REG (usp)
|
||||
#define vbr REG (vbr)
|
||||
#define sr REG (sr)
|
||||
#define fpcr REG (fpcr)
|
||||
#define fpsr REG (fpsr)
|
||||
#define fpi REG (fpi)
|
127
libgloss/m68k/bcc.ld
Normal file
127
libgloss/m68k/bcc.ld
Normal file
@ -0,0 +1,127 @@
|
||||
STARTUP(crt0.o)
|
||||
OUTPUT_ARCH(m68k)
|
||||
/* Uncomment this if you want srecords. This is needed for a.out
|
||||
* if you plan to use GDB.
|
||||
OUTPUT_FORMAT(srec)
|
||||
*/
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lbcc -lc -lgcc)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*
|
||||
* Setup the memory map of the M68332BCC Business Card Computer.
|
||||
* stack grows down from high memory.
|
||||
*
|
||||
* The memory map look like this:
|
||||
* +--------------------+ <- low memory
|
||||
* | .text |
|
||||
* | _etext |
|
||||
* | ctor list | the ctor and dtor lists are for
|
||||
* | dtor list | C++ support
|
||||
* +--------------------+
|
||||
* | .data | initialized data goes here
|
||||
* | _edata |
|
||||
* +--------------------+
|
||||
* | .bss |
|
||||
* | __bss_start | start of bss, cleared by crt0
|
||||
* | _end | start of heap, used by sbrk()
|
||||
* +--------------------+
|
||||
* . .
|
||||
* . .
|
||||
* . .
|
||||
* | __stack | top of stack
|
||||
* +--------------------+
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x3000, LENGTH = 0xd000
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate the stack to be at the top of memory, since the stack
|
||||
* grows down
|
||||
*/
|
||||
|
||||
PROVIDE (__stack = 0xd000);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/*
|
||||
* stick everything in ram (of course)
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
. = ALIGN(0x4);
|
||||
__CTOR_LIST__ = .;
|
||||
___CTOR_LIST__ = .;
|
||||
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
|
||||
*(.ctors)
|
||||
LONG(0)
|
||||
__CTOR_END__ = .;
|
||||
__DTOR_LIST__ = .;
|
||||
___DTOR_LIST__ = .;
|
||||
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
|
||||
*(.dtors)
|
||||
LONG(0)
|
||||
__DTOR_END__ = .;
|
||||
*(.rodata)
|
||||
*(.gcc_except_table)
|
||||
|
||||
. = ALIGN(0x2);
|
||||
__INIT_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.init)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
__FINI_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.fini)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
_etext = .;
|
||||
*(.lit)
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.shdata)
|
||||
*(.data)
|
||||
_edata = .;
|
||||
} > ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
__bss_start = . ;
|
||||
*(.shbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end = ALIGN (0x8);
|
||||
__end = _end;
|
||||
} > ram
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
}
|
1118
libgloss/m68k/configure
vendored
Executable file
1118
libgloss/m68k/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
68
libgloss/m68k/configure.in
Normal file
68
libgloss/m68k/configure.in
Normal file
@ -0,0 +1,68 @@
|
||||
# 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.
|
||||
#
|
||||
# process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ(2.5)dnl
|
||||
AC_INIT(crt0.S)
|
||||
|
||||
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_CANONICAL_SYSTEM
|
||||
AC_ARG_PROGRAM
|
||||
|
||||
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
|
||||
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_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}
|
||||
)
|
||||
|
118
libgloss/m68k/cpu32bug.S
Normal file
118
libgloss/m68k/cpu32bug.S
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* cpu32bug.S -- board support for the CPU32BUG monitor.
|
||||
*
|
||||
* 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"
|
||||
#include "cpu32bug.h"
|
||||
|
||||
.title "cpu32bug.S for m68k-coff"
|
||||
|
||||
.text
|
||||
.global SYM (_exit)
|
||||
.global SYM (outln)
|
||||
.global SYM (outbyte)
|
||||
.global SYM (putDebugChar)
|
||||
.global SYM (inbyte)
|
||||
.global SYM (getDebugChar)
|
||||
.global SYM (havebyte)
|
||||
|
||||
/*
|
||||
* _exit -- Exit from the application. Normally we cause a user trap
|
||||
* to return to the ROM monitor for another run.
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (_exit):
|
||||
link fp, IMM(0)
|
||||
trap IMM(15)
|
||||
.word RETURN
|
||||
|
||||
/*
|
||||
* inbyte -- get a byte from the serial port
|
||||
* d0 - contains the byte read in
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (getDebugChar): /* symbol name used by m68k-stub */
|
||||
SYM (inbyte):
|
||||
link fp, IMM(-8)
|
||||
trap IMM(15)
|
||||
.word INCHR
|
||||
moveb sp@, d0
|
||||
extw d0
|
||||
extl d0
|
||||
unlk fp
|
||||
rts
|
||||
|
||||
/*
|
||||
* outbyte -- sends a byte out the serial port
|
||||
* d0 - contains the byte to be sent
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (putDebugChar): /* symbol name used by m68k-stub */
|
||||
SYM (outbyte):
|
||||
link fp, IMM(-4)
|
||||
moveb fp@(11), sp@
|
||||
trap IMM(15)
|
||||
.word OUTCHR
|
||||
unlk fp
|
||||
rts
|
||||
|
||||
/*
|
||||
* outln -- sends a string of bytes out the serial port with a CR/LF
|
||||
* a0 - contains the address of the string's first byte
|
||||
* a1 - contains the address of the string's last byte
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (outln):
|
||||
link fp, IMM(-8)
|
||||
moveml a0/a1, sp@
|
||||
trap IMM(15)
|
||||
.word OUTLN
|
||||
unlk fp
|
||||
rts
|
||||
|
||||
/*
|
||||
* outstr -- sends a string of bytes out the serial port without a CR/LF
|
||||
* a0 - contains the address of the string's first byte
|
||||
* a1 - contains the address of the string's last byte
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (outstr):
|
||||
link fp, IMM(-8)
|
||||
moveml a0/a1, sp@
|
||||
trap IMM(15)
|
||||
.word OUTSTR
|
||||
unlk fp
|
||||
rts
|
||||
|
||||
/*
|
||||
* havebyte -- checks to see if there is a byte in the serial port,
|
||||
* returns 1 if there is a byte, 0 otherwise.
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (havebyte):
|
||||
trap IMM(15)
|
||||
.word INSTAT
|
||||
beqs empty
|
||||
movel IMM(1), d0
|
||||
rts
|
||||
empty:
|
||||
movel IMM(0), d0
|
||||
rts
|
35
libgloss/m68k/cpu32bug.h
Normal file
35
libgloss/m68k/cpu32bug.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* These constants are for the M68332BCC's boot monitor. They
|
||||
* are used with a TRAP 15 call to access the monitor's I/O routines.
|
||||
* they must be in the word following the trap call.
|
||||
*/
|
||||
INCHR=0X0
|
||||
INSTAT=0X1
|
||||
INLN=0X2
|
||||
READSTR=0X3
|
||||
READLN=0X4
|
||||
CHKBRK=0X5
|
||||
|
||||
OUTCHR=0X20
|
||||
OUTSTR=0X21
|
||||
OUTLN=0X22
|
||||
WRITE=0X23
|
||||
WRITELN=0X24
|
||||
WRITDLN=0X25
|
||||
PCRLF=0X26
|
||||
ERASELN=0X27
|
||||
WRITD=0X28
|
||||
SNDBRK=0X29
|
||||
|
||||
TM_INI=0X40
|
||||
TM_STR0=0X41
|
||||
TM_RD=0X42
|
||||
DELAY=0X43
|
||||
|
||||
RETURN=0X63
|
||||
BINDEC=0X64
|
||||
|
||||
CHANGEV=0X67
|
||||
STRCMP=0X68
|
||||
MULU32=0X69
|
||||
DIVU32=0X6A
|
143
libgloss/m68k/crt0.S
Normal file
143
libgloss/m68k/crt0.S
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* crt0.S -- startup file for m68k-coff
|
||||
*
|
||||
* 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"
|
||||
|
||||
.title "crt0.S for m68k-coff"
|
||||
#define STACKSIZE 0x4000
|
||||
|
||||
/*
|
||||
* Define an empty environment.
|
||||
*/
|
||||
.data
|
||||
.align 2
|
||||
SYM (environ):
|
||||
.long 0
|
||||
|
||||
.align 2
|
||||
.text
|
||||
|
||||
/*
|
||||
* These symbols are defined in C code, so they need to always be
|
||||
* named with SYM because of the difference between object file formats.
|
||||
*/
|
||||
|
||||
/* These are defined in C code. */
|
||||
.extern SYM (main)
|
||||
.extern SYM (exit)
|
||||
.extern SYM (hardware_init_hook)
|
||||
.extern SYM (software_init_hook)
|
||||
.extern SYM (atexit)
|
||||
.extern SYM(__do_global_dtors)
|
||||
|
||||
/*
|
||||
* These values are set in the linker script, so they must be
|
||||
* explicitly named here without SYM.
|
||||
*/
|
||||
.extern __stack
|
||||
.extern __bss_start
|
||||
.extern _end
|
||||
|
||||
/*
|
||||
* set things up so the application will run. This *must* be called start.
|
||||
*/
|
||||
.global SYM (start)
|
||||
|
||||
SYM (start):
|
||||
/*
|
||||
* put any hardware init code here
|
||||
*/
|
||||
|
||||
/* See if user supplied their own stack (__stack != 0). If not, then
|
||||
* default to using the value of %sp as set by the ROM monitor.
|
||||
*/
|
||||
movel IMM(__stack), a0
|
||||
cmpl IMM(0), a0
|
||||
jbeq 1f
|
||||
movel a0, sp
|
||||
1:
|
||||
/* set up initial stack frame */
|
||||
link a6, IMM(-8)
|
||||
|
||||
/*
|
||||
* zero out the bss section.
|
||||
*/
|
||||
movel IMM(__bss_start), d1
|
||||
movel IMM(_end), d0
|
||||
cmpl d0, d1
|
||||
jbeq 3f
|
||||
movl d1, a0
|
||||
subl d1, d0
|
||||
subql IMM(1), d0
|
||||
2:
|
||||
clrb (a0)+
|
||||
#ifndef __mcf5200__
|
||||
dbra d0, 2b
|
||||
clrw d0
|
||||
subql IMM(1), d0
|
||||
jbcc 2b
|
||||
#else
|
||||
subql IMM(1), d0
|
||||
jbpl 2b
|
||||
#endif
|
||||
|
||||
3:
|
||||
|
||||
/*
|
||||
* initialize target specific stuff. Only execute these
|
||||
* functions it they exist.
|
||||
*/
|
||||
lea SYM (hardware_init_hook), a0
|
||||
cmpl IMM(0),a0
|
||||
jbeq 4f
|
||||
jsr (a0)
|
||||
4:
|
||||
|
||||
lea SYM (software_init_hook), a0
|
||||
cmpl IMM(0),a0
|
||||
jbeq 5f
|
||||
jsr (a0)
|
||||
5:
|
||||
|
||||
/*
|
||||
* call the main routine from the application to get it going.
|
||||
* main (argc, argv, environ)
|
||||
* we pass argv as a pointer to NULL.
|
||||
*/
|
||||
|
||||
#ifdef ADD_DTORS
|
||||
/* put __do_global_dtors in the atexit list so the destructors get run */
|
||||
movel IMM (SYM(__do_global_dtors)),(sp)
|
||||
jsr SYM (atexit)
|
||||
#endif
|
||||
movel IMM (__FINI_SECTION__),(sp)
|
||||
jsr SYM (atexit)
|
||||
|
||||
jsr __INIT_SECTION__
|
||||
|
||||
pea 0
|
||||
pea SYM (environ)
|
||||
pea sp@(4)
|
||||
pea 0
|
||||
jsr SYM (main)
|
||||
movel d0, sp@-
|
||||
|
||||
/*
|
||||
* drop down into exit incase the user doesn't. This should drop
|
||||
* control back to the ROM monitor, if there is one. This calls the
|
||||
* exit() from the C library so the C++ tables get cleaned up right.
|
||||
*/
|
||||
jsr SYM (exit)
|
29
libgloss/m68k/dbug-exit.S
Normal file
29
libgloss/m68k/dbug-exit.S
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* dbug-exit.S --
|
||||
*
|
||||
* 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 "asm.h"
|
||||
|
||||
.text
|
||||
.global SYM (_exit)
|
||||
/*
|
||||
* _exit -- Exit from the application. Normally we cause a user trap
|
||||
* to return to the ROM monitor for another run.
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (_exit):
|
||||
moveql IMM(0),d0
|
||||
trap IMM(15)
|
34
libgloss/m68k/dbug-inbyte.S
Normal file
34
libgloss/m68k/dbug-inbyte.S
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* dbug-inbyte.S --
|
||||
*
|
||||
* 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 "asm.h"
|
||||
|
||||
.text
|
||||
.global SYM (inbyte)
|
||||
.global SYM (getDebugChar)
|
||||
|
||||
/*
|
||||
* inbyte -- get a byte from the serial port
|
||||
* d0 - contains the byte read in
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (getDebugChar): /* symbol name used by m68k-stub */
|
||||
SYM (inbyte):
|
||||
movel IMM(0x10),d0
|
||||
trap IMM(15)
|
||||
movel d1,d0
|
||||
rts
|
34
libgloss/m68k/dbug-outbyte.S
Normal file
34
libgloss/m68k/dbug-outbyte.S
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* dbug-outbyte.S --
|
||||
*
|
||||
* 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 "asm.h"
|
||||
|
||||
.text
|
||||
.global SYM (outbyte)
|
||||
.global SYM (putDebugChar)
|
||||
|
||||
/*
|
||||
* outbyte -- sends a byte out the serial port
|
||||
* d0 - contains the byte to be sent
|
||||
*/
|
||||
.text
|
||||
.align 2
|
||||
SYM (putDebugChar): /* symbol name used by m68k-stub */
|
||||
SYM (outbyte):
|
||||
movel sp@(4),d1
|
||||
movl IMM(0x13),d0
|
||||
trap IMM(15)
|
||||
rts
|
25
libgloss/m68k/dtor.C
Normal file
25
libgloss/m68k/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);
|
||||
}
|
41
libgloss/m68k/idp-inbyte.c
Normal file
41
libgloss/m68k/idp-inbyte.c
Normal file
@ -0,0 +1,41 @@
|
||||
/* idp-inbyte.c --
|
||||
* Copyright (c) 1995 Cygnus Support
|
||||
*
|
||||
* The authors hereby grant permission to use, copy, modify, distribute,
|
||||
* and license this software and its documentation for any purpose, provided
|
||||
* that existing copyright notices are retained in all copies and that this
|
||||
* notice is included verbatim in any distributions. No written agreement,
|
||||
* license, or royalty fee is required for any of the authorized uses.
|
||||
* Modifications to this software may be copyrighted by their authors
|
||||
* and need not follow the licensing terms described here, provided that
|
||||
* the new terms are clearly indicated on the first page of each file where
|
||||
* they apply.
|
||||
*/
|
||||
|
||||
#include <_ansi.h>
|
||||
#include "mc68681reg.h"
|
||||
|
||||
/*
|
||||
* The DUART is mapped into the IDP address space in an unusual
|
||||
* manner. The mc68681 is an 8 bit device located on the least
|
||||
* significant byte (byte0) of the data bus. Bytes 3, 2, and
|
||||
* one have nothing in them and writes to these locations are
|
||||
* not valid.
|
||||
*/
|
||||
|
||||
#define DUART_ADDR 0x00B00000
|
||||
#define READREG(x) (*((volatile char *) DUART_ADDR + (x * 4) + 3))
|
||||
#define WRITEREG(x, y) (*((char *) DUART_ADDR + (x * 4) + 3) = y)
|
||||
|
||||
/*
|
||||
* inbyte -- get a byte from the DUART RX buffer. This only reads
|
||||
* from channel A
|
||||
*/
|
||||
char
|
||||
_DEFUN_VOID (inbyte)
|
||||
{
|
||||
while ((READREG (DUART_SRA) & 0x01) == 0x00)
|
||||
;
|
||||
|
||||
return (READREG (DUART_RBA)); /* read the byte */
|
||||
}
|
42
libgloss/m68k/idp-outbyte.c
Normal file
42
libgloss/m68k/idp-outbyte.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* idp-outbyte.c
|
||||
* Copyright (c) 1995 Cygnus Support
|
||||
*
|
||||
* The authors hereby grant permission to use, copy, modify, distribute,
|
||||
* and license this software and its documentation for any purpose, provided
|
||||
* that existing copyright notices are retained in all copies and that this
|
||||
* notice is included verbatim in any distributions. No written agreement,
|
||||
* license, or royalty fee is required for any of the authorized uses.
|
||||
* Modifications to this software may be copyrighted by their authors
|
||||
* and need not follow the licensing terms described here, provided that
|
||||
* the new terms are clearly indicated on the first page of each file where
|
||||
* they apply.
|
||||
*/
|
||||
|
||||
#include <_ansi.h>
|
||||
#include "mc68681reg.h"
|
||||
|
||||
/*
|
||||
* The DUART is mapped into the IDP address space in an unusual
|
||||
* manner. The mc68681 is an 8 bit device located on the least
|
||||
* significant byte (byte0) of the data bus. Bytes 3, 2, and
|
||||
* one have nothing in them and writes to these locations are
|
||||
* not valid.
|
||||
*/
|
||||
|
||||
#define DUART_ADDR 0x00B00000
|
||||
#define READREG(x) (*((volatile char *) DUART_ADDR + (x * 4) + 3))
|
||||
#define WRITEREG(x, y) (*((char *) DUART_ADDR + (x * 4) + 3) = y)
|
||||
|
||||
/*
|
||||
* outbyte -- send a byte to the DUART buffer. This only sends
|
||||
* to channel A.
|
||||
*/
|
||||
void
|
||||
_DEFUN (outbyte, (byte),
|
||||
char byte)
|
||||
{
|
||||
while ((READREG (DUART_SRA) & 0x04) == 0x00)
|
||||
;
|
||||
|
||||
WRITEREG (DUART_TBA, byte); /* write the byte */
|
||||
}
|
146
libgloss/m68k/idp.ld
Normal file
146
libgloss/m68k/idp.ld
Normal file
@ -0,0 +1,146 @@
|
||||
STARTUP(crt0.o)
|
||||
OUTPUT_ARCH(m68k)
|
||||
/* Uncomment this if you want srecords. This is needed for a.out
|
||||
* if you plan to use GDB.
|
||||
OUTPUT_FORMAT(srec)
|
||||
*/
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lidp -lc -lgcc)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*
|
||||
* Setup the memory map of the MC68ec0x0 Board (IDP)
|
||||
* stack grows down from high memory. This works for
|
||||
* both the rom68k and the mon68k monitors.
|
||||
*
|
||||
* The memory map look like this:
|
||||
* +--------------------+ <- low memory
|
||||
* | .text |
|
||||
* | _etext |
|
||||
* | ctor list | the ctor and dtor lists are for
|
||||
* | dtor list | C++ support
|
||||
* +--------------------+
|
||||
* | .data | initialized data goes here
|
||||
* | _edata |
|
||||
* +--------------------+
|
||||
* | .bss |
|
||||
* | __bss_start | start of bss, cleared by crt0
|
||||
* | _end | start of heap, used by sbrk()
|
||||
* +--------------------+
|
||||
* . .
|
||||
* . .
|
||||
* . .
|
||||
* | __stack | top of stack
|
||||
* +--------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
* When the IDP is not remapped (see rom68k's MP command in the
|
||||
* "M68EC0x0IDP Users Manual", the first 64K bytes are reserved;
|
||||
* Otherwise the first 256K bytes are reserved.
|
||||
*
|
||||
* The following memory map describes a unmapped IDP w/2MB RAM.
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x00010000, LENGTH = 2M-64K
|
||||
rom0 : ORIGIN = 0x00800000, LENGTH = 1M
|
||||
rom1 : ORIGIN = 0x00900000, LENGTH = 1M
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate the stack to be at the top of memory, since the stack
|
||||
* grows down
|
||||
*/
|
||||
|
||||
PROVIDE (__stack = 2M - 8);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/*
|
||||
* stick everything in ram (of course)
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
*(.text)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
/* These are for running static constructors and destructors under ELF. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
|
||||
*(.rodata)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
*(.gcc_except_table)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
*(.eh_frame)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
__INIT_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.init)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
. = ALIGN(0x4);
|
||||
__FINI_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.fini)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
_etext = .;
|
||||
*(.lit)
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.shdata)
|
||||
*(.data)
|
||||
_edata = .;
|
||||
} > ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
__bss_start = . ;
|
||||
*(.shbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end = ALIGN (0x8);
|
||||
__end = _end;
|
||||
} > ram
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
}
|
81
libgloss/m68k/leds.c
Normal file
81
libgloss/m68k/leds.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* leds.c -- control the led's on a Motorola mc68ec0x0 board.
|
||||
*
|
||||
* 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 "leds.h"
|
||||
|
||||
void zylons();
|
||||
void led_putnum();
|
||||
|
||||
/*
|
||||
* led_putnum -- print a hex number on the LED. the value of num must be a char with
|
||||
* the ascii value. ie... number 0 is '0', a is 'a', ' ' (null) clears
|
||||
* the led display.
|
||||
* Setting the bit to 0 turns it on, 1 turns it off.
|
||||
* the LED's are controlled by setting the right bit mask in the base
|
||||
* address.
|
||||
* The bits are:
|
||||
* [d.p | g | f | e | d | c | b | a ] is the byte.
|
||||
*
|
||||
* The locations are:
|
||||
*
|
||||
* a
|
||||
* -----
|
||||
* f | | b
|
||||
* | g |
|
||||
* -----
|
||||
* | |
|
||||
* e | | c
|
||||
* -----
|
||||
* d . d.p (decimal point)
|
||||
*/
|
||||
void
|
||||
led_putnum ( num )
|
||||
char num;
|
||||
{
|
||||
static unsigned char *leds = (unsigned char *)LED_ADDR;
|
||||
static unsigned char num_bits [18] = {
|
||||
0xff, /* clear all */
|
||||
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, /* numbers 0-9 */
|
||||
0x98, 0x20, 0x3, 0x27, 0x21, 0x4, 0xe /* letters a-f */
|
||||
};
|
||||
|
||||
if (num >= '0' && num <= '9')
|
||||
num = (num - '0') + 1;
|
||||
|
||||
if (num >= 'a' && num <= 'f')
|
||||
num = (num - 'a') + 12;
|
||||
|
||||
if (num == ' ')
|
||||
num = 0;
|
||||
|
||||
*leds = num_bits[num];
|
||||
}
|
||||
|
||||
/*
|
||||
* zylons -- draw a rotating pattern. NOTE: this function never returns.
|
||||
*/
|
||||
void
|
||||
zylons()
|
||||
{
|
||||
unsigned char *leds = (unsigned char *)LED_ADDR;
|
||||
unsigned char curled = 0xfe;
|
||||
|
||||
while (1)
|
||||
{
|
||||
*leds = curled;
|
||||
curled = (curled >> 1) | (curled << 7);
|
||||
delay ( 200 );
|
||||
}
|
||||
}
|
36
libgloss/m68k/leds.h
Normal file
36
libgloss/m68k/leds.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* leds.c -- control the led's on a Motorola mc68ec0x0 board.
|
||||
* Written by rob@cygnus.com (Rob Savoye)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __LEDS_H__
|
||||
#define __LEDS_H__
|
||||
|
||||
#define LED_ADDR 0xd00003
|
||||
#define LED_0 ~0x1
|
||||
#define LED_1 ~0x2
|
||||
#define LED_2 ~0x4
|
||||
#define LED_3 ~0x8
|
||||
#define LED_4 ~0x10
|
||||
#define LED_5 ~0x20
|
||||
#define LED_6 ~0x40
|
||||
#define LED_7 ~0x80
|
||||
#define LEDS_OFF 0xff
|
||||
#define LEDS_ON 0x0
|
||||
|
||||
#define FUDGE(x) ((x >= 0xa && x <= 0xf) ? (x + 'a') & 0x7f : (x + '0') & 0x7f)
|
||||
|
||||
extern void led_putnum( char );
|
||||
|
||||
#endif /* __LEDS_H__ */
|
43
libgloss/m68k/mc68681reg.h
Normal file
43
libgloss/m68k/mc68681reg.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* mc68681reg.h -- Motorola mc68681 DUART register offsets.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define DUART_MR1A 0x00 /* Mode Register A */
|
||||
#define DUART_MR1A 0x00 /* Mode Register A */
|
||||
#define DUART_SRA 0x01 /* Status Register A */
|
||||
#define DUART_CSRA 0x01 /* Clock-Select Register A */
|
||||
#define DUART_CRA 0x02 /* Command Register A */
|
||||
#define DUART_RBA 0x03 /* Receive Buffer A */
|
||||
#define DUART_TBA 0x03 /* Transmit Buffer A */
|
||||
#define DUART_IPCR 0x04 /* Input Port Change Register */
|
||||
#define DUART_ACR 0x04 /* Auxiliary Control Register */
|
||||
#define DUART_ISR 0x05 /* Interrupt Status Register */
|
||||
#define DUART_IMR 0x05 /* Interrupt Mask Register */
|
||||
#define DUART_CUR 0x06 /* Counter Mode: current MSB */
|
||||
#define DUART_CTUR 0x06 /* Counter/Timer upper reg */
|
||||
#define DUART_CLR 0x07 /* Counter Mode: current LSB */
|
||||
#define DUART_CTLR 0x07 /* Counter/Timer lower reg */
|
||||
#define DUART_MR1B 0x08 /* Mode Register B */
|
||||
#define DUART_MR2B 0x08 /* Mode Register B */
|
||||
#define DUART_SRB 0x09 /* Status Register B */
|
||||
#define DUART_CSRB 0x09 /* Clock-Select Register B */
|
||||
#define DUART_CRB 0x0A /* Command Register B */
|
||||
#define DUART_RBB 0x0B /* Receive Buffer B */
|
||||
#define DUART_TBB 0x0B /* Transmit Buffer A */
|
||||
#define DUART_IVR 0x0C /* Interrupt Vector Register */
|
||||
#define DUART_IP 0x0D /* Input Port */
|
||||
#define DUART_OPCR 0x0D /* Output Port Configuration Reg. */
|
||||
#define DUART_STRTCC 0x0E /* Start-Counter command */
|
||||
#define DUART_OPRSET 0x0E /* Output Port Reg, SET bits */
|
||||
#define DUART_STOPCC 0x0F /* Stop-Counter command */
|
||||
#define DUART_OPRRST 0x0F /* Output Port Reg, ReSeT bits */
|
48
libgloss/m68k/mc68ec.c
Normal file
48
libgloss/m68k/mc68ec.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* mc68ec.c -- Low level support for the Motorola mc68ec0x0 board.
|
||||
* Written by rob@cygnus.com (Rob Savoye)
|
||||
*
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <_ansi.h>
|
||||
#include <errno.h>
|
||||
#include "leds.h"
|
||||
|
||||
/*
|
||||
* _exit -- exit the running program. We just cause an exception
|
||||
* which makes the program return to the boot monitor
|
||||
* prompt. It can be restarted from there.
|
||||
*/
|
||||
void
|
||||
_DEFUN (_exit, (status),
|
||||
int_status)
|
||||
{
|
||||
/* Use `i' constraint to get proper immediate-operand syntax for
|
||||
target assembler configuration. */
|
||||
asm ("trap %0" : : "i" (0)); /* seems to be a harmless vector number */
|
||||
}
|
||||
|
||||
/*
|
||||
* delay -- delay execution. This is an ugly hack. It should
|
||||
* use the timer, but I'm waiting for docs. (sigh)
|
||||
*/
|
||||
void
|
||||
_DEFUN (delay, (num),
|
||||
int num)
|
||||
{
|
||||
while (num--)
|
||||
{
|
||||
asm ("nop");
|
||||
}
|
||||
}
|
734
libgloss/m68k/mvme-stub.c
Normal file
734
libgloss/m68k/mvme-stub.c
Normal file
@ -0,0 +1,734 @@
|
||||
unsigned long sp_ptr;
|
||||
unsigned long pc_ptr;
|
||||
int cnt;
|
||||
#define UNWIND asm ("movel %/sp, %0" : "=g" (sp_ptr));\
|
||||
printf ("\n\t\t== Starting at 0x%x ==\n", sp_ptr);\
|
||||
for (cnt=4; cnt <=32; cnt+=4) {\
|
||||
printf ("+%d(0x%x): 0x%x\t\t-%d(0x%x): 0x%x\n",\
|
||||
cnt, (sp_ptr + cnt), *(unsigned long *)(sp_ptr + cnt),\
|
||||
cnt, (sp_ptr - cnt), *(unsigned long *)(sp_ptr - cnt)\
|
||||
); }; fflush (stdout);
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
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 $
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Some explanation is probably necessary to explain how exceptions are
|
||||
* handled. When an exception is encountered the 68000 pushes the current
|
||||
* program counter and status register onto the supervisor stack and then
|
||||
* transfers execution to a location specified in it's vector table.
|
||||
* The handlers for the exception vectors are hardwired to jmp to an address
|
||||
* given by the relation: (exception - 256) * 6. These are decending
|
||||
* addresses starting from -6, -12, -18, ... By allowing 6 bytes for
|
||||
* each entry, a jsr, jmp, bsr, ... can be used to enter the exception
|
||||
* handler. Using a jsr to handle an exception has an added benefit of
|
||||
* allowing a single handler to service several exceptions and use the
|
||||
* return address as the key differentiation. The vector number can be
|
||||
* computed from the return address by [ exception = (addr + 1530) / 6 ].
|
||||
* The sole purpose of the routine _catchException is to compute the
|
||||
* exception number and push it on the stack in place of the return address.
|
||||
* The external function exceptionHandler() is
|
||||
* used to attach a specific handler to a specific 68k exception.
|
||||
* For 68020 machines, the ability to have a return address around just
|
||||
* so the vector can be determined is not necessary because the '020 pushes an
|
||||
* extra word onto the stack containing the vector offset
|
||||
*
|
||||
* Because gdb will sometimes write to the stack area to execute function
|
||||
* calls, this program cannot rely on using the supervisor stack so it
|
||||
* uses it's own stack area reserved in the int array remcomStack.
|
||||
*
|
||||
*************
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
#include <_ansi.h>
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* external low-level support routines
|
||||
*/
|
||||
typedef void (*ExceptionHook)(int); /* pointer to function with int parm */
|
||||
typedef void (*Function)(); /* pointer to a function */
|
||||
|
||||
extern int putDebugChar(); /* write a single character */
|
||||
extern char getDebugChar(); /* read and return a single char */
|
||||
|
||||
ExceptionHook exceptionHook; /* hook variable for errors/exceptions */
|
||||
|
||||
/************************/
|
||||
/* FORWARD DECLARATIONS */
|
||||
/************************/
|
||||
/** static void initializeRemcomErrorFrame PARAMS ((void)); **/
|
||||
static void _DEFUN_VOID (initializeRemcomErrorFrame);
|
||||
|
||||
/************************************************************************/
|
||||
/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
|
||||
/* at least NUMREGBYTES*2 are needed for register packets */
|
||||
#define BUFMAX 400
|
||||
|
||||
static char initialized; /* boolean flag. != 0 means we've been initialized */
|
||||
|
||||
int remote_debug = 0; /*** Robs Thu Sep 24 22:18:51 PDT 1992 ***/
|
||||
/* debug > 0 prints ill-formed commands in valid packets & checksum errors */
|
||||
|
||||
static const char hexchars[]="0123456789abcdef";
|
||||
|
||||
/* there are 180 bytes of registers on a 68020 w/68881 */
|
||||
/* many of the fpa registers are 12 byte (96 bit) registers */
|
||||
#define NUMREGBYTES 180
|
||||
enum regnames {D0,D1,D2,D3,D4,D5,D6,D7,
|
||||
A0,A1,A2,A3,A4,A5,A6,A7,
|
||||
PS,PC,
|
||||
FP0,FP1,FP2,FP3,FP4,FP5,FP6,FP7,
|
||||
FPCONTROL,FPSTATUS,FPIADDR
|
||||
};
|
||||
|
||||
typedef struct FrameStruct
|
||||
{
|
||||
struct FrameStruct *previous;
|
||||
int exceptionPC; /* pc value when this frame created */
|
||||
int exceptionVector; /* cpu vector causing exception */
|
||||
short frameSize; /* size of cpu frame in words */
|
||||
short sr; /* for 68000, this not always sr */
|
||||
int pc;
|
||||
short format;
|
||||
int fsaveHeader;
|
||||
int morejunk[0]; /* exception frame, fp save... */
|
||||
} Frame;
|
||||
|
||||
#define FRAMESIZE 500
|
||||
int gdbFrameStack[FRAMESIZE];
|
||||
Frame *lastFrame;
|
||||
|
||||
/*
|
||||
* these should not be static cuz they can be used outside this module
|
||||
*/
|
||||
int registers[NUMREGBYTES/4];
|
||||
int superStack;
|
||||
|
||||
#define STACKSIZE 10000
|
||||
int remcomStack[STACKSIZE/sizeof(int)];
|
||||
int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
|
||||
|
||||
/*
|
||||
* In many cases, the system will want to continue exception processing
|
||||
* when a continue command is given.
|
||||
* oldExceptionHook is a function to invoke in this case.
|
||||
*/
|
||||
|
||||
static ExceptionHook oldExceptionHook;
|
||||
|
||||
/* the size of the exception stack on the 68020 varies with the type of
|
||||
* exception. The following table is the number of WORDS used
|
||||
* for each exception format.
|
||||
*/
|
||||
const short exceptionSize[] = { 4,4,6,4,4,4,4,4,29,10,16,46,12,4,4,4 };
|
||||
|
||||
/************* jump buffer used for setjmp/longjmp **************************/
|
||||
jmp_buf remcomEnv;
|
||||
|
||||
#define BREAKPOINT() asm(" trap #1");
|
||||
|
||||
extern void _DEFUN_VOID (return_to_super);
|
||||
extern void _DEFUN_VOID (return_to_user);
|
||||
extern void _DEFUN_VOID (_catchException);
|
||||
|
||||
void _returnFromException( Frame *frame )
|
||||
{
|
||||
/* if no passed in frame, use the last one */
|
||||
if (! frame)
|
||||
{
|
||||
frame = lastFrame;
|
||||
frame->frameSize = 4;
|
||||
frame->format = 0;
|
||||
frame->fsaveHeader = -1; /* restore regs, but we dont have fsave info*/
|
||||
}
|
||||
|
||||
#ifndef mc68020
|
||||
/* a 68000 cannot use the internal info pushed onto a bus error
|
||||
* or address error frame when doing an RTE so don't put this info
|
||||
* onto the stack or the stack will creep every time this happens.
|
||||
*/
|
||||
frame->frameSize=3;
|
||||
#endif
|
||||
|
||||
/* throw away any frames in the list after this frame */
|
||||
lastFrame = frame;
|
||||
|
||||
frame->sr = registers[(int) PS];
|
||||
frame->pc = registers[(int) PC];
|
||||
|
||||
if (registers[(int) PS] & 0x2000)
|
||||
{
|
||||
/* return to supervisor mode... */
|
||||
return_to_super();
|
||||
}
|
||||
else
|
||||
{ /* return to user mode */
|
||||
return_to_user();
|
||||
}
|
||||
}
|
||||
|
||||
int hex(ch)
|
||||
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> */
|
||||
void getpacket(buffer)
|
||||
char * buffer;
|
||||
{
|
||||
unsigned char checksum;
|
||||
unsigned char xmitcsum;
|
||||
int i;
|
||||
int count;
|
||||
char ch;
|
||||
|
||||
if (remote_debug) {
|
||||
printf("\nGETPACKET: sr=0x%x, pc=0x%x, sp=0x%x\n",
|
||||
registers[ PS ],
|
||||
registers[ PC ],
|
||||
registers[ A7 ]
|
||||
); fflush (stdout);
|
||||
UNWIND
|
||||
}
|
||||
|
||||
do {
|
||||
/* wait around for the start character, ignore all other characters */
|
||||
while ((ch = getDebugChar()) != '$');
|
||||
checksum = 0;
|
||||
xmitcsum = -1;
|
||||
|
||||
count = 0;
|
||||
|
||||
/* now, read until a # or end of buffer is found */
|
||||
while (count < BUFMAX) {
|
||||
ch = getDebugChar();
|
||||
if (ch == '#') break;
|
||||
checksum = checksum + ch;
|
||||
buffer[count] = ch;
|
||||
count = count + 1;
|
||||
}
|
||||
buffer[count] = 0;
|
||||
|
||||
if (ch == '#') {
|
||||
xmitcsum = hex(getDebugChar()) << 4;
|
||||
xmitcsum += hex(getDebugChar());
|
||||
if ((remote_debug ) && (checksum != xmitcsum)) {
|
||||
fprintf(stderr,"bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n",
|
||||
checksum,xmitcsum,buffer);
|
||||
}
|
||||
|
||||
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. The host get's one chance to read it.
|
||||
This routine does not wait for a positive acknowledge. */
|
||||
|
||||
void putpacket(buffer)
|
||||
char * buffer;
|
||||
{
|
||||
unsigned char checksum;
|
||||
int count;
|
||||
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 % 16]);
|
||||
|
||||
if (remote_debug) {
|
||||
printf("\nPUTPACKET: sr=0x%x, pc=0x%x, sp=0x%x\n",
|
||||
registers[ PS ],
|
||||
registers[ PC ],
|
||||
registers[ A7 ]
|
||||
); fflush (stdout);
|
||||
UNWIND
|
||||
}
|
||||
|
||||
/*** } while (getDebugChar() != '+'); ***/
|
||||
/** } while (1 == 0); (getDebugChar() != '+'); **/
|
||||
|
||||
}
|
||||
|
||||
char remcomInBuffer[BUFMAX];
|
||||
char remcomOutBuffer[BUFMAX];
|
||||
static short error;
|
||||
|
||||
|
||||
void debug_error(format, parm)
|
||||
char * format;
|
||||
char * parm;
|
||||
{
|
||||
if (remote_debug) fprintf(stderr,format,parm);
|
||||
}
|
||||
|
||||
/* convert the memory pointed to by mem into hex, placing result in buf */
|
||||
/* return a pointer to the last char put in buf (null) */
|
||||
char* mem2hex(mem, buf, count)
|
||||
char* mem;
|
||||
char* buf;
|
||||
int count;
|
||||
{
|
||||
int i;
|
||||
unsigned char ch;
|
||||
for (i=0;i<count;i++) {
|
||||
ch = *mem++;
|
||||
*buf++ = hexchars[ch >> 4];
|
||||
*buf++ = hexchars[ch % 16];
|
||||
}
|
||||
*buf = 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 */
|
||||
char* hex2mem(buf, mem, count)
|
||||
char* buf;
|
||||
char* mem;
|
||||
int count;
|
||||
{
|
||||
int i;
|
||||
unsigned char ch;
|
||||
for (i=0;i<count;i++) {
|
||||
ch = hex(*buf++) << 4;
|
||||
ch = ch + hex(*buf++);
|
||||
*mem++ = ch;
|
||||
}
|
||||
return(mem);
|
||||
}
|
||||
|
||||
/* a bus error has occurred, perform a longjmp
|
||||
to return execution and allow handling of the error */
|
||||
|
||||
void handle_buserror()
|
||||
{
|
||||
longjmp(remcomEnv,1);
|
||||
}
|
||||
|
||||
/* this function takes the 68000 exception number and attempts to
|
||||
translate this number into a unix compatible signal value */
|
||||
int computeSignal( exceptionVector )
|
||||
int exceptionVector;
|
||||
{
|
||||
int sigval;
|
||||
switch (exceptionVector) {
|
||||
case 2 : sigval = 10; break; /* bus error */
|
||||
case 3 : sigval = 10; break; /* address error */
|
||||
case 4 : sigval = 4; break; /* illegal instruction */
|
||||
case 5 : sigval = 8; break; /* zero divide */
|
||||
case 6 : sigval = 16; break; /* chk instruction */
|
||||
case 7 : sigval = 16; break; /* trapv instruction */
|
||||
case 8 : sigval = 11; break; /* privilege violation */
|
||||
case 9 : sigval = 5; break; /* trace trap */
|
||||
case 10: sigval = 4; break; /* line 1010 emulator */
|
||||
case 11: sigval = 4; break; /* line 1111 emulator */
|
||||
case 13: sigval = 8; break; /* floating point err */
|
||||
case 31: sigval = 2; break; /* interrupt */
|
||||
case 33: sigval = 5; break; /* breakpoint */
|
||||
case 40: sigval = 8; break; /* floating point err */
|
||||
case 48: sigval = 8; break; /* floating point err */
|
||||
case 49: sigval = 8; break; /* floating point err */
|
||||
case 50: sigval = 8; break; /* zero divide */
|
||||
case 51: sigval = 8; break; /* underflow */
|
||||
case 52: sigval = 8; break; /* operand error */
|
||||
case 53: sigval = 8; break; /* overflow */
|
||||
case 54: sigval = 8; break; /* NAN */
|
||||
default:
|
||||
sigval = 7; /* "software generated"*/
|
||||
}
|
||||
return (sigval);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
|
||||
/* RETURN NUMBER OF CHARS PROCESSED */
|
||||
/**********************************************/
|
||||
int hexToInt(char **ptr, int *intValue)
|
||||
{
|
||||
int numChars = 0;
|
||||
int hexValue;
|
||||
|
||||
*intValue = 0;
|
||||
|
||||
while (**ptr)
|
||||
{
|
||||
hexValue = hex(**ptr);
|
||||
if (hexValue >=0)
|
||||
{
|
||||
*intValue = (*intValue <<4) | hexValue;
|
||||
numChars ++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
(*ptr)++;
|
||||
}
|
||||
|
||||
return (numChars);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function does all command procesing for interfacing to gdb.
|
||||
*/
|
||||
void handle_exception(int exceptionVector)
|
||||
{
|
||||
int sigval;
|
||||
int addr, length;
|
||||
char * ptr;
|
||||
int newPC;
|
||||
Frame *frame;
|
||||
|
||||
if (remote_debug) printf("\nHANDLE_EXCEPTION: vector=%d, sr=0x%x, pc=0x%x, sp=0x%x\n",
|
||||
exceptionVector,
|
||||
registers[ PS ],
|
||||
registers[ PC ],
|
||||
registers[ A7 ]
|
||||
); fflush (stdout);
|
||||
|
||||
/* reply to host that an exception has occurred */
|
||||
sigval = computeSignal( exceptionVector );
|
||||
remcomOutBuffer[0] = 'S';
|
||||
remcomOutBuffer[1] = hexchars[sigval >> 4];
|
||||
remcomOutBuffer[2] = hexchars[sigval % 16];
|
||||
remcomOutBuffer[3] = 0;
|
||||
|
||||
putpacket(remcomOutBuffer);
|
||||
|
||||
while (1==1) {
|
||||
error = 0;
|
||||
remcomOutBuffer[0] = 0;
|
||||
getpacket(remcomInBuffer);
|
||||
switch (remcomInBuffer[0]) {
|
||||
case '?' : remcomOutBuffer[0] = 'S';
|
||||
remcomOutBuffer[1] = hexchars[sigval >> 4];
|
||||
remcomOutBuffer[2] = hexchars[sigval % 16];
|
||||
remcomOutBuffer[3] = 0;
|
||||
break;
|
||||
case 'd' : remote_debug = !(remote_debug); /* toggle debug flag */
|
||||
break;
|
||||
case 'g' : /* return the value of the CPU registers */
|
||||
mem2hex((char*) registers, remcomOutBuffer, NUMREGBYTES);
|
||||
break;
|
||||
case 'G' : /* set the value of the CPU registers - return OK */
|
||||
hex2mem(&remcomInBuffer[1], (char*) registers, NUMREGBYTES);
|
||||
strcpy(remcomOutBuffer,"OK");
|
||||
break;
|
||||
|
||||
/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
|
||||
case 'm' :
|
||||
if (setjmp(remcomEnv) == 0)
|
||||
{
|
||||
exceptionHandler(2,handle_buserror);
|
||||
|
||||
/* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
|
||||
ptr = &remcomInBuffer[1];
|
||||
if (hexToInt(&ptr,&addr))
|
||||
if (*(ptr++) == ',')
|
||||
if (hexToInt(&ptr,&length))
|
||||
{
|
||||
ptr = 0;
|
||||
mem2hex((char*) addr, remcomOutBuffer, length);
|
||||
}
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
strcpy(remcomOutBuffer,"E01");
|
||||
debug_error("malformed read memory command: %s",remcomInBuffer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
exceptionHandler(2,_catchException);
|
||||
strcpy(remcomOutBuffer,"E03");
|
||||
debug_error("bus error");
|
||||
}
|
||||
|
||||
/* restore handler for bus error */
|
||||
exceptionHandler(2,_catchException);
|
||||
break;
|
||||
|
||||
/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
|
||||
case 'M' :
|
||||
if (setjmp(remcomEnv) == 0) {
|
||||
exceptionHandler(2,handle_buserror);
|
||||
|
||||
/* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
|
||||
ptr = &remcomInBuffer[1];
|
||||
if (hexToInt(&ptr,&addr))
|
||||
if (*(ptr++) == ',')
|
||||
if (hexToInt(&ptr,&length))
|
||||
if (*(ptr++) == ':')
|
||||
{
|
||||
hex2mem(ptr, (char*) addr, length);
|
||||
ptr = 0;
|
||||
strcpy(remcomOutBuffer,"OK");
|
||||
}
|
||||
if (ptr)
|
||||
{
|
||||
strcpy(remcomOutBuffer,"E02");
|
||||
debug_error("malformed write memory command: %s",remcomInBuffer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
exceptionHandler(2,_catchException);
|
||||
strcpy(remcomOutBuffer,"E03");
|
||||
debug_error("bus error");
|
||||
}
|
||||
|
||||
/* restore handler for bus error */
|
||||
exceptionHandler(2,_catchException);
|
||||
break;
|
||||
|
||||
/* cAA..AA Continue at address AA..AA(optional) */
|
||||
/* sAA..AA Step one instruction from AA..AA(optional) */
|
||||
case 'c' :
|
||||
case 's' :
|
||||
/* try to read optional parameter, pc unchanged if no parm */
|
||||
ptr = &remcomInBuffer[1];
|
||||
if (hexToInt(&ptr,&addr))
|
||||
registers[ PC ] = addr;
|
||||
|
||||
newPC = registers[ PC];
|
||||
|
||||
/* clear the trace bit */
|
||||
registers[ PS ] &= 0x7fff;
|
||||
|
||||
/* set the trace bit if we're stepping */
|
||||
if (remcomInBuffer[0] == 's') registers[ PS ] |= 0x8000;
|
||||
|
||||
/*
|
||||
* look for newPC in the linked list of exception frames.
|
||||
* if it is found, use the old frame it. otherwise,
|
||||
* fake up a dummy frame in returnFromException().
|
||||
*/
|
||||
if (remote_debug) printf("new pc = 0x%x\n",newPC);
|
||||
frame = lastFrame;
|
||||
while (frame)
|
||||
{
|
||||
if (remote_debug)
|
||||
printf("frame at 0x%x has pc=0x%x, except#=%d\n",
|
||||
frame,frame->exceptionPC,
|
||||
frame->exceptionVector);
|
||||
if (frame->exceptionPC == newPC) break; /* bingo! a match */
|
||||
/*
|
||||
* for a breakpoint instruction, the saved pc may
|
||||
* be off by two due to re-executing the instruction
|
||||
* replaced by the trap instruction. Check for this.
|
||||
*/
|
||||
if ((frame->exceptionVector == 33) &&
|
||||
(frame->exceptionPC == (newPC+2))) break;
|
||||
if (frame == frame->previous)
|
||||
{
|
||||
frame = 0; /* no match found */
|
||||
break;
|
||||
}
|
||||
frame = frame->previous;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we found a match for the PC AND we are not returning
|
||||
* as a result of a breakpoint (33),
|
||||
* trace exception (9), nmi (31), jmp to
|
||||
* the old exception handler as if this code never ran.
|
||||
*/
|
||||
if (frame)
|
||||
{
|
||||
if ((frame->exceptionVector != 9) &&
|
||||
(frame->exceptionVector != 31) &&
|
||||
(frame->exceptionVector != 33))
|
||||
{
|
||||
/*
|
||||
* invoke the previous handler.
|
||||
*/
|
||||
if (oldExceptionHook)
|
||||
(*oldExceptionHook) (frame->exceptionVector);
|
||||
newPC = registers[ PC ]; /* pc may have changed */
|
||||
if (newPC != frame->exceptionPC)
|
||||
{
|
||||
if (remote_debug)
|
||||
printf("frame at 0x%x has pc=0x%x, except#=%d\n",
|
||||
frame,frame->exceptionPC,
|
||||
frame->exceptionVector);
|
||||
/* re-use the last frame, we're skipping it (longjump?)*/
|
||||
frame = (Frame *) 0;
|
||||
_returnFromException( frame ); /* this is a jump */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if we couldn't find a frame, create one */
|
||||
if (frame == 0)
|
||||
{
|
||||
frame = lastFrame -1 ;
|
||||
|
||||
/* by using a bunch of print commands with breakpoints,
|
||||
it's possible for the frame stack to creep down. If it creeps
|
||||
too far, give up and reset it to the top. Normal use should
|
||||
not see this happen.
|
||||
*/
|
||||
if ((unsigned int) (frame-2) < (unsigned int) &gdbFrameStack)
|
||||
{
|
||||
initializeRemcomErrorFrame();
|
||||
frame = lastFrame;
|
||||
}
|
||||
frame->previous = lastFrame;
|
||||
lastFrame = frame;
|
||||
frame = 0; /* null so _return... will properly initialize it */
|
||||
}
|
||||
|
||||
_returnFromException( frame ); /* this is a jump */
|
||||
|
||||
break;
|
||||
|
||||
/* kill the program */
|
||||
case 'k' : /* do nothing */
|
||||
break;
|
||||
} /* switch */
|
||||
|
||||
/* reply to the request */
|
||||
putpacket(remcomOutBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void initializeRemcomErrorFrame()
|
||||
{
|
||||
lastFrame = ((Frame *) &gdbFrameStack[FRAMESIZE-1]) - 1;
|
||||
lastFrame->previous = lastFrame;
|
||||
}
|
||||
|
||||
/* this function is used to set up exception handlers for tracing and
|
||||
breakpoints */
|
||||
void set_debug_traps()
|
||||
{
|
||||
extern void _debug_level7();
|
||||
extern void remcomHandler();
|
||||
int exception;
|
||||
|
||||
initializeRemcomErrorFrame();
|
||||
stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1];
|
||||
|
||||
setup_vectors();
|
||||
|
||||
if (oldExceptionHook != remcomHandler)
|
||||
{
|
||||
oldExceptionHook = exceptionHook;
|
||||
exceptionHook = remcomHandler;
|
||||
}
|
||||
|
||||
initialized = 1;
|
||||
|
||||
}
|
||||
/* 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) BREAKPOINT();
|
||||
}
|
155
libgloss/m68k/mvme.S
Normal file
155
libgloss/m68k/mvme.S
Normal file
@ -0,0 +1,155 @@
|
||||
/* mvme.S -- board support for m68k
|
||||
*
|
||||
* 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"
|
||||
|
||||
.title "mvme.S for m68k-coff"
|
||||
|
||||
.align 2
|
||||
.text
|
||||
.global SYM (_exit)
|
||||
.global SYM (outln)
|
||||
.global SYM (outbyte)
|
||||
.global SYM (putDebugChar)
|
||||
.global SYM (inbyte)
|
||||
.global SYM (getDebugChar)
|
||||
.global SYM (havebyte)
|
||||
.global SYM (exceptionHandler)
|
||||
|
||||
.set vbr_size, 0x400
|
||||
.comm SYM (vbr_table), vbr_size
|
||||
|
||||
/*
|
||||
* _exit -- Exit from the application. Normally we cause a user trap
|
||||
* to return to the ROM monitor for another run.
|
||||
*/
|
||||
SYM (_exit):
|
||||
unlk a6
|
||||
trap IMM(15)
|
||||
.word return
|
||||
|
||||
.align 2
|
||||
|
||||
/*
|
||||
* inbyte -- get a byte from the serial port
|
||||
* d0 - contains the byte read in
|
||||
*/
|
||||
.align 2
|
||||
SYM (getDebugChar): /* symbol name used by m68k-stub */
|
||||
SYM (inbyte):
|
||||
link a6, IMM(-8)
|
||||
trap IMM(15)
|
||||
.word inchr
|
||||
moveb sp@, d0
|
||||
extw d0
|
||||
extl d0
|
||||
unlk a6
|
||||
rts
|
||||
|
||||
/*
|
||||
* outbyte -- sends a byte out the serial port
|
||||
* d0 - contains the byte to be sent
|
||||
*/
|
||||
.align 2
|
||||
SYM (putDebugChar): /* symbol name used by m68k-stub */
|
||||
SYM (outbyte):
|
||||
link fp, IMM(-4)
|
||||
moveb fp@(11), sp@
|
||||
trap IMM(15)
|
||||
.word outchr
|
||||
unlk fp
|
||||
rts
|
||||
|
||||
/*
|
||||
* outln -- sends a string of bytes out the serial port with a CR/LF
|
||||
* a0 - contains the address of the string's first byte
|
||||
* a1 - contains the address of the string's last byte
|
||||
*/
|
||||
.align 2
|
||||
SYM (outln):
|
||||
link a6, IMM(-8)
|
||||
moveml a0/a1, sp@
|
||||
trap IMM(15)
|
||||
.word outln
|
||||
unlk a6
|
||||
rts
|
||||
|
||||
/*
|
||||
* outstr -- sends a string of bytes out the serial port without a CR/LF
|
||||
* a0 - contains the address of the string's first byte
|
||||
* a1 - contains the address of the string's last byte
|
||||
*/
|
||||
.align 2
|
||||
SYM (outstr):
|
||||
link a6, IMM(-8)
|
||||
moveml a0/a1, sp@
|
||||
trap IMM(15)
|
||||
.word outstr
|
||||
unlk a6
|
||||
rts
|
||||
|
||||
/*
|
||||
* havebyte -- checks to see if there is a byte in the serial port,
|
||||
* returns 1 if there is a byte, 0 otherwise.
|
||||
*/
|
||||
SYM (havebyte):
|
||||
trap IMM(15)
|
||||
.word instat
|
||||
beqs empty
|
||||
movel IMM(1), d0
|
||||
rts
|
||||
empty:
|
||||
movel IMM(0), d0
|
||||
rts
|
||||
|
||||
/*
|
||||
* These constants are for the MVME-135 board's boot monitor. They
|
||||
* are used with a TRAP 15 call to access the monitor's I/O routines.
|
||||
* they must be in the word following the trap call.
|
||||
*/
|
||||
.set inchr, 0x0
|
||||
.set instat, 0x1
|
||||
.set inln, 0x2
|
||||
.set readstr, 0x3
|
||||
.set readln, 0x4
|
||||
.set chkbrk, 0x5
|
||||
|
||||
.set outchr, 0x20
|
||||
.set outstr, 0x21
|
||||
.set outln, 0x22
|
||||
.set write, 0x23
|
||||
.set writeln, 0x24
|
||||
.set writdln, 0x25
|
||||
.set pcrlf, 0x26
|
||||
.set eraseln, 0x27
|
||||
.set writd, 0x28
|
||||
.set sndbrk, 0x29
|
||||
|
||||
.set tm_ini, 0x40
|
||||
.set dt_ini, 0x42
|
||||
.set tm_disp, 0x43
|
||||
.set tm_rd, 0x44
|
||||
|
||||
.set redir, 0x60
|
||||
.set redir_i, 0x61
|
||||
.set redir_o, 0x62
|
||||
.set return, 0x63
|
||||
.set bindec, 0x64
|
||||
|
||||
.set changev, 0x67
|
||||
.set strcmp, 0x68
|
||||
.set mulu32, 0x69
|
||||
.set divu32, 0x6A
|
||||
.set chk_sum, 0x6B
|
397
libgloss/m68k/mvme135-asm.S
Normal file
397
libgloss/m68k/mvme135-asm.S
Normal file
@ -0,0 +1,397 @@
|
||||
/*
|
||||
* mvme135-asm.S -- assembler routines for the MVME stub.
|
||||
*
|
||||
* This code was pulled out of mvme135-stub.c by Ian Taylor so that I
|
||||
* could handle different register and label prefixes in a sensible
|
||||
* way.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "asm.h"
|
||||
|
||||
.title "mvme135-asm.S for m68k"
|
||||
|
||||
.globl SYM (registers)
|
||||
.globl SYM (lastFrame)
|
||||
.globl SYM (superStack)
|
||||
.globl SYM (exceptionHook)
|
||||
.globl SYM (_returnFromException)
|
||||
.globl SYM (stackPtr)
|
||||
.globl SYM (handle_exception)
|
||||
.globl SYM (exceptionSize)
|
||||
.globl SYM (exceptionHandler)
|
||||
|
||||
.text
|
||||
|
||||
|
||||
/*
|
||||
* Create a new exception vector table and populates it. Vectors from the
|
||||
* boot monitor are spliced in so I/O and the abort button will continue
|
||||
* to work. We also use the monitor's generalized vector for anything the
|
||||
* debugger doesn't want.
|
||||
*/
|
||||
.global SYM (setup_vectors)
|
||||
SYM (setup_vectors):
|
||||
link fp, IMM (-8)
|
||||
/* copy monitor vector table */
|
||||
|
||||
movecl vbr, a0
|
||||
lea SYM (vbr_table), a1
|
||||
movel 0x8(a0), d0 /* get generalized vector */
|
||||
movew IMM (0x3fc), d1 /* load vector count */
|
||||
|
||||
loop: /* fill table to gen. vector */
|
||||
movel d0, (a1,d1)
|
||||
subqw IMM (4), d1
|
||||
bne loop
|
||||
|
||||
movel 0x10(a0), 0x10(a1) /* breakpoint */
|
||||
movel 0x24(a0), 0x24(a1) /* trace */
|
||||
movel 0xbc(a0), 0xbc(a1) /* system call */
|
||||
|
||||
/* add stub vectors to table */
|
||||
movel SYM (_catchException), 0x8(a1) /* vector = 2, Access Fault */
|
||||
movel SYM (_catchException), 0xc(a1) /* vector = 3, Address Error */
|
||||
movel SYM (_catchException), 0x10(a1) /* vector = 4, Illegal instruction */
|
||||
movel SYM (_catchException), 0x14(a1) /* vector = 5, divide by 0 */
|
||||
movel SYM (_catchException), 0x18(a1) /* vector = 6, chk, chk2 instruction */
|
||||
movel SYM (_catchException), 0x1c(a1) /* vector = 7, ftrap, trap, trapv ins */
|
||||
movel SYM (_catchException), 0x20(a1) /* vector = 8, priviledge violation */
|
||||
movel SYM (_catchException), 0x24(a1) /* vector = 9, trace */
|
||||
movel SYM (_catchException), 0x28(a1) /* vector = 10, Aline opcode */
|
||||
movel SYM (_catchException), 0x2c(a1) /* vector = 11, fline opcode */
|
||||
movel SYM (_catchException), 0x30(a1) /* vector = 12, reserved */
|
||||
movel SYM (_catchException), 0x34(a1) /* vector = 13, coprocessor protocol violation */
|
||||
movel SYM (_catchException), 0x38(a1) /* vector = 14, format error */
|
||||
movel SYM (_catchException), 0x3c(a1) /* vector = 15, unitialized interupt */
|
||||
|
||||
/* unassigned, reserved */
|
||||
movel SYM (_catchException), 0x40(a1) /* vector = 16 */
|
||||
movel SYM (_catchException), 0x44(a1) /* vector = 17 */
|
||||
movel SYM (_catchException), 0x48(a1) /* vector = 18 */
|
||||
movel SYM (_catchException), 0x4c(a1) /* vector = 19 */
|
||||
movel SYM (_catchException), 0x50(a1) /* vector = 20 */
|
||||
movel SYM (_catchException), 0x54(a1) /* vector = 21 */
|
||||
movel SYM (_catchException), 0x58(a1) /* vector = 22 */
|
||||
movel SYM (_catchException), 0x5c(a1) /* vector = 23 */
|
||||
|
||||
movel SYM (_catchException), 0x84(a1) /* vector = 33, breakpoint, trap #1 */
|
||||
movel SYM (_catchException), 0xa0(a1) /* vector = 40 , trap #8*/
|
||||
|
||||
/* floating point traps */
|
||||
movel SYM (_catchException), 0xc0(a1) /* vector = 48 */
|
||||
movel SYM (_catchException), 0xc4(a1) /* vector = 49 */
|
||||
movel SYM (_catchException), 0xc8(a1) /* vector = 50 */
|
||||
movel SYM (_catchException), 0xcc(a1) /* vector = 51 */
|
||||
movel SYM (_catchException), 0xd0(a1) /* vector = 52 */
|
||||
movel SYM (_catchException), 0xd4(a1) /* vector = 53 */
|
||||
movel SYM (_catchException), 0xd8(a1) /* vector = 54 */
|
||||
movel SYM (_catchException), 0xdc(a1) /* vector = 55 */
|
||||
movel SYM (_catchException), 0xe0(a1) /* vector = 56 */
|
||||
movel SYM (_catchException), 0xe4(a1) /* vector = 57 */
|
||||
movel SYM (_catchException), 0xe8(a1) /* vector = 58 */
|
||||
|
||||
/*** movel &__debug_level7, 0x7c(a1) /* level7 interupt vector */
|
||||
|
||||
movecl a1, vbr /* change VBR to new table */
|
||||
unlk fp
|
||||
rts
|
||||
/*
|
||||
* exceptionHandler -- sets up exception vector table.
|
||||
* First arg is an integer vector number
|
||||
* Second arg is the function pointer for the vector
|
||||
*/
|
||||
SYM (exceptionHandler):
|
||||
# link a6, IMM (-8)
|
||||
#str1: .ascii "Exception Handler Called\n"
|
||||
# moveal IMM (str1), a0
|
||||
# moveal IMM (str1+25), a1
|
||||
# jsr SYM (outln)
|
||||
|
||||
# unlk a6
|
||||
rts
|
||||
|
||||
/* this never gets called */
|
||||
movel fp@(8), d0 /* get vector number */
|
||||
movel fp@(12), a0 /* get function address */
|
||||
moveal &SYM (vbr_table), a1 /* FIXME */
|
||||
|
||||
addl d0, d0
|
||||
addl d0, d0
|
||||
|
||||
addal d0, a1
|
||||
movel a0, (a1)
|
||||
|
||||
movecl a1, vbr
|
||||
unlk a6
|
||||
rts
|
||||
|
||||
.globl SYM (return_to_super)
|
||||
SYM (return_to_super):
|
||||
movel SYM (registers)+60,sp /* get new stack pointer */
|
||||
movel SYM (lastFrame),a0 /* get last frame info */
|
||||
bra return_to_any
|
||||
|
||||
.globl SYM (return_to_user)
|
||||
SYM (return_to_user):
|
||||
movel SYM (registers)+60,a0 /* get usp */
|
||||
movel a0,usp /* set usp */
|
||||
movel SYM (superStack),sp /* get original stack pointer */
|
||||
|
||||
return_to_any:
|
||||
movel SYM (lastFrame),a0 /* get last frame info */
|
||||
movel a0@+,SYM (lastFrame) /* link in previous frame */
|
||||
addql IMM (8),a0 /* skip over pc, vector#*/
|
||||
movew a0@+,d0 /* get # of words in cpu frame */
|
||||
addw d0,a0 /* point to end of data */
|
||||
addw d0,a0 /* point to end of data */
|
||||
movel a0,a1
|
||||
/* copy the stack frame */
|
||||
subql IMM (1),d0
|
||||
copyUserLoop:
|
||||
movew a1@-,sp@-
|
||||
dbf d0,copyUserLoop
|
||||
|
||||
#ifdef __HAVE_68881__
|
||||
fmoveml SYM (registers)+168,fpcr/fpsr/fpi
|
||||
fmovemx SYM (registers)+72,fp0-fp7
|
||||
cmpl IMM (-1),a0@ /* skip frestore flag set ? */
|
||||
beq skip_frestore
|
||||
frestore a0@+
|
||||
skip_frestore:
|
||||
#endif
|
||||
|
||||
moveml SYM (registers),d0-d7/a0-a6
|
||||
rte /* pop and go! */
|
||||
|
||||
|
||||
/* this function is called immediately when a level 7 interrupt occurs */
|
||||
/* if the previous interrupt level was 7 then we're already servicing */
|
||||
/* this interrupt and an rte is in order to return to the debugger. */
|
||||
/* For the 68000, the offset for sr is 6 due to the jsr return address */
|
||||
.text
|
||||
.globl SYM (_debug_level7)
|
||||
SYM (_debug_level7):
|
||||
movew d0,sp@-
|
||||
#ifdef mc68020
|
||||
movew sp@(2),d0
|
||||
#else
|
||||
movew sp@(6),d0
|
||||
#endif
|
||||
andiw IMM (0x700),d0
|
||||
cmpiw IMM (0x700),d0
|
||||
beq _already7
|
||||
movew sp@+,d0
|
||||
bra SYM (_catchException)
|
||||
_already7:
|
||||
movew sp@+,d0
|
||||
#ifndef mc68020
|
||||
lea sp@(4),sp /* pull off 68000 return address */
|
||||
#endif
|
||||
rte
|
||||
|
||||
#ifdef mc68020
|
||||
/* This function is called when a 68020 exception occurs. It saves
|
||||
* all the cpu and fpcp regs in the _registers array, creates a frame on a
|
||||
* linked list of frames which has the cpu and fpcp stack frames needed
|
||||
* to properly restore the context of these processors, and invokes
|
||||
* an exception handler (remcom_handler).
|
||||
*
|
||||
* stack on entry: stack on exit:
|
||||
* N bytes of junk exception # MSWord
|
||||
* Exception Format Word exception # MSWord
|
||||
* Program counter LSWord
|
||||
* Program counter MSWord
|
||||
* Status Register
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl SYM (_catchException)
|
||||
SYM (_catchException):
|
||||
|
||||
oriw IMM (0x0700),sr /* Disable interrupts */
|
||||
|
||||
moveml d0-d7/a0-a6,SYM (registers) /* save registers */
|
||||
movel SYM (lastFrame),a0 /* last frame pointer */
|
||||
|
||||
#ifdef __HAVE_68881__
|
||||
/* do an fsave, then remember the address to begin a restore from */
|
||||
fsave a0@-
|
||||
fmovemx fp0-fp7, SYM (registers)+72
|
||||
fmoveml fpcr/fpsr/fpi, SYM (registers)+168
|
||||
#endif
|
||||
|
||||
lea SYM (registers),a5 /* get address of registers */
|
||||
movew sp@,d1 /* get status register */
|
||||
movew d1,a5@(66) /* save sr */
|
||||
movel sp@(2),a4 /* save pc in a4 for later use */
|
||||
movel a4,a5@(68) /* save pc in _regisers[] */
|
||||
|
||||
/* figure out how many bytes in the stack frame */
|
||||
movew sp@(6),d0 /* get '020 exception format */
|
||||
movew d0,d2 /* make a copy of format word */
|
||||
andiw IMM (0xf000),d0 /* mask off format type */
|
||||
rolw IMM (5),d0 /* rotate into the low byte *2 */
|
||||
lea SYM (exceptionSize),a1
|
||||
addw d0,a1 /* index into the table */
|
||||
movew a1@,d0 /* get number of words in frame */
|
||||
movew d0,d3 /* save it */
|
||||
subw d0,a0 /* adjust save pointer */
|
||||
subw d0,a0 /* adjust save pointer(bytes) */
|
||||
movel a0,a1 /* copy save pointer */
|
||||
subql IMM (1),d0 /* predecrement loop counter */
|
||||
|
||||
/* copy the frame */
|
||||
|
||||
saveFrameLoop:
|
||||
movew sp@+,a1@+
|
||||
dbf d0,saveFrameLoop
|
||||
|
||||
/* now that the stack has been clenaed,
|
||||
* save the a7 in use at time of exception
|
||||
*/
|
||||
movel sp,SYM (superStack) /* save supervisor sp */
|
||||
andiw IMM (0x2000),d1 /* were we in supervisor mode ? */
|
||||
beq userMode
|
||||
movel a7,a5@(60) /* save a7 */
|
||||
bra a7saveDone
|
||||
userMode:
|
||||
movel usp,a1
|
||||
movel a1,a5@(60) /* save user stack pointer */
|
||||
a7saveDone:
|
||||
|
||||
|
||||
/* save size of frame */
|
||||
movew d3,a0@-
|
||||
|
||||
/* compute exception number */
|
||||
andl IMM (0xfff),d2 /* mask off vector offset */
|
||||
lsrw IMM (2),d2 /* divide by 4 to get vect num */
|
||||
movel d2,a0@- /* save it */
|
||||
|
||||
/* save pc causing exception */
|
||||
movel a4,a0@-
|
||||
|
||||
/* save old frame link and set the new value*/
|
||||
movel SYM (lastFrame),a1 /* last frame pointer */
|
||||
movel a1,a0@- /* save pointer to prev frame */
|
||||
movel a0,SYM (lastFrame)
|
||||
|
||||
movel d2,sp@- /* push exception num */
|
||||
#ifdef TMP_HACK
|
||||
movel SYM (exceptionHook),a0 /* get address of handler */
|
||||
jbsr a0@ /* and call it */
|
||||
#else
|
||||
jbsr SYM (remcomHandler)
|
||||
#endif
|
||||
clrl sp@ /* replace exception num parm with frame ptr */
|
||||
jbsr SYM (_returnFromException) /* jbsr, but never returns */
|
||||
|
||||
#else /* mc68000 */
|
||||
|
||||
/* This function is called when an exception occurs. It translates the
|
||||
* return address found on the stack into an exception vector # which
|
||||
* is then handled by either handle_exception or a system handler.
|
||||
* _catchException provides a front end for both.
|
||||
*
|
||||
* stack on entry: stack on exit:
|
||||
* Program counter MSWord exception # MSWord
|
||||
* Program counter LSWord exception # MSWord
|
||||
* Status Register
|
||||
* Return Address MSWord
|
||||
* Return Address LSWord
|
||||
*/
|
||||
.text
|
||||
.globl SYM (_catchException)
|
||||
SYM (_catchException):
|
||||
|
||||
oriw IMM (0x0700),sr /* Disable interrupts */
|
||||
|
||||
moveml d0-d7/a0-a6,SYM (registers) /* save registers */
|
||||
movel SYM (lastFrame),a0 /* last frame pointer */
|
||||
|
||||
#ifdef __HAVE_68881__
|
||||
/* do an fsave, then remember the address to begin a restore from */
|
||||
fsave a0@-
|
||||
fmovemx fp0-fp7, SYM (registers)+72
|
||||
fmoveml fpcr/fpsr/fpi, SYM (registers)+168
|
||||
#endif
|
||||
|
||||
lea SYM (registers),a5 /* get address of registers */
|
||||
movel sp@+,d2 /* pop return address */
|
||||
addl IMM (1530),d2 /* convert return addr to */
|
||||
divs IMM (6),d2 /* exception number */
|
||||
extl d2
|
||||
|
||||
moveql IMM (3),d3 /* assume a three word frame */
|
||||
|
||||
cmpiw IMM (3),d2 /* bus error or address error ? */
|
||||
bgt normal /* if >3 then normal error */
|
||||
movel sp@+,a0@- /* copy error info to frame buff*/
|
||||
movel sp@+,a0@- /* these are never used */
|
||||
moveql IMM (7),d3 /* this is a 7 word frame */
|
||||
|
||||
normal:
|
||||
movew sp@+,d1 /* pop status register */
|
||||
movel sp@+,a4 /* pop program counter */
|
||||
movew d1,a5@(66) /* save sr */
|
||||
movel a4,a5@(68) /* save pc in _regisers[] */
|
||||
movel a4,a0@- /* copy pc to frame buffer */
|
||||
movew d1,a0@- /* copy sr to frame buffer */
|
||||
|
||||
movel sp,SYM (superStack) /* save supervisor sp */
|
||||
|
||||
andiw IMM (0x2000),d1 /* were we in supervisor mode ? */
|
||||
beq userMode
|
||||
movel a7,a5@(60) /* save a7 */
|
||||
bra saveDone
|
||||
userMode:
|
||||
movel usp,a1 /* save user stack pointer */
|
||||
movel a1,a5@(60) /* save user stack pointer */
|
||||
saveDone:
|
||||
|
||||
movew d3,a0@- /* push frame size in words */
|
||||
movel d2,a0@- /* push vector number */
|
||||
movel a4,a0@- /* push exception pc */
|
||||
|
||||
/* save old frame link and set the new value */
|
||||
movel SYM (lastFrame),a1 /* last frame pointer */
|
||||
movel a1,a0@- /* save pointer to prev frame */
|
||||
movel a0,SYM (lastFrame)
|
||||
|
||||
movel d2,sp@- /* push exception num */
|
||||
movel SYM (exceptionHook),a0 /* get address of handler */
|
||||
jbsr a0@ /* and call it */
|
||||
clrl sp@ /* replace exception num parm with frame ptr */
|
||||
jbsr SYM (_returnFromException) /* jbsr, but never returns */
|
||||
|
||||
#endif /* m68000 */
|
||||
|
||||
/*
|
||||
* remcomHandler is a front end for handle_exception. It moves the
|
||||
* stack pointer into an area reserved for debugger use in case the
|
||||
* breakpoint happened in supervisor mode.
|
||||
*/
|
||||
.globl SYM (remcomHandler)
|
||||
SYM (remcomHandler):
|
||||
addl IMM (4),sp /* pop off return address */
|
||||
movel sp@+,d0 /* get the exception number */
|
||||
movel SYM (stackPtr),sp /* move to remcom stack area */
|
||||
movel d0,sp@- /* push exception onto stack */
|
||||
jbsr SYM (handle_exception) /* this never returns */
|
||||
rts /* return */
|
128
libgloss/m68k/mvme135.ld
Normal file
128
libgloss/m68k/mvme135.ld
Normal file
@ -0,0 +1,128 @@
|
||||
STARTUP(crt0.o)
|
||||
OUTPUT_ARCH(m68k)
|
||||
/* Uncomment this if you want srecords. This is needed for a.out
|
||||
* if you plan to use GDB.
|
||||
OUTPUT_FORMAT(srec)
|
||||
*/
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lmvme135 -lc -lgcc)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*
|
||||
* Setup the memory map of the Motorola MVME135 Board
|
||||
* stack grows down from high memory.
|
||||
*
|
||||
* The memory map look like this:
|
||||
* +--------------------+ <- low memory
|
||||
* | .text |
|
||||
* | _etext |
|
||||
* | ctor list | the ctor and dtor lists are for
|
||||
* | dtor list | C++ support
|
||||
* +--------------------+
|
||||
* | .data | initialized data goes here
|
||||
* | _edata |
|
||||
* +--------------------+
|
||||
* | .bss |
|
||||
* | __bss_start | start of bss, cleared by crt0
|
||||
* | _end | start of heap, used by sbrk()
|
||||
* +--------------------+
|
||||
* . .
|
||||
* . .
|
||||
* . .
|
||||
* | __stack | top of stack
|
||||
* +--------------------+
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x5000, LENGTH = 1M
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the stack to be at the top of memory, since the stack
|
||||
* grows down
|
||||
*/
|
||||
|
||||
PROVIDE (__stack = 1M - 8);
|
||||
|
||||
/*
|
||||
* 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 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);
|
||||
/*
|
||||
* stick everything in ram (of course)
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
. = ALIGN(0x4);
|
||||
__CTOR_LIST__ = .;
|
||||
___CTOR_LIST__ = .;
|
||||
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
|
||||
*(.ctors)
|
||||
LONG(0)
|
||||
__CTOR_END__ = .;
|
||||
__DTOR_LIST__ = .;
|
||||
___DTOR_LIST__ = .;
|
||||
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
|
||||
*(.dtors)
|
||||
LONG(0)
|
||||
__DTOR_END__ = .;
|
||||
*(.rodata)
|
||||
*(.gcc_except_table)
|
||||
|
||||
. = ALIGN(0x2);
|
||||
__INIT_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.init)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
__FINI_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.fini)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
_etext = .;
|
||||
*(.lit)
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.shdata)
|
||||
*(.data)
|
||||
_edata = .;
|
||||
} > ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
__bss_start = . ;
|
||||
*(.shbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end = ALIGN (0x8);
|
||||
__end = _end;
|
||||
} > ram
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
}
|
129
libgloss/m68k/mvme162.ld
Normal file
129
libgloss/m68k/mvme162.ld
Normal file
@ -0,0 +1,129 @@
|
||||
STARTUP(crt0.o)
|
||||
OUTPUT_ARCH(m68k)
|
||||
/* Uncomment this if you want srecords. This is needed for a.out
|
||||
* if you plan to use GDB.
|
||||
OUTPUT_FORMAT(srec)
|
||||
*/
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lmvme162 -lc -lgcc)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*
|
||||
* Setup the memory map of the Motorola MVME135 Board
|
||||
* stack grows down from high memory.
|
||||
*
|
||||
* The memory map look like this:
|
||||
* +--------------------+ <- low memory
|
||||
* | .text |
|
||||
* | _etext |
|
||||
* | ctor list | the ctor and dtor lists are for
|
||||
* | dtor list | C++ support
|
||||
* +--------------------+
|
||||
* | .data | initialized data goes here
|
||||
* | _edata |
|
||||
* +--------------------+
|
||||
* | .bss |
|
||||
* | __bss_start | start of bss, cleared by crt0
|
||||
* | _end | start of heap, used by sbrk()
|
||||
* +--------------------+
|
||||
* . .
|
||||
* . .
|
||||
* . .
|
||||
* | __stack | top of stack
|
||||
* +--------------------+
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
monitor : ORIGIN = 0x0000, LENGTH = 64K
|
||||
ram (rwx) : ORIGIN = 0x10000, LENGTH = 16M
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate the stack to be at the top of memory, since the stack
|
||||
* grows down
|
||||
*/
|
||||
|
||||
PROVIDE (__stack = 16M - 8);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/*
|
||||
* stick everything in ram (of course)
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
. = ALIGN(0x4);
|
||||
__CTOR_LIST__ = .;
|
||||
___CTOR_LIST__ = .;
|
||||
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
|
||||
*(.ctors)
|
||||
LONG(0)
|
||||
__CTOR_END__ = .;
|
||||
__DTOR_LIST__ = .;
|
||||
___DTOR_LIST__ = .;
|
||||
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
|
||||
*(.dtors)
|
||||
LONG(0)
|
||||
__DTOR_END__ = .;
|
||||
*(.rodata)
|
||||
*(.gcc_except_table)
|
||||
|
||||
. = ALIGN(0x2);
|
||||
__INIT_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.init)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
__FINI_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.fini)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
_etext = .;
|
||||
*(.lit)
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.shdata)
|
||||
*(.data)
|
||||
_edata = .;
|
||||
} > ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
__bss_start = . ;
|
||||
*(.shbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end = ALIGN (0x8);
|
||||
__end = _end;
|
||||
} > ram
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
}
|
292
libgloss/m68k/mvme162lx-asm.S
Normal file
292
libgloss/m68k/mvme162lx-asm.S
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* mvme162lx-asm.S -- assembler routines for the MVME stub.
|
||||
*
|
||||
* This code was pulled out of mvme162lx-stub.c by Ian Taylor so that I
|
||||
* could handle different register and label prefixes in a sensible
|
||||
* way.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "asm.h"
|
||||
|
||||
.title "mvme162lx-asm.S for m68k"
|
||||
|
||||
.globl SYM (registers)
|
||||
.globl SYM (lastFrame)
|
||||
.globl SYM (superStack)
|
||||
.globl SYM (exceptionHook)
|
||||
.globl SYM (_returnFromException)
|
||||
.globl SYM (stackPtr)
|
||||
.globl SYM (handle_exception)
|
||||
.globl SYM (exceptionSize)
|
||||
|
||||
.text
|
||||
.globl SYM (return_to_super)
|
||||
SYM (return_to_super):
|
||||
movel SYM (registers)+60,sp /* get new stack pointer */
|
||||
movel SYM (lastFrame),a0 /* get last frame info */
|
||||
bra return_to_any
|
||||
|
||||
.globl SYM (return_to_user)
|
||||
SYM (return_to_user):
|
||||
movel SYM (registers)+60,a0 /* get usp */
|
||||
movel a0,usp /* set usp */
|
||||
movel SYM (superStack),sp /* get original stack pointer */
|
||||
|
||||
return_to_any:
|
||||
movel SYM (lastFrame),a0 /* get last frame info */
|
||||
movel a0@+,SYM (lastFrame) /* link in previous frame */
|
||||
addql IMM (8),a0 /* skip over pc, vector#*/
|
||||
movew a0@+,d0 /* get # of words in cpu frame */
|
||||
addw d0,a0 /* point to end of data */
|
||||
addw d0,a0 /* point to end of data */
|
||||
movel a0,a1
|
||||
/* copy the stack frame */
|
||||
subql IMM (1),d0
|
||||
copyUserLoop:
|
||||
movew a1@-,sp@-
|
||||
dbf d0,copyUserLoop
|
||||
|
||||
#ifdef __HAVE_68881__
|
||||
fmoveml SYM (registers)+168,fpcr/fpsr/fpi
|
||||
fmovemx SYM (registers)+72,fp0-fp7
|
||||
cmpl IMM (-1),a0@ /* skip frestore flag set ? */
|
||||
beq skip_frestore
|
||||
frestore a0@+
|
||||
skip_frestore:
|
||||
#endif
|
||||
|
||||
moveml SYM (registers),d0-d7/a0-a6
|
||||
rte /* pop and go! */
|
||||
|
||||
|
||||
/* this function is called immediately when a level 7 interrupt occurs */
|
||||
/* if the previous interrupt level was 7 then we're already servicing */
|
||||
/* this interrupt and an rte is in order to return to the debugger. */
|
||||
/* For the 68000, the offset for sr is 6 due to the jsr return address */
|
||||
.text
|
||||
.globl SYM (_debug_level7)
|
||||
SYM (_debug_level7):
|
||||
movew d0,sp@-
|
||||
#ifdef mc68020
|
||||
movew sp@(2),d0
|
||||
#else
|
||||
movew sp@(6),d0
|
||||
#endif
|
||||
andiw IMM (0x700),d0
|
||||
cmpiw IMM (0x700),d0
|
||||
beq _already7
|
||||
movew sp@+,d0
|
||||
bra SYM (_catchException)
|
||||
_already7:
|
||||
movew sp@+,d0
|
||||
#ifndef mc68020
|
||||
lea sp@(4),sp /* pull off 68000 return address */
|
||||
#endif
|
||||
rte
|
||||
|
||||
#ifdef mc68020
|
||||
/* This function is called when a 68020 exception occurs. It saves
|
||||
* all the cpu and fpcp regs in the _registers array, creates a frame on a
|
||||
* linked list of frames which has the cpu and fpcp stack frames needed
|
||||
* to properly restore the context of these processors, and invokes
|
||||
* an exception handler (remcom_handler).
|
||||
*
|
||||
* stack on entry: stack on exit:
|
||||
* N bytes of junk exception # MSWord
|
||||
* Exception Format Word exception # MSWord
|
||||
* Program counter LSWord
|
||||
* Program counter MSWord
|
||||
* Status Register
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl SYM (_catchException)
|
||||
SYM (_catchException):
|
||||
|
||||
oriw IMM (0x0700),sr /* Disable interrupts */
|
||||
|
||||
moveml d0-d7/a0-a6,SYM (registers) /* save registers */
|
||||
movel SYM (lastFrame),a0 /* last frame pointer */
|
||||
|
||||
#ifdef __HAVE_68881__
|
||||
/* do an fsave, then remember the address to begin a restore from */
|
||||
fsave a0@-
|
||||
fmovemx fp0-fp7, SYM (registers)+72
|
||||
fmoveml fpcr/fpsr/fpi, SYM (registers)+168
|
||||
#endif
|
||||
|
||||
lea SYM (registers),a5 /* get address of registers */
|
||||
movew sp@,d1 /* get status register */
|
||||
movew d1,a5@(66) /* save sr */
|
||||
movel sp@(2),a4 /* save pc in a4 for later use */
|
||||
movel a4,a5@(68) /* save pc in _regisers[] */
|
||||
|
||||
/* figure out how many bytes in the stack frame */
|
||||
movew sp@(6),d0 /* get '020 exception format */
|
||||
movew d0,d2 /* make a copy of format word */
|
||||
andiw IMM (0xf000),d0 /* mask off format type */
|
||||
rolw IMM (5),d0 /* rotate into the low byte *2 */
|
||||
lea SYM (exceptionSize),a1
|
||||
addw d0,a1 /* index into the table */
|
||||
movew a1@,d0 /* get number of words in frame */
|
||||
movew d0,d3 /* save it */
|
||||
subw d0,a0 /* adjust save pointer */
|
||||
subw d0,a0 /* adjust save pointer(bytes) */
|
||||
movel a0,a1 /* copy save pointer */
|
||||
subql IMM (1),d0 /* predecrement loop counter */
|
||||
|
||||
/* copy the frame */
|
||||
|
||||
saveFrameLoop:
|
||||
movew sp@+,a1@+
|
||||
dbf d0,saveFrameLoop
|
||||
|
||||
/* now that the stack has been clenaed,
|
||||
* save the a7 in use at time of exception
|
||||
*/
|
||||
movel sp,SYM (superStack) /* save supervisor sp */
|
||||
andiw IMM (0x2000),d1 /* were we in supervisor mode ? */
|
||||
beq userMode
|
||||
movel a7,a5@(60) /* save a7 */
|
||||
bra a7saveDone
|
||||
userMode:
|
||||
movel usp,a1
|
||||
movel a1,a5@(60) /* save user stack pointer */
|
||||
a7saveDone:
|
||||
|
||||
|
||||
/* save size of frame */
|
||||
movew d3,a0@-
|
||||
|
||||
/* compute exception number */
|
||||
andl IMM (0xfff),d2 /* mask off vector offset */
|
||||
lsrw IMM (2),d2 /* divide by 4 to get vect num */
|
||||
movel d2,a0@- /* save it */
|
||||
|
||||
/* save pc causing exception */
|
||||
movel a4,a0@-
|
||||
|
||||
/* save old frame link and set the new value*/
|
||||
movel SYM (lastFrame),a1 /* last frame pointer */
|
||||
movel a1,a0@- /* save pointer to prev frame */
|
||||
movel a0,SYM (lastFrame)
|
||||
|
||||
movel d2,sp@- /* push exception num */
|
||||
#ifdef TMP_HACK
|
||||
movel SYM (exceptionHook),a0 /* get address of handler */
|
||||
jbsr a0@ /* and call it */
|
||||
#else
|
||||
jbsr SYM (remcomHandler)
|
||||
#endif
|
||||
clrl sp@ /* replace exception num parm with frame ptr */
|
||||
jbsr SYM (_returnFromException) /* jbsr, but never returns */
|
||||
|
||||
#else /* mc68000 */
|
||||
|
||||
/* This function is called when an exception occurs. It translates the
|
||||
* return address found on the stack into an exception vector # which
|
||||
* is then handled by either handle_exception or a system handler.
|
||||
* _catchException provides a front end for both.
|
||||
*
|
||||
* stack on entry: stack on exit:
|
||||
* Program counter MSWord exception # MSWord
|
||||
* Program counter LSWord exception # MSWord
|
||||
* Status Register
|
||||
* Return Address MSWord
|
||||
* Return Address LSWord
|
||||
*/
|
||||
.text
|
||||
.globl SYM (_catchException)
|
||||
SYM (_catchException):
|
||||
|
||||
oriw IMM (0x0700),sr /* Disable interrupts */
|
||||
|
||||
moveml d0-d7/a0-a6,SYM (registers) /* save registers */
|
||||
movel SYM (lastFrame),a0 /* last frame pointer */
|
||||
|
||||
#ifdef __HAVE_68881__
|
||||
/* do an fsave, then remember the address to begin a restore from */
|
||||
fsave a0@-
|
||||
fmovemx fp0-fp7, SYM (registers)+72
|
||||
fmoveml fpcr/fpsr/fpi, SYM (registers)+168
|
||||
#endif
|
||||
|
||||
lea SYM (registers),a5 /* get address of registers */
|
||||
movel sp@+,d2 /* pop return address */
|
||||
addl IMM (1530),d2 /* convert return addr to */
|
||||
divs IMM (6),d2 /* exception number */
|
||||
extl d2
|
||||
|
||||
moveql IMM (3),d3 /* assume a three word frame */
|
||||
|
||||
cmpiw IMM (3),d2 /* bus error or address error ? */
|
||||
bgt normal /* if >3 then normal error */
|
||||
movel sp@+,a0@- /* copy error info to frame buff*/
|
||||
movel sp@+,a0@- /* these are never used */
|
||||
moveql IMM (7),d3 /* this is a 7 word frame */
|
||||
|
||||
normal:
|
||||
movew sp@+,d1 /* pop status register */
|
||||
movel sp@+,a4 /* pop program counter */
|
||||
movew d1,a5@(66) /* save sr */
|
||||
movel a4,a5@(68) /* save pc in _regisers[] */
|
||||
movel a4,a0@- /* copy pc to frame buffer */
|
||||
movew d1,a0@- /* copy sr to frame buffer */
|
||||
|
||||
movel sp,SYM (superStack) /* save supervisor sp */
|
||||
|
||||
andiw IMM (0x2000),d1 /* were we in supervisor mode ? */
|
||||
beq userMode
|
||||
movel a7,a5@(60) /* save a7 */
|
||||
bra saveDone
|
||||
userMode:
|
||||
movel usp,a1 /* save user stack pointer */
|
||||
movel a1,a5@(60) /* save user stack pointer */
|
||||
saveDone:
|
||||
|
||||
movew d3,a0@- /* push frame size in words */
|
||||
movel d2,a0@- /* push vector number */
|
||||
movel a4,a0@- /* push exception pc */
|
||||
|
||||
/* save old frame link and set the new value */
|
||||
movel SYM (lastFrame),a1 /* last frame pointer */
|
||||
movel a1,a0@- /* save pointer to prev frame */
|
||||
movel a0,SYM (lastFrame)
|
||||
|
||||
movel d2,sp@- /* push exception num */
|
||||
movel SYM (exceptionHook),a0 /* get address of handler */
|
||||
jbsr a0@ /* and call it */
|
||||
clrl sp@ /* replace exception num parm with frame ptr */
|
||||
jbsr SYM (_returnFromException) /* jbsr, but never returns */
|
||||
|
||||
#endif /* m68000 */
|
||||
|
||||
/*
|
||||
* remcomHandler is a front end for handle_exception. It moves the
|
||||
* stack pointer into an area reserved for debugger use in case the
|
||||
* breakpoint happened in supervisor mode.
|
||||
*/
|
||||
.globl SYM (remcomHandler)
|
||||
SYM (remcomHandler):
|
||||
addl IMM (4),sp /* pop off return address */
|
||||
movel sp@+,d0 /* get the exception number */
|
||||
movel SYM (stackPtr),sp /* move to remcom stack area */
|
||||
movel d0,sp@- /* push exception onto stack */
|
||||
jbsr SYM (handle_exception) /* this never returns */
|
||||
rts /* return */
|
127
libgloss/m68k/sbc5204.ld
Normal file
127
libgloss/m68k/sbc5204.ld
Normal file
@ -0,0 +1,127 @@
|
||||
/* STARTUP(crt0.o) */
|
||||
OUTPUT_ARCH(m68k)
|
||||
/* Uncomment this if you want srecords. This is needed for a.out
|
||||
* if you plan to use GDB.
|
||||
OUTPUT_FORMAT(srec)
|
||||
*/
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-ldbug -lc -lgcc)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*
|
||||
* Setup the memory map of the Arnewsh SBC5204
|
||||
* stack grows down from high memory.
|
||||
*
|
||||
* The memory map look like this:
|
||||
* +--------------------+ <- low memory
|
||||
* | .text |
|
||||
* | _etext |
|
||||
* | ctor list | the ctor and dtor lists are for
|
||||
* | dtor list | C++ support
|
||||
* +--------------------+
|
||||
* | .data | initialized data goes here
|
||||
* | _edata |
|
||||
* +--------------------+
|
||||
* | .bss |
|
||||
* | __bss_start | start of bss, cleared by crt0
|
||||
* | _end | start of heap, used by sbrk()
|
||||
* +--------------------+
|
||||
* . .
|
||||
* . .
|
||||
* . .
|
||||
* | __stack | top of stack
|
||||
* +--------------------+
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x10000, LENGTH = 0x30000
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate the stack to be at the top of memory, since the stack
|
||||
* grows down
|
||||
*/
|
||||
|
||||
PROVIDE (__stack = 0x30000);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/*
|
||||
* stick everything in ram (of course)
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
. = ALIGN(0x4);
|
||||
__CTOR_LIST__ = .;
|
||||
___CTOR_LIST__ = .;
|
||||
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
|
||||
*(.ctors)
|
||||
LONG(0)
|
||||
__CTOR_END__ = .;
|
||||
__DTOR_LIST__ = .;
|
||||
___DTOR_LIST__ = .;
|
||||
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
|
||||
*(.dtors)
|
||||
LONG(0)
|
||||
__DTOR_END__ = .;
|
||||
*(.rodata)
|
||||
*(.gcc_except_table)
|
||||
|
||||
. = ALIGN(0x2);
|
||||
__INIT_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.init)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
__FINI_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.fini)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
_etext = .;
|
||||
*(.lit)
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.shdata)
|
||||
*(.data)
|
||||
_edata = .;
|
||||
} > ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
__bss_start = . ;
|
||||
*(.shbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end = ALIGN (0x8);
|
||||
__end = _end;
|
||||
} > ram
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
}
|
127
libgloss/m68k/sbc5206.ld
Normal file
127
libgloss/m68k/sbc5206.ld
Normal file
@ -0,0 +1,127 @@
|
||||
/* STARTUP(crt0.o) */
|
||||
OUTPUT_ARCH(m68k)
|
||||
/* Uncomment this if you want srecords. This is needed for a.out
|
||||
* if you plan to use GDB.
|
||||
OUTPUT_FORMAT(srec)
|
||||
*/
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-ldbug -lc -lgcc)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*
|
||||
* Setup the memory map of the Arnewsh SBC5206
|
||||
* stack grows down from high memory.
|
||||
*
|
||||
* The memory map look like this:
|
||||
* +--------------------+ <- low memory
|
||||
* | .text |
|
||||
* | _etext |
|
||||
* | ctor list | the ctor and dtor lists are for
|
||||
* | dtor list | C++ support
|
||||
* +--------------------+
|
||||
* | .data | initialized data goes here
|
||||
* | _edata |
|
||||
* +--------------------+
|
||||
* | .bss |
|
||||
* | __bss_start | start of bss, cleared by crt0
|
||||
* | _end | start of heap, used by sbrk()
|
||||
* +--------------------+
|
||||
* . .
|
||||
* . .
|
||||
* . .
|
||||
* | __stack | top of stack
|
||||
* +--------------------+
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x10000, LENGTH = 0xd000
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate the stack to be at the top of memory, since the stack
|
||||
* grows down
|
||||
*/
|
||||
|
||||
PROVIDE (__stack = 0xd000);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
/*
|
||||
* stick everything in ram (of course)
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
. = ALIGN(0x4);
|
||||
__CTOR_LIST__ = .;
|
||||
___CTOR_LIST__ = .;
|
||||
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
|
||||
*(.ctors)
|
||||
LONG(0)
|
||||
__CTOR_END__ = .;
|
||||
__DTOR_LIST__ = .;
|
||||
___DTOR_LIST__ = .;
|
||||
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
|
||||
*(.dtors)
|
||||
LONG(0)
|
||||
__DTOR_END__ = .;
|
||||
*(.rodata)
|
||||
*(.gcc_except_table)
|
||||
|
||||
. = ALIGN(0x2);
|
||||
__INIT_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.init)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
__FINI_SECTION__ = . ;
|
||||
LONG (0x4e560000) /* linkw %fp,#0 */
|
||||
*(.fini)
|
||||
SHORT (0x4e5e) /* unlk %fp */
|
||||
SHORT (0x4e75) /* rts */
|
||||
|
||||
_etext = .;
|
||||
*(.lit)
|
||||
} > ram
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.shdata)
|
||||
*(.data)
|
||||
_edata = .;
|
||||
} > ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
__bss_start = . ;
|
||||
*(.shbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end = ALIGN (0x8);
|
||||
__end = _end;
|
||||
} > ram
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
}
|
26
libgloss/m68k/test.c
Normal file
26
libgloss/m68k/test.c
Normal file
@ -0,0 +1,26 @@
|
||||
extern int led_putnum();
|
||||
extern char print(),putnum();
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
main()
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
outbyte ('&');
|
||||
outbyte ('@');
|
||||
outbyte ('$');
|
||||
outbyte ('%');
|
||||
print ("FooBar\r\n");
|
||||
|
||||
#if 0
|
||||
write (2, "Enter 5 characters... ", 24);
|
||||
read (0, buf, 5);
|
||||
print (buf);
|
||||
print ("\r\n");
|
||||
#endif
|
||||
|
||||
/* whew, we made it */
|
||||
print ("\r\nDone...\r\n");
|
||||
fflush(stdout);
|
||||
}
|
Reference in New Issue
Block a user