diff options
author | Stu Grossman <grossman@cygnus> | 1994-03-25 01:38:12 +0000 |
---|---|---|
committer | Stu Grossman <grossman@cygnus> | 1994-03-25 01:38:12 +0000 |
commit | 27847c6f99c457a02816c2082fa91e0a8c408d00 (patch) | |
tree | 202f093abaad0f3caf5ac879f63675ce10aa8b11 /gdb/nlm | |
parent | 193c5f93a17206ea7e83b7ae476e1a997e1ff108 (diff) | |
download | gdb-27847c6f99c457a02816c2082fa91e0a8c408d00.zip gdb-27847c6f99c457a02816c2082fa91e0a8c408d00.tar.gz gdb-27847c6f99c457a02816c2082fa91e0a8c408d00.tar.bz2 |
Netware debugger stub NLM.
Diffstat (limited to 'gdb/nlm')
-rw-r--r-- | gdb/nlm/Makefile.in | 264 | ||||
-rw-r--r-- | gdb/nlm/README-ALPHA-NETWARE | 60 | ||||
-rw-r--r-- | gdb/nlm/alpha-io.S | 875 | ||||
-rw-r--r-- | gdb/nlm/alpha-patch.c | 243 | ||||
-rw-r--r-- | gdb/nlm/alpha-patch.h | 651 | ||||
-rw-r--r-- | gdb/nlm/alpha-regdef.h | 80 | ||||
-rwxr-xr-x | gdb/nlm/alpha-uart.c | 179 | ||||
-rwxr-xr-x | gdb/nlm/alpha-uart.h | 59 | ||||
-rw-r--r-- | gdb/nlm/altdebug.h | 105 | ||||
-rw-r--r-- | gdb/nlm/configure.in | 325 | ||||
-rw-r--r-- | gdb/nlm/gdbserve.c | 1101 | ||||
-rw-r--r-- | gdb/nlm/gdbserve.def | 66 | ||||
-rw-r--r-- | gdb/nlm/prelude.c | 62 | ||||
-rw-r--r-- | gdb/nlm/prelude.o | bin | 0 -> 5184 bytes |
14 files changed, 4070 insertions, 0 deletions
diff --git a/gdb/nlm/Makefile.in b/gdb/nlm/Makefile.in new file mode 100644 index 0000000..36388da --- /dev/null +++ b/gdb/nlm/Makefile.in @@ -0,0 +1,264 @@ +#Copyright 1989, 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + +# This file is part of GDB. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +prefix = /usr/local + +program_transform_name = +exec_prefix = $(prefix) +bindir = $(exec_prefix)/bin +libdir = $(exec_prefix)/lib +tooldir = $(libdir)/$(target_alias) + +datadir = $(prefix)/lib +mandir = $(prefix)/man +man1dir = $(mandir)/man1 +man2dir = $(mandir)/man2 +man3dir = $(mandir)/man3 +man4dir = $(mandir)/man4 +man5dir = $(mandir)/man5 +man6dir = $(mandir)/man6 +man7dir = $(mandir)/man7 +man8dir = $(mandir)/man8 +man9dir = $(mandir)/man9 +infodir = $(prefix)/info +includedir = $(prefix)/include +docdir = $(datadir)/doc + +SHELL = /bin/sh + +INSTALL = `cd $(srcdir)/../..;pwd`/install.sh -c +INSTALL_PROGRAM = $(INSTALL) +INSTALL_DATA = $(INSTALL) +INSTALL_XFORM = $(INSTALL) -t='$(program_transform_name)' +INSTALL_XFORM1 = $(INSTALL_XFORM) -b=.1 + +AR = ar +AR_FLAGS = qv +RANLIB = ranlib + +# Flags that describe where you can find the termcap library. +# This can be overridden in the host Makefile fragment file. +TERMCAP = -ltermcap + +# System V: If you compile gdb with a compiler which uses the coff +# encapsulation feature (this is a function of the compiler used, NOT +# of the m-?.h file selected by config.gdb), you must make sure that +# the GNU nm is the one that is used by munch. + +# If you are compiling with GCC, make sure that either 1) You use the +# -traditional flag, or 2) You have the fixed include files where GCC +# can reach them. Otherwise the ioctl calls in inflow.c +# will be incorrectly compiled. The "fixincludes" script in the gcc +# distribution will fix your include files up. +#CC=cc +#CC=gcc -traditional +GCC=gcc + +# Directory containing source files. Don't clean up the spacing, +# this exact string is matched for by the "configure" script. +srcdir = . + +# It is also possible that you will need to add -I/usr/include/sys to the +# CFLAGS section if your system doesn't have fcntl.h in /usr/include (which +# is where it should be according to Posix). + +# If you use bison instead of yacc, it needs to include the "-y" argument. +#BISON=bison -y +BISON=yacc +YACC=$(BISON) + +# where to find texinfo; GDB dist should include a recent one +TEXIDIR=${srcdir}/../texinfo + +# where to find makeinfo, preferably one designed for texinfo-2 +MAKEINFO=makeinfo + +# Set this up with gcc if you have gnu ld and the loader will print out +# line numbers for undefinded refs. +#CC-LD=gcc -static +CC-LD=${CC} + +# Where is the "include" directory? Traditionally ../include or ./include +INCLUDE_DIR = ${srcdir}/../../include +INCLUDE_DEP = $$(INCLUDE_DIR) + +# Where is the source dir for the MMALLOC library? Traditionally ../mmalloc +# or ./mmalloc (When we want the binary library built from it, we use +# ${MMALLOC_DIR}${subdir}.) +# Note that mmalloc can still be used on systems without mmap(). +# To use your system malloc, comment out the following defines. +MMALLOC_DIR = ${srcdir}/../mmalloc +MMALLOC_DEP = $$(MMALLOC_DIR) +# To use your system malloc, uncomment MMALLOC_DISABLE. +#MMALLOC_DISABLE = -DNO_MMALLOC +# To use mmalloc but disable corruption checking, uncomment MMALLOC_CHECK +#MMALLOC_CHECK = -DNO_MMALLOC_CHECK +MMALLOC_CFLAGS = ${MMALLOC_CHECK} ${MMALLOC_DISABLE} + +# Where is the source dir for the READLINE library? Traditionally in .. or . +# (For the binary library built from it, we use ${READLINE_DIR}${subdir}.) +READLINE_DIR = ${srcdir}/../readline +READLINE_DEP = $$(READLINE_DIR) + +# All the includes used for CFLAGS and for lint. +# -I. for config files. +# -I${srcdir} possibly for regex.h also. +# -I${srcdir}/config for more generic config files. +INCLUDE_CFLAGS = -I. -I${srcdir} -I${srcdir}/.. -I${srcdir}/../config -I$(INCLUDE_DIR) + +# M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS +# from the config/ directory. +GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS} +#PROFILE_CFLAGS = -pg + +# CFLAGS is specifically reserved for setting from the command line +# when running make. I.E. "make CFLAGS=-Wmissing-prototypes". +CFLAGS = -g +# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros. +INTERNAL_CFLAGS = ${CFLAGS} ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} ${MMALLOC_CFLAGS} ${INCLUDE_CFLAGS} ${USER_CFLAGS} +LDFLAGS = $(CFLAGS) + +# Perhaps should come from parent Makefile +VERSION = gdbserve-4.12 +DIST=gdb + +LINT=/usr/5bin/lint +LINTFLAGS= -I${BFD_DIR} + +# Host and target-dependent makefile fragments come in here. +#### +# End of host and target-dependent makefile fragments + +# All source files that go into linking GDB remote server. + +SFILES = $(srcdir)/alpha-patch.c $(srcdir)/alpha-uart.c $(srcdir)/gdbserve.c \ + $(srcdir)/alpha-io.S + +DEPFILES = $(GDBSERVE_DEPFILES) + +SOURCES = $(SFILES) $(ALLDEPFILES) +TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS} + +OBS = gdbserve.o alpha-patch.o alpha-uart.o alpha-io.o $(srcdir)/prelude.o + +# Prevent Sun make from putting in the machine type. Setting +# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1. +.c.o: + ${CC} -c ${INTERNAL_CFLAGS} $< + +all: GDBSERVE.NLM + +# Traditionally "install" depends on "all". But it may be useful +# not to; for example, if the user has made some trivial change to a +# source file and doesn't care about rebuilding or just wants to save the +# time it takes for make to check that all is up to date. +# install-only is intended to address that need. +install: all install-only +install-only: + $(INSTALL_XFORM) gdbserver $(bindir)/gdbserver + $(INSTALL_XFORM1) $(srcdir)/gdbserver.1 $(man1dir)/gdbserver.1 + +uninstall: force + rm -f $(bindir)/gdbserver $(man1dir)/gdbserver.1 +# @$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do + +installcheck: +check: +info dvi: +install-info: +clean-info: + +NWAXPDEV=/gaunt/grossman/ALPHA-NLM/cygnus_940215/nwaxpdev + +.EXPORT: NWAXPDEV + +CC=${NWAXPDEV}/bin/cc -32addr -non_shared -no_excpt -g -DALPHA=1 -std -I -I${NWAXPDEV}/usr/include -I${NWAXPDEV}/clib/include +LD=${NWAXPDEV}/bin/ld -32addr -no_excpt -non_shared -d -r -L -T 0 -g -b +AS=${NWAXPDEV}/bin/as -I. -32addr +NLMCONV=${NWAXPDEV}/bin/alphanlm + +GDBSERVE.NLM: gdbserve $(srcdir)/gdbserve.def + ${NLMCONV} $(srcdir)/gdbserve.def + +gdbserve: $(OBS) + ${LD} $(LDFLAGS) -o gdbserve ${OBS} ${LIBS} ${NWAXPDEV}/usr/lib/nwlibc.a + +gdbserve.o: $(srcdir)/gdbserve.c $(srcdir)/alpha-patch.h + +alpha-patches.o: $(srcdir)/alpha-patches.c $(srcdir)/alpha-patches.h + +alpha-io.o: $(srcdir)/alpha-io.S + ${AS} -o alpha-io.o $(srcdir)/alpha-io.S + +alpha-uart.o: $(srcdir)/alpha-uart.c + +config.status: + @echo "You must configure gdbserver. Look at the README file for details." + @false + +# Put the proper machine-specific files first, so M-. on a machine +# specific routine gets the one for the correct machine. +# The xyzzy stuff below deals with empty DEPFILES +TAGS: ${TAGFILES} + etags `find ${srcdir}/../config -name $(TM_FILE) -print` \ + `find ${srcdir}/../config -name ${XM_FILE} -print` \ + `find ${srcdir}/../config -name ${NAT_FILE} -print` \ + `for i in yzzy ${DEPFILES}; do \ + if [ x$$i != xyzzy ]; then \ + echo ${srcdir}/$$i | sed -e 's/\.o$$/\.c/' ; \ + fi; \ + done` \ + ${TAGFILES} +tags: TAGS + +clean: + rm -f *.o ${ADD_FILES} *~ + rm -f init.c version.c + rm -f gdbserver core make.log + +distclean: clean c-exp.tab.c m2-exp.tab.c ch-exp.tab.c TAGS + rm -f tm.h xm.h config.status + rm -f Makefile + +realclean: clean + rm -f c-exp.tab.c m2-exp.tab.c ch-exp.tab.c TAGS + rm -f tm.h xm.h config.status + rm -f Makefile + +STAGESTUFF=${OBS} ${TSOBS} ${NTSOBS} ${ADD_FILES} init.c init.o version.c gdb + +Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag) + $(SHELL) ./config.status + +force: + +version.c: Makefile + echo 'char *version = "$(VERSION)";' >version.c + +# GNU Make has an annoying habit of putting *all* the Makefile variables +# into the environment, unless you include this target as a circumvention. +# Rumor is that this will be fixed (and this target can be removed) +# in GNU Make 4.0. +.NOEXPORT: + +# GNU Make 3.63 has a different problem: it keeps tacking command line +# overrides onto the definition of $(MAKE). This variable setting +# will remove them. +MAKEOVERRIDES= + +# This is the end of "Makefile.in". diff --git a/gdb/nlm/README-ALPHA-NETWARE b/gdb/nlm/README-ALPHA-NETWARE new file mode 100644 index 0000000..b092f71 --- /dev/null +++ b/gdb/nlm/README-ALPHA-NETWARE @@ -0,0 +1,60 @@ +This is a preliminary release of GDB and GDBSERVE.NLM for Alpha/Netware. + +Building this release is very straightforward. You just need to do the +following: + + 1) Unpack the release. gunzip < gdb-4.12.3.tar.gz | tar xvf - + should do the trick. + 2) cd gdb-4.12.3 + 3) ./configure --target alpha-netware + 4) make BISON=yacc [You can use either gcc, or the DEC compiler here]. + +Building GDBSERVE.NLM: + + 1) cd gdb-4.12.3/gdb/nlm + 2) Edit Makefile, and change the value to NWAXPDEV to point at the + DEC development kit. + 3) make + +To debug a program, you need to install GDBSERVE.NLM on your server in +[SYSTEM] (or, anywhere in your search path). Then, connect your netware +server to the host with a null modem cable. Start up the app you want to +debug by doing `gdbserve 0 0 APPNAME APP-ARGS ...'. At this point, the +server will be stopped inside of GDBSERVE, waiting for debugger commands +from the serial line. Now, you run GDB on a copy of the app .o file, +and do a target command to connect to the server. `gdb foo.o', then +(gdb) target remote /dev/tty00. Note that foo.o should not be the NLM. +It should be the file that is input to alphanlm or nlmconv. + +At this point, GDB should be paused at the first instruction of the program +(that's probably _Prelude). You can put a breakpoint at main, and then do +a continue command to debug your program. At that point, normal step/next +commands, backtrace, etc should work. + +Known problems: + +Sometimes you will see messages like the following: + warning: Hit heuristic-fence-post without finding + warning: enclosing function for address 0x1112f1f0 +These can be ignored. They are usually associated with stepping over +external functions (like printf). + +Function calling (ie: print foo(42)) is very slow. A fix for this is in +the works. + +Due to last minute problems with GAS, I was not able to build GDBSERVE.NLM +with our tools, and I was unable to test code compiled with our tools. This +should not be a problem, as GDB will quite happily debug programs compiled +with either GCC, or the DEC tools. For the time being, GDBSERVE will be +compiled with the DEC tools. + +We can't build prelude.o because the DEC dev kit didn't supply libhooks.h. +For the time being, I have just copied prelude.o from the DEC dev kit into +the GDB kit. + +In case of problems: + +If GDB hangs when talking to the target, try turning on remote debugging +(you can use ^C to wake up GDB if necessary). To do this, just type +`set remotedebug 1'. This will print out the protocol packets whenever +GDB and GDBSERVE talk to each other. diff --git a/gdb/nlm/alpha-io.S b/gdb/nlm/alpha-io.S new file mode 100644 index 0000000..7bb5001 --- /dev/null +++ b/gdb/nlm/alpha-io.S @@ -0,0 +1,875 @@ +/* + * Copyright (C) 1993, 1994 by + * Digital Equipment Corporation, Maynard, Massachusetts. + * All rights reserved. + * + * This software is furnished under a license and may be used and copied + * only in accordance of the terms of such license and with the + * inclusion of the above copyright notice. This software or any other + * copies thereof may not be provided or otherwise made available to any + * other person. No title to and ownership of the software is hereby + * transferred. + * + * The information in this software is subject to change without notice + * and should not be construed as a commitment by Digital Equipment + * Corporation. + * + * Digital assumes no responsibility for the use or reliability of its + * software on equipment which is not supplied by Digital. + * + */ + + +/*#include "kxalpha.h"*/ +#include "alpha-regdef.h" + +#define LEAF_ENTRY(NAME) .text ; .align 4 ; .globl NAME ; .ent NAME, 0 ; NAME: ; .frame sp, 0, ra ; .prologue 0 ; + + +#define PICIACKADR 0xfffffc0100000000 +#define EISABAD 0xfffffc0200000000 +#define EISABIO 0xfffffc0300000000 +#define EISA_SHIFT 7 +#define EISA_BYTE_ADJ 0x80 +#define EISA_WORD_ADJ 0x100 +#define EISA_LONG_ADJ 0x200 +#define HALF_USEC 75 +#define ONE_USEC 150 + + +LEAF_ENTRY(flush_i_cache) + call_pal 0x86 // IMB + ret zero, (ra) // return + .end outportb + +//++ +// +// VOID +// { outportX +// ULONG port +// ULONG data +// ) +// X variants are: +// +// b - byte 8 bits +// w - word 16 bits +// t - tri-byte 24 bits +// l - long 32 bits +// +// +// Routine Description: +// +// This function uses the 64-bit super-page to write data to a port +// of the EISA bus for JENSEN. Only AT (ISA) cycles are supported. +// +// Arguments: +// +// port (a0) - port address on the EISA to which to write data +// data (a1) - data to write to the port. +// +// +// Return Value: +// +// None. +// +//-- + + +//+ +// outportb +//-- + LEAF_ENTRY(outportb) + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,3,t0 // get byte index from address + insbl a1,t0,t5 // put byte in proper position + and a0,0x1ffffff,t1 // 25 bit mask + ldiq t0,EISABIO // get EISA IO base address + sll t1, 7, a0 // shift 7 for EISA + bis t0,a0,t0 // t0 = address of EISA + stl t5, 0(t0) // write data to port + mb // guarantee write ordering + ret zero, (ra) // return + .end outportb + + +//+ +// outportw +//-- + LEAF_ENTRY(outportw) + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,3,t0 // get byte index from address + inswl a1,t0,t5 // put byte in proper position + and a0,0x1ffffff,t1 // 25 bit mask + ldiq t0,EISABIO // get EISA IO base address + or t0,0x20,t0 // t0 = ffff fc03 0000 0020 - word + sll t1, 7, a0 // shift 7 for EISA + bis t0,a0,t0 // t0 = address of EISA + stl t5, 0(t0) // write data to port + mb // guarantee write ordering + ret zero, (ra) // return + .end outportw + + +//+ +// outportl +//-- + LEAF_ENTRY(outportl) + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,0x1ffffff,t1 // 25 bit mask + ldiq t0,EISABIO // get EISA IO base address + or t0,0x60,t0 // t0 = ffff fc03 0000 0060 - long + sll t1, 7, a0 // shift 7 for EISA + bis t0,a0,t0 // t0 = address of EISA + stl a1, 0(t0) // write data to port + mb // guarantee write ordering + ret zero, (ra) // return + .end outportl + + + +//+ +// vgastl +//-- + LEAF_ENTRY(vgastl) + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + sra a0, 3, t0 // right shift addr by 3 + and t0, 3, t1 // and addr with 3 + s8addq t1, zero, t2 // multiply by 8 + sll a1, t2, t3 // left shift data + sll a0, 4, t4 // left shift addr by 4 + lda t0,0xfc00 // t0 = 0000 0000 0000 0c00 + ldah t0,-1(t0) // t0 = ffff ffff ffff 0c00 + sll t0,32,t0 // t0 = ffff fc00 0000 0000 + or t0,t4,t4 // make io address + stl t3, 0(t4) // store data + mb // guarantee write ordering + ret zero, (ra) // return + .end vgastl + + + + +//++ +// +// ULONG +// inportX( +// ULONG port +// ) +// +// X variants are: +// +// b - byte 8 bits +// w - word 16 bits +// t - tri-byte 24 bits +// l - long 32 bits +// +// Routine Description: +// +// This function uses the 64-bit super-page to read data from an EISA +// port for JENSEN. +// +// Arguments: +// +// port (a0) - EISA port number. +// +// Return Value: +// +// data (v0) - the data read and only the low byte is valid +// +//-- + +//+ +// inportb +//-- + LEAF_ENTRY(inportb) + + // + // generate super-page address of EISA, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,0x1ffffff,t1 // 25 bit mask + ldiq t0,EISABIO // get EISA IO base address + sll t1, 7, t2 // shift 7 for EISA + bis t0,t2,t0 // t0 = address of EISA + ldl v0, 0(t0) // get EISA IO byte + and a0,0x3,t1 // setup word shift count + extbl v0,t1,v0 // put into low byte + ret zero, (ra) // return + .end inportb + + +//+ +// inportw +//-- + LEAF_ENTRY(inportw) + // + // generate super-page address of vti, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,0x1ffffff,t1 // 25 bit mask + ldiq t0,EISABIO // get EISA IO base addr + or t0,0x20,t0 // t0 = ffff fc03 0000 0020 - word + sll t1, 7, t2 // shift 7 for EISA + bis t0,t2,t0 // t0 = address of EISA + ldl v0, 0(t0) // load EISA word + and a0,0x3,t1 // setup shift count + extwl v0,t1,v0 // put into low word + ret zero, (ra) // return + .end inportw + + + +//+ +// inportl +//-- + LEAF_ENTRY(inportl) + // + // generate super-page address of vti, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,0x1ffffff,t1 // 25 bit mask + ldiq t0,EISABIO // get EISA IO base address + or t0,0x60,t0 // t0 = ffff fc03 0000 0060 + sll t1, 7, t2 // shift 7 for EISA + bis t0,t2,t0 // t0 = address of EISA + ldl v0, 0(t0) // load EISA word + ret zero, (ra) // return + .end inportl + + +//+ +// vgaldl +//-- + LEAF_ENTRY(vgaldl) + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + sll a0, 4, t5 // left shift address by 4 + lda t0,0xfc00 // t0 = 0000 0000 0000 fc00 + ldah t0,-1(t0) // t0 = ffff ffff ffff fc00 + sll t0,32,t0 // t0 = ffff fc00 0000 0000 + or t0,t5,t0 // make io address + ldl t4, 0(t0) // load data + sra a0, 3, t1 // right shift addr by 3 + and t1, 3, t2 // and addr with 3 + s8addq t2, zero, t3 // multiply by 8 + srl t4, t3, v0 // right shift data + ret zero, (ra) // return + .end vgaldl + + + + +//+ +// inIack +//-- + + LEAF_ENTRY(inIack) + + // + // get Iack from pic, need two to get the vector + // + ldiq t0,PICIACKADR + ldl v0,0(t0) // load data + and v0,0xff,v0 // make it a byte + ret zero, (ra) // return + .end inIack + + + + + + LEAF_ENTRY(outmemb) + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,3,t0 // get byte index from address + insbl a1,t0,t5 // put byte in proper position + + and a0,0x1ffffff,t1 // 25 bit mask + ldiq t0,EISABAD // get EISA address + + sll t1, 7, a0 // shift 7 for EISA + bis t0,a0,t0 // t0 = address of EISA + stl t5, 0(t0) // write data to port + ret zero, (ra) // return + + .end outmemb + + + + LEAF_ENTRY(outmemw) + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,3,t0 // get byte index from address + inswl a1,t0,t5 // put byte in proper position + + and a0,0x1ffffff,t1 // 25 bit mask + + ldiq t0,EISABAD // get EISA address + or t0,0x20,t0 // t0 = ffff fc02 0000 0020 - word + + sll t1, 7, a0 // shift 7 for EISA + bis t0,a0,t0 // t0 = address of EISA + stl t5, 0(t0) // write data to port + ret zero, (ra) // return + + .end outmemw + + + + + LEAF_ENTRY(outmeml) + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,0x1ffffff,t1 // 25 bit mask + + ldiq t0,EISABAD // get EISA address + or t0,0x60,t0 // t0 = ffff fc02 0000 0060 - long + + sll t1, 7, a0 // shift 7 for EISA + bis t0,a0,t0 // t0 = address of EISA + stl a1, 0(t0) // write data to port + ret zero, (ra) // return + + .end outmeml + + + + LEAF_ENTRY(outbuffb) + + /* Arguments: + a0 address of destination buffer (byte aligned). + a1 address of source buffer in memory (byte aligned) + a2 Number of bytes to move (Count). + */ + + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + beq a2, donewb // leave if nothing to do + + ldiq t0,EISABAD // get EISA address + + and a0,3,t3 // get byte index from dst address + + and a0,0x1ffffff,t1 // 25 bit mask + sll t1,EISA_SHIFT,t4 // shift 7 for EISA + bis t0,t4,t0 // t0 = address of EISA + +loopwb: + ldq_u t1, 0(a1) // get src data + subl a2, 1, a2 // decrement count + extbl t1, a1,t1 // extract byte + addl a1, 1, a1 // point ot next src address + insbl t1,t3,t1 // insert byte in proper place + stl t1, 0(t0) // write data to EISA memory + addq t0,EISA_BYTE_ADJ, t0 // increment EISA memory pointer + addl t3,1,t3 // increment index + and t3,3,t3 // mask off overflow + bne a2, loopwb +donewb: + ret zero, (ra) + + .end outbuffb + + + + LEAF_ENTRY(outbuffw) + + /* Arguments: + a0 address of destination buffer (word aligned), eisa. + a1 address of source buffer in memory (word aligned) + a2 Number of words to move (Count). + */ + + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + beq a2, doneww // leave if nothing to do + + ldiq t0,EISABAD // get EISA address + or t0,0x20,t0 // t0 = ffff fc02 0000 0020 - word + + and a0,3,t3 // get word index from dst address + + and a0,0x1ffffff,t1 // 25 bit mask + sll t1,EISA_SHIFT,t4 // shift 7 for EISA + bis t0,t4,t0 // t0 = address of EISA + +loopww: + ldq_u t1, 0(a1) // get src data + subl a2, 1, a2 // decrement count + extwl t1, a1,t1 // extract word + addl a1, 2, a1 // point ot next src address + inswl t1,t3,t1 // insert in proper place + stl t1, 0(t0) // write data to EISA memory + addq t0,EISA_WORD_ADJ, t0 // increment EISA memory pointer + addl t3,2,t3 // increment index + and t3,3,t3 // mask off overflow + bne a2, loopww +doneww: + ret zero, (ra) + + .end outbuffw + + + + + + LEAF_ENTRY(outbuffl) + + /* Arguments: + a0 address of destination buffer (long aligned), eisa. + a1 address of source buffer in memory (long aligned) + a2 Number of longs to move (Count). + */ + + // + // generate super-page address of EISA base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + beq a2, donewl // leave if nothing to do + + ldiq t0,EISABAD // get EISA address + or t0,0x60,t0 // t0 = ffff fc02 0000 0060 - long + + and a0,0x1ffffff,t1 // 25 bit mask + sll t1,EISA_SHIFT,t4 // shift 7 for EISA + bis t0,t4,t0 // t0 = address of EISA + +loopwl: + ldl t1, 0(a1) // get src data + subl a2, 1, a2 // decrement count + stl t1, 0(t0) // write data to EISA memory + addl a1, 4, a1 // point ot next src address + addq t0,EISA_LONG_ADJ, t0 // increment EISA memory pointer + bne a2, loopwl +donewl: + ret zero, (ra) + + .end outbuffw + + + + LEAF_ENTRY(inmemb) + + // + // generate super-page address of EISA, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,0x1ffffff,t1 // 25 bit mask + + ldiq t0,EISABAD // get EISA address + + sll t1, 7, t2 // shift 7 for EISA + bis t0,t2,t0 // t0 = address of EISA + ldl v0, 0(t0) // get EISA byte + + and a0,0x3,t1 // setup word shift count + extbl v0,t1,v0 // put into low byte + + ret zero, (ra) // return + + .end inmemb + + + + + LEAF_ENTRY(inmemw) + + // + // generate super-page address of EISA, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,0x1ffffff,t1 // 25 bit mask + + ldiq t0,EISABAD // get EISA base addr + or t0,0x20,t0 // t0 = ffff fc02 0000 0020 - word + + sll t1, 7, t2 // shift 7 for EISA + bis t0,t2,t0 // t0 = address of EISA + + ldl v0, 0(t0) // get EISA short + + and a0,0x3,t1 // setup byte shift count + extwl v0,t1,v0 // put into low word + + ret zero, (ra) // return + + .end inmemw + + + + + LEAF_ENTRY(inmeml) + + // + // generate super-page address of EISA, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + and a0,0x1ffffff,t1 // 25 bit mask + + ldiq t0,EISABAD // get EISA base address + or t0,0x60,t0 // t0 = ffff fc02 0000 0060 - long + + sll t1, 7, t2 // shift 7 for EISA + bis t0,t2,t0 // t0 = address of EISA + + ldl v0, 0(t0) // get EISA 4 bytes + ret zero, (ra) // return + + .end inmeml + + + + + LEAF_ENTRY(inbuffb) + + /* + Arguments: + + a0 source buffer in eisa bus memory. + a1 destination buffer in memory. + a2 Number of bytes to move (Count). + */ + + // + // generate super-page address of EISA, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + beq a2, donerb // leave if nothing to do + + ldiq t0,EISABAD // get EISA base address + + and a0,3,t3 // get byte index from src address + + and a0,0x1ffffff,t1 // 25 bit mask + sll t1, EISA_SHIFT, t4 // shift 7 for EISA + bis t0,t4,t0 // t0 = address of EISA + +looprb: + ldl t1, 0(t0) // get EISA 4 bytes + subl a2, 1, a2 // decrement byte count + extbl t1, t3, t1 // extract byte + addq t0, EISA_BYTE_ADJ, t0 // increment EISA address + stb t1, 0(a1) // assembler preserves the memory + // behind the newly stored byte + addl a1, 1, a1 // increment memory pointer + addl t3, 1, t3 // point to next byte in long + and t3, 3, t3 // get new index + bne a2, looprb +donerb: + ret zero, (ra) // return + + .end inbuffb + + + + + LEAF_ENTRY(inbuffw) + /* + Arguments: + + a0 source buffer in eisa bus memory. + a1 destination buffer in memory. + a2 Number of words to move (Count). + */ + + + // + // generate super-page address of EISA, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + beq a2, donerw // leave if nothing to do + + ldiq t0,EISABAD // get EISA base address + or t0,0x20,t0 // t0 = ffff fc02 0000 0020 - word + + + and a0,3,t3 // get byte index from src address + + and a0,0x1ffffff,t1 // 25 bit mask + sll t1, EISA_SHIFT, t4 // shift 7 for EISA + bis t0,t4,t0 // t0 = address of EISA + +looprw: + ldl t1, 0(t0) // get EISA 4 bytes + subl a2, 1, a2 // decrement word count + extwl t1, t3, t1 // extract word + addq t0, EISA_WORD_ADJ, t0 // increment EISA address + stw t1, 0(a1) // store in dst memory + addl a1, 2, a1 // increment memory pointer + addl t3, 2, t3 // point to next word in long + and t3, 3, t3 // get new index + bne a2, looprw +donerw: + ret zero, (ra) // return + + .end inbuffw + + + + LEAF_ENTRY(inbuffl) + /* + Arguments: + + a0 source buffer in eisa bus memory. + a1 destination buffer in memory. + a2 Number of longs to move (Count). + */ + + // + // generate super-page address of EISA, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + beq a2, donerl // leave if nothing to do + + ldiq t0,EISABAD // get EISA base address + or t0,0x60,t0 // t0 = ffff fc02 0000 0060 - long + + and a0,0x1ffffff,t1 // 25 bit mask + sll t1, EISA_SHIFT, t4 // shift 7 for EISA + bis t0,t4,t0 // t0 = address of EISA + +looprl: + ldl v0, 0(t0) // get EISA 4 bytes + subl a2, 1, a2 // decrement long count + stl v0, 0(a1) // store in dst memory + addl a1, 4, a1 // increment memory pointer + addq t0, EISA_LONG_ADJ, t0 // increment EISA address + bne a2, looprl +donerl: + ret zero, (ra) // return + + .end inbuffl + + + + LEAF_ENTRY(inctl) + + // + // generate super-page address of EISA, base address + // upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + lda t0,0xfc01 // t0 = 0000 0000 0000 fc01 + ldah t0,-1(t0) // t0 = ffff ffff ffff fc01 + sll t0,32,t0 // t0 = ffff fc01 0000 0000 + bis t0,0xe0000000,t0 // t0 = ffff fc01 e000 0000 + + ldl v0, 0(t0) // get EISA byte + and v0,0xff,v0 + + ret zero, (ra) // return + + .end inctl + + + + +//++ +// +// VOID +// outVti( +// ULONG port +// ULONG data +// ) +// +// Routine Description: +// +// This function uses the 64-bit super-page to write data to a port +// of the on-board VTI combo chip for JENSEN. +// +// Arguments: +// +// port (a0) - port number on VTI chip to which to write data +// data (a1) - data to write to the port, only low byte is significant +// to the VTI +// +// Return Value: +// +// None. +// +//-- + + LEAF_ENTRY(outVti) + + // + // generate super-page address of vti, base address + // N.B. - upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + + lda t0, 0xc01c(zero) // t0 = 0000 0000 0000 c01c + ldah t0, -1(t0) // t0 = ffff ffff ffff c01c + sll t0, 28, t0 // t0 = ffff fc01 c000 0000 + + + // + // Shift in the port number to generate the port address we + // wish to access + // N.B. - access width is always zero = byte access for VTI + // + + sll a0, 9, a0 // a0 << 9 + bis t0, a0, t0 // t0 = address of VTI port + + + // + // Do the port write, guarantee that subsequent writes (and reads) + // are ordered with respect to this write and return to caller + // + + stl a1, 0(t0) // write data to port + mb // guarantee write ordering + + ret zero, (ra) // return + + .end outVti + + + +//++ +// +// ULONG +// inVti( +// ULONG port +// ) +// +// Routine Description: +// +// This function uses the 64-bit super-page to read data from a port +// of the on-board VTI combo chip for JENSEN. +// +// Arguments: +// +// port (a0) - port number on VTI chip to which to write data +// +// Return Value: +// +// data (v0) - the data read from the VTI chip, only the low byte will +// be valid +// +//-- + + LEAF_ENTRY(inVti) + + // + // generate super-page address of vti, base address + // N.B. - upper bits must be sign extension of bit 42 + // va<42:41> = 10 (binary) for super-page address + // + + lda t0, 0xc01c(zero) // t0 = 0000 0000 0000 c01c + ldah t0, -1(t0) // t0 = ffff ffff ffff c01c + sll t0, 28, t0 // t0 = ffff fc01 c000 0000 + + + // + // Shift in the port number to generate the port address we + // wish to access + // N.B. - access width for VTI is always 0 = byte access + // + + sll a0, 9, a0 // a0 << 9 + bis t0, a0, t0 // t0 = address of VTI port + + + // + // Do the super-page i/o access and return data to caller + // + + ldl v0, 0(t0) // read data from port + and v0, 0xff, v0 + + ret zero, (ra) // return + + .end inVti + + + +LEAF_ENTRY(delay_us) + bis zero, ONE_USEC, t1 + rpcc t0 /* RCC T0, read cycle counter */ + +loop0: rpcc t2 /* RCC T2, read cycle counter */ + subl t2, t0, t2 /* check for wrapping */ + bge t2, over0 /* check, and see if negative */ + + ornot t0, zero, t4 /* calculate the offset */ + zap t4, 0xf0, t4 + cmplt t4, t1, t2 + beq t2, done0 + subl t1, t4, t1 /* adjust the counter */ + and zero, t0, t0 /* set t0 to zero */ + +over0: cmplt t2, t1, t2 /* compare these for usec timer */ + bne t2, loop0 /* stay in... */ +done0: ret zero, (ra) + .end delay_us + + + +LEAF_ENTRY(delay_500ns) + bis zero, HALF_USEC, t1 + rpcc t0 /* RCC T0, read cycle counter */ + +loop1: rpcc t2 /* RCC T2, read cycle counter */ + subl t2, t0, t2 /* check for wrapping */ + bge t2, over1 /* check, and see if negative */ + + ornot t0, zero, t4 /* calculate the offset */ + zap t4, 0xf0, t4 + cmplt t4, t1, t2 + beq t2, done1 + subl t1, t4, t1 /* adjust the counter */ + and zero, t0, t0 /* set t0 to zero */ + +over1: cmplt t2, t1, t2 /* compare these for usec timer */ + bne t2, loop1 /* stay in... */ +done1: ret zero, (ra) + .end delay_500ns + + + diff --git a/gdb/nlm/alpha-patch.c b/gdb/nlm/alpha-patch.c new file mode 100644 index 0000000..7128c3c --- /dev/null +++ b/gdb/nlm/alpha-patch.c @@ -0,0 +1,243 @@ +#include <nwtypes.h> +#include "alpha-patch.h" +#include <errno.h> +#include <stdio.h> + +#define CONST const + +/* This file provides stubs and equivalent interfaces for all functions that + the debugger stub needs, but aren't yet implemented. */ + +int +AIOReadData (int portHandle, char *buffer, LONG length, LONG *numberBytesRead) +{ + ULONG c; + + while (1) + { + c = com_interrupt (); + if ((c & ~0377) == COM1) + break; + } + + *buffer = c; + *numberBytesRead = 1; + + return AIO_SUCCESS; +} + +int +AIOWriteData (int portHandle, char *buffer, LONG length, + LONG *numberBytesWritten) + +{ + *numberBytesWritten = length; + + while (length-- > 0) + uart_putchar (COM1, *buffer++); + + return AIO_SUCCESS; +} + +int +AIOAcquirePort (int *hardwareType, int *boardNumber, int *portNumber, + int *portHandle) +{ + return AIO_SUCCESS; +} + +int +AIOConfigurePort (int portHandle, BYTE bitRate, BYTE dataBits, BYTE stopBits, + BYTE parityMode, BYTE flowCtrlMode) +{ + uart_init_line (1, 9600); + + return AIO_SUCCESS; +} + +int +AIOGetPortConfiguration (int portHandle, AIOPORTCONFIG *pPortConfig, + AIODVRCONFIG *pDvrConfig) +{ + fprintf (stderr, "AIOGetPortConfiguration stubbed out\n"); + exit (1); +} + +int +AIOReleasePort (int portHandle) +{ + return AIO_SUCCESS; +} + +int +AIOSetExternalControl (int portHandle, int requestType, int requestValue) +{ + return AIO_SUCCESS; +} + +int +AIOGetExternalStatus (int portHandle, LONG *extStatus, LONG *chgdExtStatus) +{ + fprintf (stderr, "AIOGetExternalStatus stubbed out\n"); + exit (1); +} + +void +StopBell () +{ +} + +int +Breakpoint (int __arg) +{ + fprintf (stderr, "Breakpoint() stubbed out\n"); + exit (1); +} + +/* + * strtol : convert a string to long. + * + * Andy Wilson, 2-Oct-89. + */ + +/* FIXME: It'd be nice to configure around these, but the include files are too + painful. These macros should at least be more portable than hardwired hex + constants. */ + +#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ +#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF */ +#define LONG_MIN ((long)(~LONG_MAX)) /* 0x80000000 */ + +extern int errno; + +long +strtol(s, ptr, base) + CONST char *s; char **ptr; int base; +{ + extern unsigned long strtoul(); + int minus=0; + unsigned long tmp; + CONST char *start=s, *eptr; + + if (s==NULL) + { + errno = ERANGE; + if (!ptr) + *ptr = (char *)start; + return 0L; + } + while (isspace(*s)) + s++; + if (*s == '-') { + s++; + minus = 1; + } + else if (*s == '+') + s++; + + /* + * let strtoul do the hard work. + */ + tmp = strtoul(s, &eptr, base); + if (ptr != NULL) + *ptr = (char *)((eptr==s) ? (char *)start : eptr); + if (tmp > (minus ? - (unsigned long) LONG_MIN : (unsigned long) LONG_MAX)) + { + errno = ERANGE; + return (minus ? LONG_MIN : LONG_MAX); + } + return (minus ? (long) -tmp : (long) tmp); +} + +/* + * strtol : convert a string to long. + * + * Andy Wilson, 2-Oct-89. + */ + +#ifndef ULONG_MAX +#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ +#endif + +extern int errno; + +unsigned long +strtoul(s, ptr, base) + CONST char *s; char **ptr; int base; +{ + unsigned long total = 0; + unsigned digit; + CONST char *start=s; + int did_conversion=0; + int overflow = 0; + int negate = 0; + unsigned long maxdiv, maxrem; + + if (s==NULL) + { + errno = ERANGE; + if (!ptr) + *ptr = (char *)start; + return 0L; + } + + while (isspace(*s)) + s++; + if (*s == '+') + s++; + else if (*s == '-') + s++, negate = 1; + if (base==0 || base==16) /* the 'base==16' is for handling 0x */ + { + int tmp; + + /* + * try to infer base from the string + */ + if (*s != '0') + tmp = 10; /* doesn't start with 0 - assume decimal */ + else if (s[1] == 'X' || s[1] == 'x') + tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */ + else + tmp = 8; /* starts with 0 - hence octal */ + if (base==0) + base = (int)tmp; + } + + maxdiv = ULONG_MAX / base; + maxrem = ULONG_MAX % base; + + while ((digit = *s) != '\0') + { + if (digit >= '0' && digit < ('0'+base)) + digit -= '0'; + else + if (base > 10) + { + if (digit >= 'a' && digit < ('a'+(base-10))) + digit = digit - 'a' + 10; + else if (digit >= 'A' && digit < ('A'+(base-10))) + digit = digit - 'A' + 10; + else + break; + } + else + break; + did_conversion = 1; + if (total > maxdiv + || (total == maxdiv && digit > maxrem)) + overflow = 1; + total = (total * base) + digit; + s++; + } + if (overflow) + { + errno = ERANGE; + if (ptr != NULL) + *ptr = (char *)s; + return (ULONG_MAX); + } + if (ptr != NULL) + *ptr = (char *) ((did_conversion) ? (char *)s : (char *)start); + return negate ? -total : total; +} diff --git a/gdb/nlm/alpha-patch.h b/gdb/nlm/alpha-patch.h new file mode 100644 index 0000000..4452f09 --- /dev/null +++ b/gdb/nlm/alpha-patch.h @@ -0,0 +1,651 @@ +/* This contains defs for the stubs defined in alpha-patch.c. Many of these + defs are ripped off of other files. */ + +#include "altdebug.h" /* Get StackFrame structure */ + +/* -=-=-= aio.h -=-=-= */ + +/*----------------------------------------------------------------------------* + * * + * NetWare 386 Developer's Asynchronous I/O (AIO) Runtime library * + * * + * This include file defines the constants and prototypes required * + * to use the AIO application interface. * + * * + * (c) Copyright. 1991 Novell, Inc. All rights reserved. * + * * + *----------------------------------------------------------------------------*/ + +typedef unsigned long DWORD; + + +/*----------------------------------------------------------------------------* + * * + * Predefined hardware types for use with the AIOAcquirePort function. * + * * + *----------------------------------------------------------------------------*/ + +#define AIO_COMX_TYPE (1) +#define AIO_ARTIC_TYPE (2) +#define AIO_WNIM_TYPE (3) + + +/*----------------------------------------------------------------------------* + * * + * Function completion code status values. * + * * + * Note that all error statuses are negative values. * + * * + *----------------------------------------------------------------------------*/ + +#define AIO_SUCCESS (0) +#define AIO_BAD_HANDLE (-1) +#define AIO_FAILURE (-2) +#define AIO_FUNC_NOT_SUPPORTED (-3) +#define AIO_INVALID_PARAMETER (-5) +#define AIO_PORT_NOT_AVAILABLE (-6) +#define AIO_QUALIFIED_SUCCESS (-7) +#define AIO_NO_MORE_PORTS (-8) +#define AIO_TYPE_NUMBER_INVALID (-10) +#define AIO_BOARD_NUMBER_INVALID (-11) +#define AIO_PORT_NUMBER_INVALID (-12) +#define AIO_RESOURCE_TAG_INVALID (-13) +#define AIO_DATA_PRESENT (-14) +#define AIO_BAD_REQUEST_TYPE (-15) +#define AIO_PORT_GONE (-20) +#define AIO_RTAG_INVALID (-21) + + +/* This is only for non-CLIB application */ + +#define ASYNCIOSignature 0x4E595341 /* 'NYSA' */ + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOSetExternalControl function. * + * * + *----------------------------------------------------------------------------*/ + +#define AIO_EXTERNAL_CONTROL (1) +#define AIO_EXTCTRL_DTR (1) +#define AIO_EXTCTRL_RTS (2) + + +#define AIO_BREAK_CONTROL (2) +#define AIO_SET_BREAK_OFF (0) +#define AIO_SET_BREAK_ON (1) + + +#define AIO_FLOW_CONTROL (3) +#define AIO_SOFTWARE_FLOW_CONTROL_OFF (0) +#define AIO_SOFTWARE_FLOW_CONTROL_ON (1) +#define AIO_HARDWARE_FLOW_CONTROL_OFF (0) +#define AIO_HARDWARE_FLOW_CONTROL_ON (2) + + +#define AIO_FLOW_CONTROL_CHARACTERS (4) + +#define AIO_SET_DEADMAN_TIMER (5) + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOGetExternalStatus function. * + * * + *----------------------------------------------------------------------------*/ + +#define AIO_EXTSTA_RI (0x00000001) +#define AIO_EXTSTA_DCD (0x00000008) +#define AIO_EXTSTA_DSR (0x00000010) +#define AIO_EXTSTA_CTS (0x00000020) +#define AIO_EXTSTA_BREAK (0x00000080) + + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOFlushBuffers function. * + * * + *----------------------------------------------------------------------------*/ + +#define AIO_FLUSH_WRITE_BUFFER (0x0001) +#define AIO_FLUSH_READ_BUFFER (0x0002) + + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOReadStatus function. * + * * + *----------------------------------------------------------------------------*/ + +#define AIO_RECEIVE_ACTIVE (0) +#define AIO_RECEIVE_FULL (1) + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOWriteStatus function. * + * * + *----------------------------------------------------------------------------*/ + +#define AIO_TRANSMIT_IDLE (0) +#define AIO_TRANSMIT_ACTIVE (1) +#define AIO_TRANSMIT_XOFFED (2) + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOAcquirePort function. * + * * + *----------------------------------------------------------------------------*/ + +#define AIO_HARDWARE_TYPE_WILDCARD (-1) +#define AIO_BOARD_NUMBER_WILDCARD (-1) +#define AIO_PORT_NUMBER_WILDCARD (-1) + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOConfigurePort function. * + * * + *----------------------------------------------------------------------------*/ + +/* BitRate */ + +#define AIO_BAUD_50 (0) +#define AIO_BAUD_75 (1) +#define AIO_BAUD_110 (2) +#define AIO_BAUD_134p5 (3) +#define AIO_BAUD_150 (4) +#define AIO_BAUD_300 (5) +#define AIO_BAUD_600 (6) +#define AIO_BAUD_1200 (7) +#define AIO_BAUD_1800 (8) +#define AIO_BAUD_2000 (9) +#define AIO_BAUD_2400 (10) +#define AIO_BAUD_3600 (11) +#define AIO_BAUD_4800 (12) +#define AIO_BAUD_7200 (13) +#define AIO_BAUD_9600 (14) +#define AIO_BAUD_19200 (15) +#define AIO_BAUD_38400 (16) +#define AIO_BAUD_57600 (17) +#define AIO_BAUD_115200 (18) + +/* DataBits */ + +#define AIO_DATA_BITS_5 (0) +#define AIO_DATA_BITS_6 (1) +#define AIO_DATA_BITS_7 (2) +#define AIO_DATA_BITS_8 (3) + +/* StopBits */ + +#define AIO_STOP_BITS_1 (0) +#define AIO_STOP_BITS_1p5 (1) +#define AIO_STOP_BITS_2 (2) + +/* Parity */ + +#define AIO_PARITY_NONE (0) +#define AIO_PARITY_ODD (1) +#define AIO_PARITY_EVEN (2) +#define AIO_PARITY_MARK (3) +#define AIO_PARITY_SPACE (4) + +/* FlowControl */ + +#define AIO_SOFTWARE_FLOWCONTROL_OFF (0) +#define AIO_SOFTWARE_FLOWCONTROL_ON (1) +#define AIO_HARDWARE_FLOWCONTROL_OFF (0) +#define AIO_HARDWARE_FLOWCONTROL_ON (2) + +#define AIO_DROPOUT_VALUE (0xFF) + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with AIOPORTCAPABILITIES structure. * + * * + *----------------------------------------------------------------------------*/ + +typedef struct + { + WORD returnLength; /* byte length of capabilities data */ + BYTE majorVersion; + BYTE minorVersion; + LONG notSupportedMask; + BYTE minBitRate; /* minimum bit rate index supported */ + BYTE maxBitRate; /* maximum bit rate index supported */ + BYTE minDataBits; /* minimum data bits per char index supported */ + BYTE maxDataBits; /* maximum data bits per char index supported */ + BYTE minStopBits; /* minimum stop bits per char index supported */ + BYTE maxStopBits; /* maximum stop bits per char index supported */ + BYTE minParityMode; /* minimum parity mode index supported */ + BYTE maxParityMode; /* maximum parity mode index supported */ + BYTE minFlowCtrlMode; /* minimum flow control mode index supported */ + BYTE maxFlowCtrlMode; /* maximum flow control mode index supported */ + LONG miscCapabilities; /* miscellaneous capability flags */ + LONG minReadBufferSize; /* minimum length of receive buffer */ + LONG maxReadBufferSize; /* maximum length of receive buffer */ + LONG minWriteBufferSize; /* minimum length of transmit buffer */ + LONG maxWriteBufferSize; /* maximum length of transmit buffer */ + WORD minDeadmanTime; /* minimum deadman time (seconds) */ + WORD maxDeadmanTime; /* maximum deadman time (seconds) */ + } AIOPORTCAPABILITIES; + +#define AIO_PORT_NS_MINBITRATE (0x80000000) +#define AIO_PORT_NS_MAXBITRATE (0x40000000) +#define AIO_PORT_NS_MINDATABITS (0x20000000) +#define AIO_PORT_NS_MAXDATABITS (0x10000000) +#define AIO_PORT_NS_MINSTOPBITS (0x08000000) +#define AIO_PORT_NS_MAXSTOPBITS (0x04000000) +#define AIO_PORT_NS_MINPARITYMODE (0x02000000) +#define AIO_PORT_NS_MAXPARITYMODE (0x01000000) +#define AIO_PORT_NS_MINFLOWCTRLMODE (0x00800000) +#define AIO_PORT_NS_MAXFLOWCTRLMODE (0x00400000) +#define AIO_PORT_NS_MISCCAPABILITIES (0x00200000) +#define AIO_PORT_NS_MINREADBUFFERSIZE (0x00100000) +#define AIO_PORT_NS_MAXREADBUFFERSIZE (0x00080000) +#define AIO_PORT_NS_MINWRITEBUFFERSIZE (0x00040000) +#define AIO_PORT_NS_MAXWRITEBUFFERSIZE (0x00020000) +#define AIO_PORT_NS_MINDEADMANTIME (0x00010000) +#define AIO_PORT_NS_MAXDEADMANTIME (0x00008000) + +#define AIO_PORT_CAPS_NOT_SUPPORTED (0x00007FFF) +#define AIO_PORT_CAPS_MAJOR_VERSION (1) +#define AIO_PORT_CAPS_MINOR_VERSION (0) + +#define AIO_CAP_OUTPUT_BREAK (0x00000002) +#define AIO_CAP_FLOWCTRLCHARS (0x00000004) +#define AIO_CAP_PROGRAMMABLE (0x00000008) +#define AIO_CAP_INPUT (0x00000010) +#define AIO_CAP_OUTPUT (0x00000020) + + +typedef struct + { + WORD returnLength; /* byte length of driver capabilities structure */ + BYTE byteData[2]; + } AIODVRCAPABILITIES; + +#define AIO_NO_STRUCT_DATA_RETURNED (2) + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOGetPortsRollCall function. * + * * + *----------------------------------------------------------------------------*/ + +typedef struct + { + WORD returnLength; /* byte length of port info data */ + BYTE majorVersion; + BYTE minorVersion; + LONG notSupportedMask; + int hardwareType; /* value used with AIOAcquirePort */ + int boardNumber; /* " */ + int portNumber; /* " */ + WORD availability; /* availability of port for acquire */ + LONG externalStatus; /* current external status value for port */ + LONG chgdExternalStatus; /* changed external status value for port */ + } AIOPORTINFO; + +#define AIO_INFO_NS_HARDWARETYPE (0x80000000) +#define AIO_INFO_NS_BOARDNUMBER (0x40000000) +#define AIO_INFO_NS_PORTNUMBER (0x20000000) +#define AIO_INFO_NS_AVAILABILITY (0x10000000) +#define AIO_INFO_NS_EXTERNALSTATUS (0x08000000) +#define AIO_INFO_NS_CHGDEXTERNALSTATUS (0x04000000) + +#define AIO_PORT_INFO_NOT_SUPPORTED (0x03FFFFFF) +#define AIO_PORT_INFO_MAJOR_VERSION (1) +#define AIO_PORT_INFO_MINOR_VERSION (0) + +#define AIO_AVAILABLE_FOR_ACQUIRE (0) +#define AIO_ALREADY_ACQUIRED (1) +#define AIO_UNAVAILABLE (0xFF) + +#define AIO_INITIAL (0) +#define AIO_SUCCESSOR (1) + + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOGetPortConfiguration function. * + * * + *----------------------------------------------------------------------------*/ + +typedef struct + { + WORD returnLength; /* byte length of port configuration data */ + BYTE majorVersion; + BYTE minorVersion; + LONG notSupportedMask; + int hardwareType; /* value used with AIOAcquirePort */ + int boardNumber; /* " */ + int portNumber; /* " */ + BYTE bitRate; /* Bits per second index */ + BYTE dataBits; /* Bits per character index */ + BYTE stopBits; /* Stop bits per char index */ + BYTE parityMode; /* Generated parity index */ + BYTE flowCtrlMode; /* Flow control mode */ + BYTE breakMode; /* Break control mode */ + LONG readSize; /* Receive buffer size */ + LONG writeSize; /* Transmit buffer size */ + BYTE transmitXon; + BYTE transmitXoff; + BYTE receiveXon; + BYTE receiveXoff; + WORD externalControl; /* set with AIO_EXTERNAL_CONTROL */ + + } AIOPORTCONFIG; + +#define AIO_CONFIG_NS_HARDWARETYPE (0x80000000) +#define AIO_CONFIG_NS_BOARDNUMBER (0x40000000) +#define AIO_CONFIG_NS_PORTNUMBER (0x20000000) +#define AIO_CONFIG_NS_BITRATE (0x10000000) +#define AIO_CONFIG_NS_DATABITS (0x08000000) +#define AIO_CONFIG_NS_STOPBITS (0x04000000) +#define AIO_CONFIG_NS_PARITYMODE (0x02000000) +#define AIO_CONFIG_NS_FLOWCTRLMODE (0x01000000) +#define AIO_CONFIG_NS_BREAKMODE (0x00800000) +#define AIO_CONFIG_NS_READSIZE (0x00400000) +#define AIO_CONFIG_NS_WRITESIZE (0x00200000) +#define AIO_CONFIG_NS_TRANSMITXON (0x00100000) +#define AIO_CONFIG_NS_TRANSMITXOFF (0x00080000) +#define AIO_CONFIG_NS_RECEIVEXON (0x00040000) +#define AIO_CONFIG_NS_RECEIVEXOFF (0x00020000) +#define AIO_CONFIG_NS_EXTERNALCONTROL (0x00010000) + +#define AIO_PORT_CONFIG_NOT_SUPPORTED (0x0007FFFF) +#define AIO_PORT_CONFIG_MAJOR_VERSION (1) +#define AIO_PORT_CONFIG_MINOR_VERSION (0) + +#define AIO_EXTCTRL_DTR_ENABLE (1) +#define AIO_EXTCTRL_DTR_DISABLE (0) +#define AIO_EXTCTRL_RTS_ENABLE (2) +#define AIO_EXTCTRL_RTS_DISABLE (0) + +#define AIO_BREAK_MODE_OFF (0) +#define AIO_BREAK_MODE_ON (1) + +typedef struct + { + WORD returnLength; /* byte length of driver config structure */ + BYTE byteData[2]; + } AIODVRCONFIG; + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with the AIOGetStatistics function. * + * * + *----------------------------------------------------------------------------*/ + +typedef struct + { + WORD returnLength; /* byte length of port statistics structure */ + BYTE majorVersion; + BYTE minorVersion; + LONG notSupportedMask; + LONG receiveBytes; /* total number of bytes received on port */ + LONG transmitBytes; /* total number of bytes transmitted from port */ + LONG parityErrors; /* number of receive parity errors */ + LONG framingErrors; /* number of receive framing errors */ + LONG overrunSoftware; /* number of software overruns (occurrences) */ + LONG overrunHardware; /* number of hardware overruns (occurrences) */ + } AIOPORTSTATISTICS; + +#define AIO_STATS_NS_RECEIVEBYTES (0x80000000) +#define AIO_STATS_NS_TRANSMITBYTES (0x40000000) +#define AIO_STATS_NS_PARITYERRORS (0x20000000) +#define AIO_STATS_NS_FRAMINGERRORS (0x10000000) +#define AIO_STATS_NS_OVERRUNSOFTWARE (0x08000000) +#define AIO_STATS_NS_OVERRUNHARDWARE (0x04000000) + +#define AIO_PORT_STATS_NOT_SUPPORTED (0x03FFFFFF) +#define AIO_PORT_STATS_MAJOR_VERSION (1) +#define AIO_PORT_STATS_MINOR_VERSION (0) + +typedef struct + { + WORD returnLength; /* byte length of driver statistics structure */ + BYTE byteData[2]; + } AIODVRSTATISTICS; + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with AIOGetDriverList function. * + * * + *----------------------------------------------------------------------------*/ + +typedef struct + { + int hardwareType; + int ports; + char name[128]; + } AIODRIVERLISTENTRY; + +typedef struct + { + WORD returnLength; + AIODRIVERLISTENTRY driver[1]; + } AIODRIVERLIST; + +#define AIO_DRIVER_LIST_GET_FIRST (-1) + + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with AIOGetBoardList function. * + * * + *----------------------------------------------------------------------------*/ + +typedef struct + { + int boardNumber; + int ports; + char name[128]; + } AIOBOARDLISTENTRY; + +typedef struct + { + WORD returnLength; + AIOBOARDLISTENTRY board[1]; + } AIOBOARDLIST; + +#define AIO_BOARD_LIST_GET_FIRST (-1) + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with AIOSetControlData function. * + * * + *----------------------------------------------------------------------------*/ + +typedef struct + { + WORD returnLength; /* byte length of control data structure */ + BYTE byteData[2]; + } AIOCONTROLDATA; + +/*----------------------------------------------------------------------------* + * * + * Definitions for use with AIOGetFirstPortInfo and AIOGetNextPortInfo * + * * + *----------------------------------------------------------------------------*/ + +typedef struct + { + int typeMask; + int boardMask; + int portMask; + int reserved[6]; + } AIOPORTSEARCH; + + /* reserved index values */ + +#define SEARCH_TYPE_INDEX 0 +#define SEARCH_BOARD_INDEX 1 +#define SEARCH_PORT_INDEX 2 + + +/*----------------------------------------------------------------------------* + * * + * Definition of AIO functions. * + * * + *----------------------------------------------------------------------------*/ + +extern int AIOAcquirePort ( int *hardwareType, + int *boardNumber, + int *portNumber, + int *portHandle + ); + +extern int AIOAcquirePortWithRTag ( int *hardwareType, + int *boardNumber, + int *portNumber, + int *portHandle, + LONG RTag + ); + +extern int AIOConfigurePort ( int portHandle, + BYTE bitRate, + BYTE dataBits, + BYTE stopBits, + BYTE parityMode, + BYTE flowCtrlMode + ); + +extern int AIOFlushBuffers ( int portHandle, + WORD flushFlag + ); + +extern int AIOGetBoardList( int hardwareType, + int boardIndex, + AIOBOARDLIST *pBoardList ); + +extern int AIOGetDriverList ( int lastHardwareType, + AIODRIVERLIST *pDriverList + ); + +extern int AIOGetExternalStatus ( int portHandle, + LONG *extStatus, + LONG *chgdExtStatus + ); + +extern int AIOGetFirstPortInfo ( int hardwareType, + int boardNumber, + int portNumber, + AIOPORTSEARCH *portSearchP, + AIOPORTINFO *portInfoP, + AIOPORTCAPABILITIES *capabilitiesP, + AIODVRCAPABILITIES *dvrCapabilitiesP, + char *NLMModuleNameP ); + +extern int AIOGetNextPortInfo ( AIOPORTSEARCH *portSearchP, + AIOPORTINFO *portInfoP, + AIOPORTCAPABILITIES *capabilitiesP, + AIODVRCAPABILITIES *dvrCapabilitiesP, + char *NLMModuleNameP ); + +extern int AIOGetPortCapability ( int portHandle, + AIOPORTCAPABILITIES *pCapabilities, + AIODVRCAPABILITIES *pDvrCapabilities + ); + +extern int AIOGetPortConfiguration ( int portHandle, + AIOPORTCONFIG *pPortConfig, + AIODVRCONFIG *pDvrConfig + ); + +extern int AIOGetPortStatus ( int portHandle, + LONG *writeCount, + WORD *writeState, + LONG *readCount, + WORD *readState, + LONG *extStatus, + LONG *chgdExtStatus + ); + +extern int AIOGetReadBufferSize ( int portHandle, + LONG *readSize + ); + +extern int AIOGetPortStatistics ( int portHandle, + AIOPORTSTATISTICS *pPortStatistics, + AIODVRSTATISTICS *pDvrStatistics + ); + +extern int AIOGetFirstPortStatistics( int hardwareType, + int boardNumber, + int portNumber, + AIOPORTSEARCH *portSearchP, + AIOPORTSTATISTICS *pPortStatistics, + AIODVRSTATISTICS *pDvrStatistics + ); + +extern int AIOGetNextPortStatistics ( AIOPORTSEARCH *portSearchP, + AIOPORTSTATISTICS *pPortStatistics, + AIODVRSTATISTICS *pDvrStatistics + ); + +extern int AIOGetWriteBufferSize ( int portHandle, + LONG *writeSize + ); + +extern int AIOReadData ( int portHandle, + char *buffer, + LONG length, + LONG *numberBytesRead + ); + +extern int AIOReadStatus ( int portHandle, + LONG *count, + WORD *state + ); + +extern int AIOReleasePort ( int portHandle ); + +extern int AIOSetControlData ( int portHandle, + int requestType, + AIOCONTROLDATA *requestStructValue + ); + +extern int AIOSetExternalControl ( int portHandle, + int requestType, + int requestValue + ); + +extern int AIOSetFlowControl ( int portHandle, + int flowCtrlMode + ); + +extern int AIOSetFlowControlCharacters( int portHandle, + BYTE transmitXon, + BYTE transmitXoff, + BYTE receiveXon, + BYTE receiveXoff + ); + +extern int AIOSetReadBufferSize ( int portHandle, + LONG bufferSize + ); + +extern int AIOSetWriteBufferSize ( int portHandle, + LONG bufferSize + ); + +extern int AIOWriteData ( int portHandle, + char *buffer, + LONG length, + LONG *numberBytesWritten + ); + +extern int AIOWriteStatus ( int portHandle, + LONG *count, + WORD *state + ); + +/* -=-=-= Random stuff -=-=-=-= */ + +#define isspace(C) (C == '\n' || C == '\r' || C == ' ' || C == '\t') +int Breakpoint (int __arg); + +#define ULONG unsigned long + +#define COM1 0x8000 +#define COM2 0x9000 diff --git a/gdb/nlm/alpha-regdef.h b/gdb/nlm/alpha-regdef.h new file mode 100644 index 0000000..4bd673c --- /dev/null +++ b/gdb/nlm/alpha-regdef.h @@ -0,0 +1,80 @@ +/* + * ***************************************************************** + * * * + * * Copyright (c) Digital Equipment Corporation, 1991, 1992 * + * * * + * * All Rights Reserved. Unpublished rights reserved under * + * * the copyright laws of the United States. * + * * * + * * The software contained on this media is proprietary to * + * * and embodies the confidential technology of Digital * + * * Equipment Corporation. Possession, use, duplication or * + * * dissemination of the software and media is authorized only * + * * pursuant to a valid written license from Digital Equipment * + * * Corporation. * + * * * + * * RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure * + * * by the U.S. Government is subject to restrictions as set * + * * forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, * + * * or in FAR 52.227-19, as applicable. * + * * * + * ***************************************************************** + */ +/* + * HISTORY + */ +/* + * Modification History: /sys/machine/alpha/regdef.h + * + * 01-Oct-90 -- rjl + * Defined the k0 and k1 registers. They are not really used as such + * but they have to be defined in order for them to be saved during + * exception handling + * + * 06-Sep-90 -- kjl and afd + * Created this file for Alpha support. + */ + +#define v0 $0 + +#define t0 $1 +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define t6 $7 +#define t7 $8 + +#define s0 $9 +#define s1 $10 +#define s2 $11 +#define s3 $12 +#define s4 $13 +#define s5 $14 +#define s6 $15 +#define fp $15 /* fp & s6 are the same */ + +#define a0 $16 +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 + +#define t8 $22 +#define t9 $23 +#define t10 $24 +#define t11 $25 + +#define ra $26 + +#define pv $27 /* pv and t5 are the same */ +#define t12 $27 + +#define AT $at + +#define gp $29 + +#define sp $30 +#define zero $31 diff --git a/gdb/nlm/alpha-uart.c b/gdb/nlm/alpha-uart.c new file mode 100755 index 0000000..00c33e0 --- /dev/null +++ b/gdb/nlm/alpha-uart.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 1993, 1994 by + * Digital Equipment Corporation, Maynard, Massachusetts. + * All rights reserved. + * + * This software is furnished under a license and may be used and copied + * only in accordance of the terms of such license and with the + * inclusion of the above copyright notice. This software or any other + * copies thereof may not be provided or otherwise made available to any + * other person. No title to and ownership of the software is hereby + * transferred. + * + * The information in this software is subject to change without notice + * and should not be construed as a commitment by Digital Equipment + * Corporation. + * + * Digital assumes no responsibility for the use or reliability of its + * software on equipment which is not supplied by Digital. + * + */ + + + +/*$Id$*/ + +#include "nwtypes.h" +#include "alpha-uart.h" +/*#include "alphansi.h"*/ +#include "alpha-patch.h" +#include <stdio.h> + +ULONG com_interrupt() +{ + if (inVti(com1Lsr) & 1) + return COM1 | inVti (com1Rbr); + + return 0; +} + +void + putcLpt(int c) +{ + int i, s; + while(!((s = inVti(lptSr)) & 0x80)) + ; + + for(i=0;i<lptDly;++i) + ; + + outVti(lptDr, c); + for(i=0;i<lptDly;++i) + ; + + outVti(lptCr, lptnInit|lptSTB|lptAFD); + for(i=0;i<lptDly;++i) + ; + + outVti(lptCr, lptnInit|lptAFD); + for(i=0;i<lptDly;++i) + ; + + s = inVti(lptSr); +} + + + +void + uart_putchar(int port, char c) +{ + int lsr, thr; + switch(port) + { + case COM1: + lsr = com1Lsr; + thr = com1Thr; + break; + case COM2: + lsr = com2Lsr; + thr = com2Thr; + break; +#if 0 + case LPT: + putcLpt(c); + return; + case VGA: + vga_putc(c); + return; +#endif + default: + return; + } + + while ((inVti(lsr) & 0x20) == 0); + outVti(thr,c); + if (c == '\n') uart_putchar(port, '\r'); +} + + + +int uart_init_line(int line, int baud) +{ + int i; + int baudconst; + + switch (baud) + { + case 57600: baudconst = 2; break; + case 38400: baudconst = 3; break; + case 19200: baudconst = 6; break; + case 9600: baudconst = 12; break; + case 4800: baudconst = 24; break; + case 2400: baudconst = 48; break; + case 1200: baudconst = 96; break; + case 300: baudconst = 384; break; + case 150: baudconst = 768; break; + default: baudconst = 12; break; + } + + if (line == 1) + { + outVti(com1Lcr, 0x87); + outVti(com1Dlm, 0); + outVti(com1Dll, baudconst); + outVti(com1Lcr, 0x07); + outVti(com1Mcr, 0x0F); + com1_disable_int(); + } + + else if (line == 2) + { + outVti(com2Lcr, 0x87); + outVti(com2Dlm, 0); + outVti(com2Dll, baudconst); + outVti(com2Lcr, 0x07); + outVti(com2Mcr, 0x0F); + } + fprintf (stderr, "com1Ier = 0x%x\n", inVti(com1Ier)); + fprintf (stderr, "com1Lcr = 0x%x\n", inVti(com1Lcr)); + fprintf (stderr, "com1Dlm = 0x%x\n", inVti(com1Dlm)); + fprintf (stderr, "com1Dll = 0x%x\n", inVti(com1Dll)); + fprintf (stderr, "com1Lcr = 0x%x\n", inVti(com1Lcr)); + fprintf (stderr, "com1Mcr = 0x%x\n", inVti(com1Mcr)); +} + + + +int + uart_init() +{ + uart_init_line(1, 19200); +} + + + +com1_enable_int() +{ + outVti(com1Ier, 0x01); +} + + + +com1_disable_int() +{ + outVti(com1Ier, 0x0); +} + + + +com2_enable_int() +{ + outVti(com2Ier, 0x01); +} + + + +com2_disable_int() +{ + outVti(com2Ier, 0x0); +} diff --git a/gdb/nlm/alpha-uart.h b/gdb/nlm/alpha-uart.h new file mode 100755 index 0000000..77f5f05 --- /dev/null +++ b/gdb/nlm/alpha-uart.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 1993, 1994 by + * Digital Equipment Corporation, Maynard, Massachusetts. + * All rights reserved. + * + * This software is furnished under a license and may be used and copied + * only in accordance of the terms of such license and with the + * inclusion of the above copyright notice. This software or any other + * copies thereof may not be provided or otherwise made available to any + * other person. No title to and ownership of the software is hereby + * transferred. + * + * The information in this software is subject to change without notice + * and should not be construed as a commitment by Digital Equipment + * Corporation. + * + * Digital assumes no responsibility for the use or reliability of its + * software on equipment which is not supplied by Digital. + * + */ + + +#define com1Rbr 0x3f8 /* Receiver Buffer - Read */ +#define com1Thr 0x3f8 /* Transmitter Holding - Write */ +#define com1Ier 0x3f9 /* Interrupt Enable */ +#define com1Iir 0x3fa /* Interrupt Identification */ +#define com1Lcr 0x3fb /* Line Control */ +#define com1Mcr 0x3fc /* Modem Control */ +#define com1Lsr 0x3fd /* Line Status */ +#define com1Msr 0x3fe /* Modem Status */ +#define com1Scr 0x3ff /* Scratch */ +#define com1Dll 0x3f8 /* Divisor Latch - lsb */ +#define com1Dlm 0x3f9 /* Divisor Latch - msb */ + +#define com2Rbr 0x2f8 /* Receiver Buffer - Read */ +#define com2Thr 0x2f8 /* Transmitter Holding - Write */ +#define com2Ier 0x2f9 /* Interrupt Enable */ +#define com2Iir 0x2fa /* Interrupt Identification */ +#define com2Lcr 0x2fb /* Line Control */ +#define com2Mcr 0x2fc /* Modem Control */ +#define com2Lsr 0x2fd /* Line Status */ +#define com2Msr 0x2fe /* Modem Status */ +#define com2Scr 0x2ff /* Scratch */ +#define com2Dll 0x2f8 /* Divisor Latch - lsb */ +#define com2Dlm 0x2f9 /* Divisor Latch - msb */ + +#define lptDr 0x3bc +#define lptSr 0x3bd +#define lptCr 0x3be + +#define lptSTB 0x01 +#define lptAFD 0x02 +#define lptnInit 0x04 +#define lptSlct 0x08 +#define lptIrq 0x10 +#define lptDir 0x20 + +#define lptDly 100000 + diff --git a/gdb/nlm/altdebug.h b/gdb/nlm/altdebug.h new file mode 100644 index 0000000..c9372ab --- /dev/null +++ b/gdb/nlm/altdebug.h @@ -0,0 +1,105 @@ +typedef short int16_t; +typedef unsigned short uint16_t; + +typedef int int32_t; +typedef unsigned int uint32_t; + +typedef struct int64_s { + uint32_t lo; + uint32_t hi; +} int64_t; + +/* Define indexes into register array in StackFrame */ +#define SF_REG_PC 0 + +#define SF_IREG_OFFSET 1 /* int regs start at index 1 */ +#define SF_REG_V0 (0+SF_IREG_OFFSET) +#define SF_REG_T0 (1+SF_IREG_OFFSET) +#define SF_REG_T1 (2+SF_IREG_OFFSET) +#define SF_REG_T2 (3+SF_IREG_OFFSET) +#define SF_REG_T3 (4+SF_IREG_OFFSET) +#define SF_REG_T4 (5+SF_IREG_OFFSET) +#define SF_REG_T5 (6+SF_IREG_OFFSET) +#define SF_REG_T6 (7+SF_IREG_OFFSET) +#define SF_REG_T7 (8+SF_IREG_OFFSET) +#define SF_REG_S0 (9+SF_IREG_OFFSET) +#define SF_REG_S1 (10+SF_IREG_OFFSET) +#define SF_REG_S2 (11+SF_IREG_OFFSET) +#define SF_REG_S3 (12+SF_IREG_OFFSET) +#define SF_REG_S4 (13+SF_IREG_OFFSET) +#define SF_REG_S5 (14+SF_IREG_OFFSET) +#define SF_REG_S6 (15+SF_IREG_OFFSET) +#define SF_REG_FP SF_REG_S6 +#define SF_REG_A0 (16+SF_IREG_OFFSET) +#define SF_REG_A1 (17+SF_IREG_OFFSET) +#define SF_REG_A2 (18+SF_IREG_OFFSET) +#define SF_REG_A3 (19+SF_IREG_OFFSET) +#define SF_REG_A4 (20+SF_IREG_OFFSET) +#define SF_REG_A5 (21+SF_IREG_OFFSET) +#define SF_REG_T8 (22+SF_IREG_OFFSET) +#define SF_REG_T9 (23+SF_IREG_OFFSET) +#define SF_REG_T10 (24+SF_IREG_OFFSET) +#define SF_REG_T11 (25+SF_IREG_OFFSET) +#define SF_REG_RA (26+SF_IREG_OFFSET) +#define SF_REG_PV (27+SF_IREG_OFFSET) +#define SF_REG_T12 SF_REG_PV +#define SF_REG_AT (28+SF_IREG_OFFSET) +#define SF_REG_GP (29+SF_IREG_OFFSET) +#define SF_REG_SP (30+SF_IREG_OFFSET) +#define SF_REG_ZERO (31+SF_IREG_OFFSET) +#define NUMBER_OF_INT_REGS 32 + +#define SF_FREG_OFFSET (SF_IREG_OFFSET+NUMBER_OF_INT_REGS) +#define SF_REG_F0 (0+SF_FREG_OFFSET) +#define SF_REG_F1 (1+SF_FREG_OFFSET) +#define SF_REG_F2 (2+SF_FREG_OFFSET) +#define SF_REG_F3 (3+SF_FREG_OFFSET) +#define SF_REG_F4 (4+SF_FREG_OFFSET) +#define SF_REG_F5 (5+SF_FREG_OFFSET) +#define SF_REG_F6 (6+SF_FREG_OFFSET) +#define SF_REG_F7 (7+SF_FREG_OFFSET) +#define SF_REG_F8 (8+SF_FREG_OFFSET) +#define SF_REG_F9 (9+SF_FREG_OFFSET) +#define SF_REG_F10 (10+SF_FREG_OFFSET) +#define SF_REG_F11 (11+SF_FREG_OFFSET) +#define SF_REG_F12 (12+SF_FREG_OFFSET) +#define SF_REG_F13 (13+SF_FREG_OFFSET) +#define SF_REG_F14 (14+SF_FREG_OFFSET) +#define SF_REG_F15 (15+SF_FREG_OFFSET) +#define SF_REG_F16 (16+SF_FREG_OFFSET) +#define SF_REG_F17 (17+SF_FREG_OFFSET) +#define SF_REG_F18 (18+SF_FREG_OFFSET) +#define SF_REG_F19 (19+SF_FREG_OFFSET) +#define SF_REG_F20 (20+SF_FREG_OFFSET) +#define SF_REG_F21 (21+SF_FREG_OFFSET) +#define SF_REG_F22 (22+SF_FREG_OFFSET) +#define SF_REG_F23 (23+SF_FREG_OFFSET) +#define SF_REG_F24 (24+SF_FREG_OFFSET) +#define SF_REG_F25 (25+SF_FREG_OFFSET) +#define SF_REG_F26 (26+SF_FREG_OFFSET) +#define SF_REG_F27 (27+SF_FREG_OFFSET) +#define SF_REG_F28 (28+SF_FREG_OFFSET) +#define SF_REG_F29 (29+SF_FREG_OFFSET) +#define SF_REG_F30 (30+SF_FREG_OFFSET) +#define SF_REG_FZERO (31+SF_FREG_OFFSET) + +#define NUMBER_OF_FLOAT_REGS 32 + +struct StackFrame +{ + struct DomainStructure *ExceptionDomainID; + struct ProcessorStructure *ExceptionProcessorID; + BYTE *ExceptionDescription; + LONG ExceptionFlags; + LONG ExceptionErrorCode; + LONG ExceptionNumber; + + int64_t ExceptionAddress; /* Address at which exception occured */ + int64_t ExceptionRegs[1+NUMBER_OF_INT_REGS+NUMBER_OF_FLOAT_REGS]; + /* First entry is for PC */ + int ExceptionBrkptNum; /* Set by the NSI debug exception handler + if the exception was caused by a + NID breakpoint */ + int ExceptionBrkptFlags; /* Flags for the breakpoint. See nsibrkpt.c + for details */ +}; diff --git a/gdb/nlm/configure.in b/gdb/nlm/configure.in new file mode 100644 index 0000000..5f4ca6c --- /dev/null +++ b/gdb/nlm/configure.in @@ -0,0 +1,325 @@ +srcname="Remote GDB server for Netware" +srctrigger=gdbserve.c + +# per-host: + +# Map host cpu into the config cpu subdirectory name. +# The default is $host_cpu. + +case "${host_cpu}" in + +alpha) gdb_host_cpu=alpha ;; +c[12]) gdb_host_cpu=convex ;; +hppa*) gdb_host_cpu=pa ;; +i[34]86) gdb_host_cpu=i386 ;; +m68*) gdb_host_cpu=m68k ;; +np1) gdb_host_cpu=gould ;; +pyramid) gdb_host_cpu=pyr ;; +*) gdb_host_cpu=$target_cpu ;; + +esac + +# map host info into gdb names. + +case "${host}" in + +a29k-*-*) gdb_host=ultra3 ;; +alpha-*-osf*) gdb_host=alpha-osf1 ;; + +arm-*-*) gdb_host=arm ;; + +c[12]-*-*) gdb_host=convex ;; + +hppa*-hp-bsd*) gdb_host=hppabsd ;; +hppa*-hp-hpux*) gdb_host=hppahpux ;; + +i[34]86-ncr-*) gdb_host=ncr3000 ;; +i[34]86-sequent-*) gdb_host=symmetry ;; + +i[34]86-*-bsd*) gdb_host=i386bsd ;; +i[34]86-*-lynxos*) gdb_host=i386lynx ;; +i[34]86-*-go32) gdb_host=go32 + gdb_serial_driver=ser-go32.c + ;; +i[34]86-*-linux) gdb_host=linux ;; +i[34]86-*-mach) gdb_host=i386mach ;; +i[34]86-*-sco3.2v4*) gdb_host=i386sco4 ;; +i[34]86-*-sco*) gdb_host=i386sco ;; +i[34]86-*-solaris*) gdb_host=i386sol2 ;; +i[34]86-*-sunos*) gdb_host=sun386 ;; +i[34]86-*-sysv3.2) gdb_host=i386v32 ;; +i[34]86-*-sysv4*) gdb_host=i386v4 ;; +i[34]86-*-sysv*) gdb_host=i386v ;; + +m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;; +m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;; +m68030-sony-*) gdb_host=news1000 ;; + +m68*-altos-*) gdb_host=altos ;; +m68*-apollo*-sysv*) gdb_host=apollo68v ;; +m68*-apollo*-bsd*) gdb_host=apollo68b ;; +m68*-att-*) gdb_host=3b1 ;; +m68*-cbm-sysv4*) gdb_host=amix ;; +m68*-hp-bsd*) gdb_host=hp300bsd ;; +m68*-hp-hpux*) gdb_host=hp300hpux ;; +m68*-isi-*) gdb_host=isi ;; +m68*-*-lynxos*) gdb_host=m68klynx ;; +m68*-sony-*) gdb_host=news ;; +m68*-sun-sunos3*) gdb_host=sun3os3 ;; +m68*-sun-sunos4*) gdb_host=sun3os4 ;; +m68*-sun-*) gdb_host=sun3os4 ;; + +m88k-motorola-*) gdb_host=delta88 ;; +m88k-*-*) gdb_host=m88k ;; + +mips-dec-*) gdb_host=decstation ;; +mips-little-*) gdb_host=littlemips ;; +mips-sgi-irix3) gdb_host=irix3 ;; +mips-sgi-irix4*) gdb_host=irix4 ;; +mips-sony-*) gdb_host=bigmips ;; + +none-*-*) gdb_host=none ;; + +np1-*-*) gdb_host=np1 ;; + +ns32k-umax-*) gdb_host=umax ;; +ns32k-utek-sysv) gdb_host=merlin ;; + +pn-*-*) gdb_host=pn ;; + +pyramid-*-*) gdb_host=pyramid ;; + +romp-*-*) gdb_host=rtbsd ;; + +rs6000-*-*) gdb_host=rs6000 ;; + +sparc-*-lynxos*) gdb_host=sparclynx ;; +sparc-*-solaris2*) gdb_host=sun4sol2 ;; +sparc-*-sunos4*) gdb_host=sun4os4 ;; +sparc-*-*) gdb_host=sun4os4 ;; + +tahoe-*-*) gdb_host=tahoe ;; + +vax-*-bsd*) gdb_host=vaxbsd ;; +vax-*-ultrix2*) gdb_host=vaxult2 ;; +vax-*-ultrix*) gdb_host=vaxult ;; + +esac + +if [ ! -f ${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh ]; then + echo '***' "GDB remote does not support host ${host}" 1>&2 + exit 1 +fi + +# We really shouldn't depend on there being a space after XM_FILE= ... +hostfile=`awk '$1 == "XM_FILE=" { print $2 }' <${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh` + +# per-target: + +# Map target cpu into the config cpu subdirectory name. +# The default is $target_cpu. + +case "${target_cpu}" in + +alpha) gdb_target_cpu=alpha ;; +c[12]) gdb_target_cpu=convex ;; +hppa*) gdb_target_cpu=pa ;; +i[34]86) gdb_target_cpu=i386 ;; +m68*) gdb_target_cpu=m68k ;; +np1) gdb_target_cpu=gould ;; +pn) gdb_target_cpu=gould ;; +pyramid) gdb_target_cpu=pyr ;; +sparc*) gdb_target_cpu=sparc ;; +*) gdb_target_cpu=$target_cpu ;; + +esac + +# map target info into gdb names. + +case "${target}" in + +a29k-*-aout) gdb_target=a29k ;; +a29k-*-coff) gdb_target=a29k ;; +a29k-*-elf) gdb_target=a29k ;; +a29k-*-ebmon) gdb_target=a29k ;; +a29k-*-kern) gdb_target=a29k-kern ;; +a29k-*-none) gdb_target=a29k ;; +a29k-*-sym1) gdb_target=ultra3 ;; +a29k-*-udi) gdb_target=a29k-udi ;; +alpha-*-netware*) gdb_target=alpha-nw ;; + +arm-*-*) gdb_target=arm ;; + +c1-*-*) gdb_target=convex ;; +c2-*-*) gdb_target=convex ;; + +h8300-*-*) gdb_target=h8300hms ;; +h8500-*-*) gdb_target=h8500hms ;; + +sh-*-*) gdb_target=sh ;; + +hppa*-*-bsd*) gdb_target=hppabsd ;; +hppa*-*-hpux*) gdb_target=hppahpux ;; + +i[34]86-sequent-*) gdb_target=symmetry ;; +i[34]86-ncr-*) gdb_target=ncr3000 ;; + +i[34]86-*-aout) gdb_target=i386aout ;; +i[34]86-*-coff) gdb_target=i386v ;; +i[34]86-*-elf) gdb_target=i386v ;; + +i[34]86-*-bsd*) gdb_target=i386bsd ;; +i[34]86-*-lynxos*) gdb_target=i386lynx ;; +i[34]86-*-go32) gdb_target=i386aout ;; +i[34]86-*-solaris*) gdb_target=i386sol2 ;; +i[34]86-*-sunos*) gdb_target=sun386 ;; +i[34]86-*-sysv4*) gdb_target=i386v4 ;; +i[34]86-*-sco*) gdb_target=i386v ;; +i[34]86-*-sysv*) gdb_target=i386v ;; +i[34]86-*-linux) gdb_target=linux ;; + +i960-*-bout) gdb_target=vxworks960 ;; +i960-*-coff) gdb_target=nindy960 ;; +i960-*-elf) gdb_target=nindy960 ;; + +i960-*-nindy) gdb_target=nindy960 ;; +i960-*-vxworks) gdb_target=vxworks960 ;; + +m68000-*-aout) gdb_target=m68k-nofp ;; +m68000-*-coff) gdb_target=m68k-nofp ;; +m68000-*-elf) gdb_target=m68k-nofp ;; +m68000-*-sunos3*) gdb_target=sun2os3 ;; +m68000-*-sunos4*) gdb_target=sun2os4 ;; + +m68*-cbm-sysv4*) gdb_target=amix ;; +m68*-hp-bsd*) gdb_target=hp300bsd ;; +m68*-hp-hpux*) gdb_target=hp300hpux ;; + +m68*-altos-*) gdb_target=altos ;; +m68*-att-*) gdb_target=3b1 ;; +m68*-ericsson-*) gdb_target=es1800 ;; +m68*-isi-*) gdb_target=isi ;; +m68*-netx-*) gdb_target=vxworks68 ;; +m68*-sony-*) gdb_target=news ;; +m68*-tandem-*) gdb_target=st2000 ;; + +m68*-*-aout) gdb_target=m68k-fp ;; +m68*-*-coff) gdb_target=m68k-fp ;; +m68*-*-elf) gdb_target=m68k-fp ;; +m68*-*-lynxos*) gdb_target=m68klynx ;; +m68*-*-os68k) gdb_target=os68k ;; +m68*-*-sunos3*) gdb_target=sun3os3 ;; +m68*-*-sunos4*) gdb_target=sun3os4 ;; +m68*-*-vxworks*) gdb_target=vxworks68 ;; + +m88k-motorola-*) gdb_target=delta88 ;; +m88k-*-*) gdb_target=m88k ;; + +mips-big-*) gdb_target=bigmips ;; +mips-dec-*) gdb_target=decstation ;; +mips-idt-ecoff) gdb_target=idt ;; +mips-little-*) gdb_target=littlemips ;; +mips-sgi-*) gdb_target=irix3 ;; +mips-sony-*) gdb_target=bigmips ;; + +none-*-*) gdb_target=none ;; + +np1-*-*) gdb_target=np1 ;; + +ns32k-utek-sysv) gdb_target=merlin ;; +ns32k-utek-*) gdb_target=umax ;; + +pn-*-*) gdb_target=pn ;; + +pyramid-*-*) gdb_target=pyramid ;; + +rs6000-*-*) gdb_target=rs6000 ;; + +sparc-*-aout) gdb_target=sparc-em ;; +sparc-*-coff) gdb_target=sparc-em ;; +sparc-*-elf) gdb_target=sparc-em ;; +sparc-*-lynxos*) gdb_target=sparclynx ;; +sparc-*-solaris2*) gdb_target=sun4sol2 ;; +sparc-*-sunos4*) gdb_target=sun4os4 ;; +sparc-*-vxworks*) gdb_target=sparc-em ;; +sparc-*-*) gdb_target=sun4os4 ;; +sparclite*-*-*) gdb_target=sparclite ;; + +tahoe-*-*) gdb_target=tahoe ;; +vax-*-*) gdb_target=vax ;; + +z8k-*-sim) gdb_target=z8ksim ;; +esac + +if [ ! -f ${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt ]; then + echo '***' "GDB remote does not support target ${target}" 1>&2 + exit 1 +fi + +if [ -z "${removing}" ] ; then + cat ${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh ${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt | awk '$1 == "#msg" { + print substr($0,6)}' +fi + +# We really shouldn't depend on there being a space after TM_FILE= ... +targetfile=`awk '$1 == "TM_FILE=" { print $2 }' <${srcdir}/../config/${gdb_target_cpu}/${gdb_target}.mt` + +if [ "${target}" = "${host}" ] ; then + nativefile=`awk '$1 == "NAT_FILE=" { print $2 }' <${srcdir}/../config/${gdb_host_cpu}/${gdb_host}.mh` +fi + +host_makefile_frag=../config/${gdb_host_cpu}/${gdb_host}.mh +target_makefile_frag=../config/${gdb_target_cpu}/${gdb_target}.mt + +# If hostfile (XM_FILE) and/or targetfile (TM_FILE) and/or nativefile +# (NAT_FILE) is not set in the ?config/* file, we don't make the +# corresponding links. But we have to remove the xm.h files and tm.h +# files anyway, e.g. when switching from "configure host" to +# "configure none". + +files= +links= +rm -f xm.h +if [ "${hostfile}" != "" ]; then + if [ -f ${srcdir}/../config/${hostfile} ]; then + files="${files} ../config/${hostfile}" + else + files="${files} ../config/${gdb_host_cpu}/${hostfile}" + fi + links="${links} xm.h" +fi +rm -f tm.h +if [ "${targetfile}" != "" ]; then + if [ -f ${srcdir}/../config/${targetfile} ]; then + files="${files} ../config/${targetfile}" + else + files="${files} ../config/${gdb_target_cpu}/${targetfile}" + fi + links="${links} tm.h" +fi +rm -f nm.h +if [ "${nativefile}" != "" ]; then + if [ -f ${srcdir}/../config/${nativefile} ]; then + files="${files} ../config/${nativefile}" + else + files="${files} ../config/${gdb_host_cpu}/${nativefile}" + fi + links="${links} nm.h" +# temporary scaffolding until all hosts have the host/target/native +# split in place. +else + files="${files} ../config/nm-trash.h" + links="${links} nm.h" +fi + +if [ ${target_cpu} = "sparclite" ]; then + configdirs="${configdirs} sparclite" +fi + +# post-target: + +if [ "${nativefile}" = "" ] ; then + sed -e '/^NATDEPFILES= /s//# NATDEPFILES= /' \ + < Makefile > Makefile.tem + mv -f Makefile.tem Makefile +fi diff --git a/gdb/nlm/gdbserve.c b/gdb/nlm/gdbserve.c new file mode 100644 index 0000000..b97847f --- /dev/null +++ b/gdb/nlm/gdbserve.c @@ -0,0 +1,1101 @@ +/* i386-nlmstub.c -- NLM debugging stub for the i386. + + This is originally based on an m68k software stub written by Glenn + Engel at HP, but has changed quite a bit. It was modified for the + i386 by Jim Kingdon, Cygnus Support. It was modified to run under + NetWare by Ian Lance Taylor, Cygnus Support. + + This code is intended to produce an NLM (a NetWare Loadable Module) + to run under NetWare on an i386 platform. To create the NLM, + compile this code into an object file using the NLM SDK on any i386 + host, and use the nlmconv program (available in the GNU binutils) + to transform the resulting object file into an NLM. */ + +/**************************************************************************** + + 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. + +****************************************************************************/ + +/**************************************************************************** + * + * 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 <nwdfs.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +/*#include <ctype.h>*/ +#include <time.h> +/*#include <aio.h>*/ +#include <nwconio.h> +#include <nwadv.h> +#include <nwdbgapi.h> +/*#include <process.h>*/ +#include <errno.h> +#include <nwthread.h> +#include "alpha-patch.h" + +/****************************************************/ +/* This information is from Novell. It is not in any of the standard + NetWare header files. */ + +struct DBG_LoadDefinitionStructure +{ + void *reserved1[4]; + LONG reserved5; + LONG LDCodeImageOffset; + LONG LDCodeImageLength; + LONG LDDataImageOffset; + LONG LDDataImageLength; + LONG LDUninitializedDataLength; + LONG LDCustomDataOffset; + LONG LDCustomDataSize; + LONG reserved6[2]; + LONG (*LDInitializationProcedure)(void); +}; + +#define LO_NORMAL 0x0000 +#define LO_STARTUP 0x0001 +#define LO_PROTECT 0x0002 +#define LO_DEBUG 0x0004 +#define LO_AUTO_LOAD 0x0008 + +/* Loader returned error codes */ +#define LOAD_COULD_NOT_FIND_FILE 1 +#define LOAD_ERROR_READING_FILE 2 +#define LOAD_NOT_NLM_FILE_FORMAT 3 +#define LOAD_WRONG_NLM_FILE_VERSION 4 +#define LOAD_REENTRANT_INITIALIZE_FAILURE 5 +#define LOAD_CAN_NOT_LOAD_MULTIPLE_COPIES 6 +#define LOAD_ALREADY_IN_PROGRESS 7 +#define LOAD_NOT_ENOUGH_MEMORY 8 +#define LOAD_INITIALIZE_FAILURE 9 +#define LOAD_INCONSISTENT_FILE_FORMAT 10 +#define LOAD_CAN_NOT_LOAD_AT_STARTUP 11 +#define LOAD_AUTO_LOAD_MODULES_NOT_LOADED 12 +#define LOAD_UNRESOLVED_EXTERNAL 13 +#define LOAD_PUBLIC_ALREADY_DEFINED 14 +/****************************************************/ + +/* The main thread ID. */ +static int mainthread; + +/* An error message for the main thread to print. */ +static char *error_message; + +/* The AIO port handle. */ +static int AIOhandle; + +/* BUFMAX defines the maximum number of characters in inbound/outbound + buffers. At least NUMREGBYTES*2 are needed for register packets */ +#define BUFMAX (REGISTER_BYTES * 2 + 16) + +/* remote_debug > 0 prints ill-formed commands in valid packets and + checksum errors. */ +static int remote_debug = 1; + +static const char hexchars[] = "0123456789abcdef"; + +/* Register values. All of these values *MUST* agree with tm.h */ +#define RA_REGNUM 26 /* Contains return address value */ +#define SP_REGNUM 30 /* Contains address of top of stack */ +#define PC_REGNUM 64 /* Contains program counter */ +#define FP_REGNUM 65 /* Virtual frame pointer */ +#define V0_REGNUM 0 /* Function integer return value */ +#define NUM_REGS 66 /* Number of machine registers */ +#define REGISTER_BYTES (NUM_REGS * 8) /* Total size of registers array */ + +/*#define flush_i_cache() asm("call_pal 0x86")*/ + +static char *mem2hex (void *mem, char *buf, int count, int may_fault); +static char *hex2mem (char *buf, void *mem, int count, int may_fault); + +#if 0 +__main() {}; +#endif + +/* Read a character from the serial port. This must busy wait, but + that's OK because we will be the only thread running anyhow. */ + +static int +getDebugChar () +{ + int err; + LONG got; + unsigned char ret; + + do + { + err = AIOReadData (AIOhandle, (char *) &ret, 1, &got); + if (err != 0) + { + error_message = "AIOReadData failed"; + ResumeThread (mainthread); + return -1; + } + } + while (got == 0); + + return ret; +} + +/* Write a character to the serial port. Returns 0 on failure, + non-zero on success. */ + +static int +putDebugChar (c) + unsigned char c; +{ + int err; + LONG put; + + err = AIOWriteData (AIOhandle, (char *) &c, 1, &put); + if (err != 0 || put != 1) + { + error_message = "AIOWriteData failed"; + ResumeThread (mainthread); + return 0; + } + return 1; +} + +/* Get the registers out of the frame information. */ + +static void +frame_to_registers (frame, regs) + struct StackFrame *frame; + char *regs; +{ + mem2hex (&frame->ExceptionRegs[SF_REG_PC], ®s[PC_REGNUM * 8 * 2], 8, 0); + + mem2hex (&frame->ExceptionRegs[SF_IREG_OFFSET], ®s[V0_REGNUM * 8 * 2], 8 * 64, 0); +} + +/* Put the registers back into the frame information. */ + +static void +registers_to_frame (regs, frame) + char *regs; + struct StackFrame *frame; +{ + hex2mem (®s[PC_REGNUM * 8 * 2], &frame->ExceptionRegs[SF_REG_PC], 8, 0); + + hex2mem (®s[V0_REGNUM * 8 * 2], &frame->ExceptionRegs[SF_IREG_OFFSET], 8 * 64, 0); +} + +/* Turn a hex character into a number. */ + +static 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>. Returns 0 on failure, + non-zero on success. */ + +static int +getpacket (buffer) + char * buffer; +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + int ch; + + do + { + /* wait around for the start character, ignore all other characters */ + while ((ch = getDebugChar()) != '$') + if (ch == -1) + return 0; + checksum = 0; + xmitcsum = -1; + + count = 0; + + /* now, read until a # or end of buffer is found */ + while (count < BUFMAX) + { + ch = getDebugChar(); + if (ch == -1) + return 0; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + + if (ch == '#') + { + ch = getDebugChar (); + if (ch == -1) + return 0; + xmitcsum = hex(ch) << 4; + ch = getDebugChar (); + if (ch == -1) + return 0; + xmitcsum += hex(ch); + + if (checksum != xmitcsum) + { + if (remote_debug) + ConsolePrintf ("bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", + checksum,xmitcsum,buffer); + /* failed checksum */ + if (! putDebugChar('-')) + return 0; + return 1; + } + else + { + /* successful transfer */ + if (! putDebugChar('+')) + return 0; + /* if a sequence char is present, reply the sequence ID */ + if (buffer[2] == ':') + { + if (! putDebugChar (buffer[0]) + || ! putDebugChar (buffer[1])) + return 0; + /* remove sequence chars from buffer */ + count = strlen(buffer); + for (i=3; i <= count; i++) + buffer[i-3] = buffer[i]; + } + } + } + } + while (checksum != xmitcsum); + + if (remote_debug) + ConsolePrintf ("Received packet \"%s\"\r\n", buffer); + + return 1; +} + +/* Send the packet in buffer. Returns 0 on failure, non-zero on + success. */ + +static int +putpacket (buffer) + char * buffer; +{ + unsigned char checksum; + int count; + int ch; + + if (remote_debug) + ConsolePrintf ("Sending packet \"%s\"\r\n", buffer); + + /* $<packet info>#<checksum>. */ + do + { + if (! putDebugChar('$')) + return 0; + checksum = 0; + count = 0; + + while (ch=buffer[count]) + { + if (! putDebugChar(ch)) + return 0; + checksum += ch; + count += 1; + } + + if (! putDebugChar('#') + || ! putDebugChar(hexchars[checksum >> 4]) + || ! putDebugChar(hexchars[checksum % 16])) + return 0; + + ch = getDebugChar (); + if (ch == -1) + return 0; + } + while (ch != '+'); + + return 1; +} + +static char remcomInBuffer[BUFMAX]; +static char remcomOutBuffer[BUFMAX]; +static short error; + +static void +debug_error (format, parm) + char *format; + char *parm; +{ + if (remote_debug) + { + ConsolePrintf (format, parm); + ConsolePrintf ("\n"); + } +} + +/* This is set if we could get a memory access fault. */ +static int mem_may_fault; + +/* Indicate to caller of mem2hex or hex2mem that there has been an + error. */ +static volatile int mem_err = 0; + +/* These are separate functions so that they are so short and sweet + that the compiler won't save any registers (if there is a fault + to mem_fault, they won't get restored, so there better not be any + saved). */ + +static int +get_char (addr) + char *addr; +{ + return *addr; +} + +static void +set_char (addr, val) + char *addr; + int val; +{ + *addr = val; +} + +/* This bit of assembly language just returns from a function. If a + memory error occurs within get_char or set_char, the debugger + handler points EIP at these instructions to get out. */ + +extern void just_return (); +#if 0 +asm (".globl just_return"); +asm (".globl _just_return"); +asm ("just_return:"); +asm ("_just_return:"); +asm ("leave"); +asm ("ret"); +#endif + +/* convert the memory pointed to by mem into hex, placing result in buf */ +/* return a pointer to the last char put in buf (null) */ +/* If MAY_FAULT is non-zero, then we should set mem_err in response to + a fault; if zero treat a fault like any other fault in the stub. */ + +static char * +mem2hex (mem, buf, count, may_fault) + void *mem; + char *buf; + int count; + int may_fault; +{ + int i; + unsigned char ch; + char *ptr = mem; + + mem_may_fault = may_fault; + for (i = 0; i < count; i++) + { + ch = get_char (ptr++); + if (may_fault && mem_err) + return (buf); + *buf++ = hexchars[ch >> 4]; + *buf++ = hexchars[ch % 16]; + } + *buf = 0; + mem_may_fault = 0; + return(buf); +} + +/* convert the hex array pointed to by buf into binary to be placed in mem */ +/* return a pointer to the character AFTER the last byte written */ + +static char * +hex2mem (buf, mem, count, may_fault) + char *buf; + void *mem; + int count; + int may_fault; +{ + int i; + unsigned char ch; + char *ptr; + + mem_may_fault = may_fault; + for (i=0;i<count;i++) + { + ch = hex(*buf++) << 4; + ch = ch + hex(*buf++); + set_char (ptr++, ch); + if (may_fault && mem_err) + return (mem); + } + mem_may_fault = 0; + return(mem); +} + +/* This function takes the 386 exception vector and attempts to + translate this number into a unix compatible signal value. */ + +static int +computeSignal (exceptionVector) + int exceptionVector; +{ + int sigval; + switch (exceptionVector) + { + case 0 : sigval = 8; break; /* divide by zero */ + case 1 : sigval = 5; break; /* debug exception */ + case 3 : sigval = 5; break; /* breakpoint */ + case 4 : sigval = 16; break; /* into instruction (overflow) */ + case 5 : sigval = 16; break; /* bound instruction */ + case 6 : sigval = 4; break; /* Invalid opcode */ + case 7 : sigval = 8; break; /* coprocessor not available */ + case 8 : sigval = 7; break; /* double fault */ + case 9 : sigval = 11; break; /* coprocessor segment overrun */ + case 10 : sigval = 11; break; /* Invalid TSS */ + case 11 : sigval = 11; break; /* Segment not present */ + case 12 : sigval = 11; break; /* stack exception */ + case 13 : sigval = 11; break; /* general protection */ + case 14 : sigval = 11; break; /* page fault */ + case 16 : sigval = 7; break; /* coprocessor error */ + default: + sigval = 7; /* "software generated"*/ + } + return (sigval); +} + +/**********************************************/ +/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ +/* RETURN NUMBER OF CHARS PROCESSED */ +/**********************************************/ +static int +hexToInt(ptr, intValue) + 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); +} + +union inst +{ + LONG l; + + struct + { + union + { + struct + { + unsigned hint : 16; + unsigned rb : 5; + unsigned ra : 5; + unsigned opcode : 6; + } jump; + struct + { + signed disp : 21; + unsigned ra : 5; + unsigned opcode : 6; + } branch; + } variant; + } inst; +}; + +static LONG saved_inst; +static LONG *saved_inst_pc = 0; +static LONG saved_target_inst; +static LONG *saved_target_inst_pc = 0; + +static void +set_step_breakpoint (pc, frame) + LONG *pc; + struct StackFrame *frame; +{ + union inst inst; + LONG *target; + int opcode; + int ra, rb; + + inst.l = *pc++; + + opcode = inst.inst.variant.branch.opcode; + + if ((opcode & 0x30) == 0x30) /* A branch of some sort */ + target = inst.inst.variant.branch.disp + pc; + else if (opcode == 0x1a) /* jmp, ret, etc... */ + target = (LONG *)(frame->ExceptionRegs[SF_IREG_OFFSET + + inst.inst.variant.jump.rb].lo + & ~3); + else + target = pc; + + saved_inst = *pc; + *pc = 0x80; /* call_pal bpt */ + saved_inst_pc = pc; + + if (target != pc) + { + saved_target_inst = *target; + *target = 0x80; /* call_pal bpt */ + saved_target_inst_pc = target; + } +} + +/* Remove step breakpoints. Returns non-zero if pc was at a step breakpoint, + zero otherwise. This routine works even if there were no step breakpoints + set. */ + +static int +clear_step_breakpoint (pc) + LONG *pc; +{ + int retcode; + + if (saved_inst_pc == pc || saved_target_inst_pc == pc) + retcode = 1; + else + retcode = 0; + + if (saved_inst_pc) + { + *saved_inst_pc = saved_inst; + saved_inst_pc = 0; + } + + if (saved_target_inst_pc) + { + *saved_target_inst_pc = saved_target_inst; + saved_target_inst_pc = 0; + } + + return retcode; +} + +static void +do_status (ptr, frame) + char *ptr; + struct StackFrame *frame; +{ + int sigval; + + sigval = computeSignal (frame->ExceptionNumber); + + sprintf (ptr, "T%02x", sigval); + ptr += 3; + + sprintf (ptr, "%02x:", PC_REGNUM); + ptr = mem2hex (&frame->ExceptionRegs[SF_REG_PC], ptr + 3, 8, 0); + *ptr++ = ';'; + + sprintf (ptr, "%02x:", SP_REGNUM); + ptr = mem2hex (&frame->ExceptionRegs[SF_IREG_OFFSET + SP_REGNUM], ptr + 3, 8, 0); + *ptr++ = ';'; + + sprintf (ptr, "%02x:", RA_REGNUM); + ptr = mem2hex (&frame->ExceptionRegs[SF_IREG_OFFSET + RA_REGNUM], ptr + 3, 8, 0); + *ptr++ = ';'; + + sprintf (ptr, "%02x:", FP_REGNUM); + ptr = mem2hex (&frame->ExceptionRegs[SF_IREG_OFFSET + FP_REGNUM], ptr + 3, 8, 0); + *ptr++ = ';'; + + *ptr = '\000'; +} + +/* This function does all command processing for interfacing to gdb. + It is called whenever an exception occurs in the module being + debugged. */ + +static LONG +handle_exception (struct StackFrame *frame) +{ + int addr, length; + char *ptr; + static struct DBG_LoadDefinitionStructure *ldinfo = 0; + static LONG first_insn; /* The first instruction in the program. */ + + /* Apparently the bell can sometimes be ringing at this point, and + should be stopped. */ + StopBell (); + + if (remote_debug) + { + ConsolePrintf ("vector=%d: %s, pc=%08x, thread=%08x\r\n", + frame->ExceptionNumber, + frame->ExceptionDescription, + frame->ExceptionRegs[SF_REG_PC].lo, + GetThreadID ()); + } + + switch (frame->ExceptionNumber) + { + case START_NLM_EVENT: + /* If the NLM just started, we record the module load information + and the thread ID, and set a breakpoint at the first instruction + in the program. */ + + ldinfo = ((struct DBG_LoadDefinitionStructure *) + frame->ExceptionErrorCode); + first_insn = *(LONG *)ldinfo->LDInitializationProcedure; + *(LONG *)ldinfo->LDInitializationProcedure = 0x80; /* call_pal bpt */ + flush_i_cache (); + return RETURN_TO_PROGRAM; + + case ENTER_DEBUGGER_EVENT: + case KEYBOARD_BREAK_EVENT: + /* Pass some events on to the next debugger, in case it will handle + them. */ + return RETURN_TO_NEXT_DEBUGGER; + + case 3: /* Breakpoint */ + /* After we've reached the initial breakpoint, reset it. */ + if (frame->ExceptionRegs[SF_REG_PC].lo == (LONG) ldinfo->LDInitializationProcedure + && *(LONG *) ldinfo->LDInitializationProcedure == 0x80) + { + *(LONG *) ldinfo->LDInitializationProcedure = first_insn; + flush_i_cache (); + } + /* Normal breakpoints end up here */ + do_status (remcomOutBuffer, frame); + break; + + default: + /* At the moment, we don't care about most of the unusual NetWare + exceptions. */ + if (frame->ExceptionNumber > 31) + return RETURN_TO_PROGRAM; + + /* Most machine level exceptions end up here */ + do_status (remcomOutBuffer, frame); + break; + + case 11: /* Segment not present */ + case 13: /* General protection */ + case 14: /* Page fault */ + /* If we get a GP fault, and mem_may_fault is set, and the + instruction pointer is near set_char or get_char, then we caused + the fault ourselves accessing an illegal memory location. */ + if (mem_may_fault + && ((frame->ExceptionRegs[SF_REG_PC].lo >= (long) &set_char + && frame->ExceptionRegs[SF_REG_PC].lo < (long) &set_char + 50) + || (frame->ExceptionRegs[SF_REG_PC].lo >= (long) &get_char + && frame->ExceptionRegs[SF_REG_PC].lo < (long) &get_char + 50))) + { + mem_err = 1; + /* Point the instruction pointer at an assembly language stub + which just returns from the function. */ + + frame->ExceptionRegs[SF_REG_PC].lo += 4; /* Skip the load or store */ + + /* Keep going. This will act as though it returned from + set_char or get_char. The calling routine will check + mem_err, and do the right thing. */ + return RETURN_TO_PROGRAM; + } + /* Random mem fault, report it */ + do_status (remcomOutBuffer, frame); + break; + + case TERMINATE_NLM_EVENT: + /* There is no way to get the exit status. */ + sprintf (remcomOutBuffer, "W%02x", 0); + break; /* We generate our own status */ + } + + /* FIXME: How do we know that this exception has anything to do with + the program we are debugging? We can check whether the PC is in + the range of the module we are debugging, but that doesn't help + much since an error could occur in a library routine. */ + + clear_step_breakpoint (frame->ExceptionRegs[SF_REG_PC]); + + if (! putpacket(remcomOutBuffer)) + return RETURN_TO_NEXT_DEBUGGER; + + if (frame->ExceptionNumber == TERMINATE_NLM_EVENT) + { + ResumeThread (mainthread); + return RETURN_TO_PROGRAM; + } + + while (1) + { + error = 0; + remcomOutBuffer[0] = 0; + if (! getpacket (remcomInBuffer)) + return RETURN_TO_NEXT_DEBUGGER; + switch (remcomInBuffer[0]) + { + case '?': + do_status (remcomOutBuffer, frame); + break; + case 'd': + remote_debug = !(remote_debug); /* toggle debug flag */ + break; + case 'g': + /* return the value of the CPU registers */ + frame_to_registers (frame, remcomOutBuffer); + break; + case 'G': + /* set the value of the CPU registers - return OK */ + registers_to_frame (&remcomInBuffer[1], frame); + strcpy(remcomOutBuffer,"OK"); + break; + + case 'm': + /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + /* 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; + mem_err = 0; + mem2hex((char*) addr, remcomOutBuffer, length, 1); + if (mem_err) + { + strcpy (remcomOutBuffer, "E03"); + debug_error ("memory fault"); + } + } + + if (ptr) + { + strcpy(remcomOutBuffer,"E01"); + debug_error("malformed read memory command: %s",remcomInBuffer); + } + break; + + case 'M': + /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + /* 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++) == ':') + { + mem_err = 0; + hex2mem(ptr, (char*) addr, length, 1); + + if (mem_err) + { + strcpy (remcomOutBuffer, "E03"); + debug_error ("memory fault"); + } + else + { + strcpy(remcomOutBuffer,"OK"); + } + + ptr = 0; + } + if (ptr) + { + strcpy(remcomOutBuffer,"E02"); + debug_error("malformed write memory command: %s",remcomInBuffer); + } + break; + + case 'c': + case 's': + /* cAA..AA Continue at address AA..AA(optional) */ + /* sAA..AA Step one instruction from AA..AA(optional) */ + /* try to read optional parameter, pc unchanged if no parm */ + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr,&addr)) + { +/* registers[PC_REGNUM].lo = addr;*/ + fprintf (stderr, "Setting PC to 0x%x\n", addr); + while (1); + } + + if (remcomInBuffer[0] == 's') + set_step_breakpoint (frame->ExceptionRegs[SF_REG_PC].lo); + + flush_i_cache (); + return RETURN_TO_PROGRAM; + + case 'k': + /* kill the program */ + KillMe (ldinfo); + ResumeThread (mainthread); + return RETURN_TO_PROGRAM; + + case 'q': /* Query message */ + if (strcmp (&remcomInBuffer[1], "Offsets") == 0) + { + sprintf (remcomOutBuffer, "Text=%x;Data=%x;Bss=%x", + ldinfo->LDCodeImageOffset, + ldinfo->LDDataImageOffset, + ldinfo->LDDataImageOffset + ldinfo->LDDataImageLength); + } + else + sprintf (remcomOutBuffer, "E04, Unknown query %s", &remcomInBuffer[1]); + break; + } + + /* reply to the request */ + if (! putpacket(remcomOutBuffer)) + return RETURN_TO_NEXT_DEBUGGER; + } +} + +char *baudRates[] = { "50", "75", "110", "134.5", "150", "300", "600", "1200", + "1800", "2000", "2400", "3600", "4800", "7200", "9600", + "19200", "38400", "57600", "115200" }; + +char dataBits[] = "5678"; + +char *stopBits[] = { "1", "1.5", "2" }; + +char parity[] = "NOEMS"; + +/* Start up. The main thread opens the named serial I/O port, loads + the named NLM module and then goes to sleep. The serial I/O port + is named as a board number and a port number. It would be more DOS + like to provide a menu of available serial ports, but I don't want + to have to figure out how to do that. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int hardware, board, port; + LONG err; + struct debuggerStructure s; + char *cmdlin; + int i; + +/* Use the -B option to invoke the NID if you want to debug the stub. */ + + if (argc > 1 && strcmp(argv[1], "-B") == 0) + { + Breakpoint(argc); + ++argv, --argc; + } + + if (argc < 4) + { + fprintf (stderr, + "Usage: load gdbserve board port program [arguments]\n"); + exit (1); + } + + hardware = -1; + board = strtol (argv[1], (char **) NULL, 0); + port = strtol (argv[2], (char **) NULL, 0); + + err = AIOAcquirePort (&hardware, &board, &port, &AIOhandle); + if (err != AIO_SUCCESS) + { + switch (err) + { + case AIO_PORT_NOT_AVAILABLE: + fprintf (stderr, "Port not available\n"); + break; + + case AIO_BOARD_NUMBER_INVALID: + case AIO_PORT_NUMBER_INVALID: + fprintf (stderr, "No such port\n"); + break; + + default: + fprintf (stderr, "Could not open port: %d\n", err); + break; + } + + exit (1); + } + + err = AIOConfigurePort (AIOhandle, AIO_BAUD_9600, AIO_DATA_BITS_8, + AIO_STOP_BITS_1, AIO_PARITY_NONE, + AIO_HARDWARE_FLOW_CONTROL_OFF); + + if (err == AIO_QUALIFIED_SUCCESS) + { + AIOPORTCONFIG portConfig; + AIODVRCONFIG dvrConfig; + + fprintf (stderr, "Port configuration changed!\n"); + AIOGetPortConfiguration (AIOhandle, &portConfig, &dvrConfig); + fprintf (stderr, + " Bit Rate: %s, Data Bits: %c, Stop Bits: %s, Parity: %c,\ + Flow:%s\n", + baudRates[portConfig.bitRate], + dataBits[portConfig.dataBits], + stopBits[portConfig.stopBits], + parity[portConfig.parityMode], + portConfig.flowCtrlMode ? "ON" : "OFF"); + } + else if (err != AIO_SUCCESS) + { + fprintf (stderr, "Could not configure port: %d\n", err); + AIOReleasePort (AIOhandle); + exit (1); + } + + if (AIOSetExternalControl(AIOhandle, AIO_EXTERNAL_CONTROL, + (AIO_EXTCTRL_DTR | AIO_EXTCTRL_RTS)) + != AIO_SUCCESS) + { + LONG extStatus, chgdExtStatus; + + fprintf (stderr, "Could not set desired port controls!\n"); + AIOGetExternalStatus (AIOhandle, &extStatus, &chgdExtStatus); + fprintf (stderr, "Port controls now: %d, %d\n", extStatus, + chgdExtStatus); + } + + /* Register ourselves as an alternate debugger. */ + memset (&s, 0, sizeof s); + s.DDSResourceTag = ((struct ResourceTagStructure *) + AllocateResourceTag (GetNLMHandle (), + (BYTE *)"gdbserver", + DebuggerSignature)); + if (s.DDSResourceTag == 0) + { + fprintf (stderr, "AllocateResourceTag failed\n"); + AIOReleasePort (AIOhandle); + exit (1); + } + s.DDSdebuggerEntry = handle_exception; + s.DDSFlags = TSS_FRAME_BIT; + + err = RegisterDebuggerRTag (&s, AT_FIRST); + if (err != 0) + { + fprintf (stderr, "RegisterDebuggerRTag failed\n"); + AIOReleasePort (AIOhandle); + exit (1); + } + + /* Get the command line we were invoked with, and advance it past + our name and the board and port arguments. */ + cmdlin = getcmd ((char *) NULL); + for (i = 0; i < 2; i++) + { + while (! isspace (*cmdlin)) + ++cmdlin; + while (isspace (*cmdlin)) + ++cmdlin; + } + + /* In case GDB is started before us, ack any packets (presumably + "$?#xx") sitting there. */ + if (! putDebugChar ('+')) + { + fprintf (stderr, "putDebugChar failed\n"); + UnRegisterDebugger (&s); + AIOReleasePort (AIOhandle); + exit (1); + } + + mainthread = GetThreadID (); + + if (remote_debug > 0) + fprintf (stderr, "About to call LoadModule with \"%s\" %08x\r\n", + cmdlin, __GetScreenID (GetCurrentScreen())); + + /* Start up the module to be debugged. */ + err = LoadModule ((struct ScreenStruct *) __GetScreenID (GetCurrentScreen()), + (BYTE *)cmdlin, LO_DEBUG); + if (err != 0) + { + fprintf (stderr, "LoadModule failed: %d\n", err); + UnRegisterDebugger (&s); + AIOReleasePort (AIOhandle); + exit (1); + } + + /* Wait for the debugger to wake us up. */ + if (remote_debug > 0) + fprintf (stderr, "Suspending main thread (%08x)\r\n", mainthread); + SuspendThread (mainthread); + if (remote_debug > 0) + fprintf (stderr, "Resuming main thread (%08x)\r\n", mainthread); + + /* If we are woken up, print an optional error message, deregister + ourselves and exit. */ + if (error_message != NULL) + fprintf (stderr, "%s\n", error_message); + UnRegisterDebugger (&s); + AIOReleasePort (AIOhandle); + exit (0); +} diff --git a/gdb/nlm/gdbserve.def b/gdb/nlm/gdbserve.def new file mode 100644 index 0000000..5cb8624 --- /dev/null +++ b/gdb/nlm/gdbserve.def @@ -0,0 +1,66 @@ +description "GDB debugger stub" +version 1,2,0 +#debug +screenname "System Console" +input gdbserve +output GDBSERVE.NLM +start _Prelude +exit _Stop +import + exit + getcmd + _get_stdstream + fprintf + UnRegisterDebugger + exit + GetThreadID + GetCurrentScreen + __GetScreenID + ConsolePrintf + GetCurrentScreen + __GetScreenID + LoadModule + _get_stdstream + fprintf + UnRegisterDebugger + exit + ConsolePrintf + SuspendThread + ConsolePrintf + _get_stdstream + fprintf + UnRegisterDebugger + exit + _TerminateNLM + _SetupArgv + _StartNLM + _GetCLibNLMLibHandle + _NWRegisterNLMLibraryUser + ResumeThread + _get_stdstream + fprintf + strlen + ConsolePrintf + GetThreadID + sprintf + strcpy + KillMe + strcmp + exit + memset + memcpy + GetNLMHandle + AllocateResourceTag + RegisterDebuggerRTag + getcmd + UnRegisterDebugger + GetCurrentScreen + __GetScreenID + LoadModule + SuspendThread + _TerminateNLM + _SetupArgv + _StartNLM + _GetCLibNLMLibHandle + _NWRegisterNLMLibraryUser + __get_errno_ptr diff --git a/gdb/nlm/prelude.c b/gdb/nlm/prelude.c new file mode 100644 index 0000000..c2e6857 --- /dev/null +++ b/gdb/nlm/prelude.c @@ -0,0 +1,62 @@ +/*=========================================================================== += Novell Standard C Library for NetWare Loadable Modules += += Unpublished Copyright (C) 1993 by Novell, Inc. All rights reserved. += += No part of this file may be duplicated, revised, translated, localized or += modified in any manner or compiled, linked or uploaded or downloaded to or += from any computer system without the prior written consent of Novell, Inc. +============================================================================== += The object produced by compiling this file is for use by the client of this += library and is not linked in; Prelude.Obj is therefore one of the files to += be distributed with CLib.NLM and its headers. +============================================================================== +*/ +#include <nwpre.h> +#include "libhooks.h" + +static int NLMID; + + +void _Stop( void ) +{ + _TerminateNLM(NLMID, NULL, TERMINATE_BY_UNLOAD); +} + +int _cstart_( void ) +{ + return _SetupArgv(main); +} + +int _Prelude +( + int NLMHandle, + int initErrorScreenID, + char *commandLine, + char *loadDirectoryPath, + int uninitializedDataLength, + int NLMFileHandle, + int (*readRoutineP)(), + int customDataOffset, + int customDataSize +) +{ + int rc; + + rc = _StartNLM(NLMHandle, + initErrorScreenID, + commandLine, + loadDirectoryPath, + uninitializedDataLength, + NLMFileHandle, + readRoutineP, + customDataOffset, + customDataSize, + &NLMID, + _cstart_); + + if (!rc) + rc = _NWRegisterNLMLibraryUser(NLMID, _GetCLibNLMLibHandle()); + + return rc; +} diff --git a/gdb/nlm/prelude.o b/gdb/nlm/prelude.o Binary files differnew file mode 100644 index 0000000..c9f5f42 --- /dev/null +++ b/gdb/nlm/prelude.o |