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