diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-04-16 14:32:21 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-04-16 14:32:21 +0000 |
commit | f81824a9ed224daf40da0222217618bae9b8d383 (patch) | |
tree | 8b8c7cafabc6a44dc20131ae9f86c32de4874df6 | |
parent | 39f1ebed0b8180d9b48af1b836ce89388eb5de2e (diff) | |
download | gdb-f81824a9ed224daf40da0222217618bae9b8d383.zip gdb-f81824a9ed224daf40da0222217618bae9b8d383.tar.gz gdb-f81824a9ed224daf40da0222217618bae9b8d383.tar.bz2 |
2003-04-16 Andrew Cagney <cagney@redhat.com>
* NEWS: Mention that sparclet-*-* and sparclite-*-* have been made
obsolete.
* sparc-tdep.c: Obsolete SPARCLET and SPARCLITE code.
* sparcl-stub.c: Obsolete file.
* config/sparc/tm-sparclet.h: Obsolete file.
* sparclet-stub.c: Obsolete file.
* sparclet-rom.c: Obsolete file.
* sparcl-tdep.c: Obsolete file.
* config/sparc/tm-sparclite.h: Obsolete file.
* config/sparc/sparclite.mt: Obsolete file.
* config/sparc/sparclet.mt: Obsolete file.
* configure.tgt: Make sparclet-*-*, sparclite-*-*, and
sparc86x-*-* obsolete.
-rw-r--r-- | gdb/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/NEWS | 2 | ||||
-rw-r--r-- | gdb/config/sparc/sparclet.mt | 6 | ||||
-rw-r--r-- | gdb/config/sparc/sparclite.mt | 10 | ||||
-rw-r--r-- | gdb/config/sparc/tm-sparclet.h | 316 | ||||
-rw-r--r-- | gdb/config/sparc/tm-sparclite.h | 246 | ||||
-rw-r--r-- | gdb/configure.tgt | 6 | ||||
-rw-r--r-- | gdb/sparc-tdep.c | 389 | ||||
-rw-r--r-- | gdb/sparcl-stub.c | 1892 | ||||
-rw-r--r-- | gdb/sparcl-tdep.c | 1738 | ||||
-rw-r--r-- | gdb/sparclet-rom.c | 632 | ||||
-rw-r--r-- | gdb/sparclet-stub.c | 2334 |
12 files changed, 3823 insertions, 3764 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a83a8f5..7b589a2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2003-04-16 Andrew Cagney <cagney@redhat.com> + + * NEWS: Mention that sparclet-*-* and sparclite-*-* have been made + obsolete. + * sparc-tdep.c: Obsolete SPARCLET and SPARCLITE code. + * sparcl-stub.c: Obsolete file. + * config/sparc/tm-sparclet.h: Obsolete file. + * sparclet-stub.c: Obsolete file. + * sparclet-rom.c: Obsolete file. + * sparcl-tdep.c: Obsolete file. + * config/sparc/tm-sparclite.h: Obsolete file. + * config/sparc/sparclite.mt: Obsolete file. + * config/sparc/sparclet.mt: Obsolete file. + * configure.tgt: Make sparclet-*-*, sparclite-*-*, and + sparc86x-*-* obsolete. + 2003-04-15 David Carlton <carlton@math.stanford.edu> * Makefile.in (SFILES): Add cp-namespace.c. @@ -48,6 +48,8 @@ PMAX (MIPS) running Mach 3.0 mips*-*-mach3* Sequent family i[3456]86-sequent-sysv4* i[3456]86-sequent-sysv* i[3456]86-sequent-bsd* +Tsqware Sparclet sparclet-*-* +Fujitsu SPARClite sparclite-fujitsu-none or sparclite * REMOVED configurations and files diff --git a/gdb/config/sparc/sparclet.mt b/gdb/config/sparc/sparclet.mt index f08cfd7..5dde41b 100644 --- a/gdb/config/sparc/sparclet.mt +++ b/gdb/config/sparc/sparclet.mt @@ -1,3 +1,3 @@ -# Target: SPARC embedded Sparclet monitor -TDEPFILES= sparc-tdep.o monitor.o sparclet-rom.o dsrec.o -TM_FILE= tm-sparclet.h +# OBSOLETE # Target: SPARC embedded Sparclet monitor +# OBSOLETE TDEPFILES= sparc-tdep.o monitor.o sparclet-rom.o dsrec.o +# OBSOLETE TM_FILE= tm-sparclet.h diff --git a/gdb/config/sparc/sparclite.mt b/gdb/config/sparc/sparclite.mt index 43cb38c..7ae1008 100644 --- a/gdb/config/sparc/sparclite.mt +++ b/gdb/config/sparc/sparclite.mt @@ -1,5 +1,5 @@ -# Target: Fujitsu SPARClite processor -TDEPFILES= sparc-tdep.o sparcl-tdep.o -TM_FILE= tm-sparclite.h -SIM_OBS = remote-sim.o -SIM = ../sim/erc32/libsim.a +# OBSOLETE # Target: Fujitsu SPARClite processor +# OBSOLETE TDEPFILES= sparc-tdep.o sparcl-tdep.o +# OBSOLETE TM_FILE= tm-sparclite.h +# OBSOLETE SIM_OBS = remote-sim.o +# OBSOLETE SIM = ../sim/erc32/libsim.a diff --git a/gdb/config/sparc/tm-sparclet.h b/gdb/config/sparc/tm-sparclet.h index 6aad71d..95bdeea 100644 --- a/gdb/config/sparc/tm-sparclet.h +++ b/gdb/config/sparc/tm-sparclet.h @@ -1,158 +1,158 @@ -/* Target machine definitions for GDB for an embedded SPARC. - Copyright 1996, 1997, 2000 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "regcache.h" - -#define TARGET_SPARCLET 1 /* Still needed for non-multi-arch case */ - -#include "sparc/tm-sparc.h" - -/* Note: we are not defining GDB_MULTI_ARCH for the sparclet target - at this time, because we have not figured out how to detect the - sparclet target from the bfd structure. */ - -/* Sparclet regs, for debugging purposes. */ - -enum { - CCSR_REGNUM = 72, - CCPR_REGNUM = 73, - CCCRCR_REGNUM = 74, - CCOR_REGNUM = 75, - CCOBR_REGNUM = 76, - CCIBR_REGNUM = 77, - CCIR_REGNUM = 78 -}; - -/* Select the sparclet disassembler. Slightly different instruction set from - the V8 sparc. */ - -#undef TM_PRINT_INSN_MACH -#define TM_PRINT_INSN_MACH bfd_mach_sparc_sparclet - -/* overrides of tm-sparc.h */ - -#undef TARGET_BYTE_ORDER - -/* Sequence of bytes for breakpoint instruction (ta 1). */ -#undef BREAKPOINT -#define BIG_BREAKPOINT {0x91, 0xd0, 0x20, 0x01} -#define LITTLE_BREAKPOINT {0x01, 0x20, 0xd0, 0x91} - -#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0) -/* - * The following defines must go away for MULTI_ARCH. - */ - -#undef NUM_REGS /* formerly "72" */ -/* WIN FP CPU CCP ASR AWR APSR */ -#define NUM_REGS (32 + 32 + 8 + 8 + 8/*+ 32 + 1*/) - -#undef REGISTER_BYTES /* formerly "(32*4 + 32*4 + 8*4)" */ -#define REGISTER_BYTES (32*4 + 32*4 + 8*4 + 8*4 + 8*4/* + 32*4 + 1*4*/) - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ -/* Sparclet has no fp! */ -/* Compiler maps types for floats by number, so can't - change the numbers here. */ - -#undef REGISTER_NAMES -#define REGISTER_NAMES \ -{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \ - "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", \ - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ - "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7", \ - \ - "", "", "", "", "", "", "", "", /* no FPU regs */ \ - "", "", "", "", "", "", "", "", \ - "", "", "", "", "", "", "", "", \ - "", "", "", "", "", "", "", "", \ - /* no CPSR, FPSR */ \ - "y", "psr", "wim", "tbr", "pc", "npc", "", "", \ - \ - "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "", \ - \ - /* ASR15 ASR19 (don't display them) */ \ - "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22", \ -/* \ - "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7", \ - "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15", \ - "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23", \ - "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31", \ - "apsr", \ - */ \ -} - -/* Remove FP dependant code which was defined in tm-sparc.h */ -#undef FP0_REGNUM /* Floating point register 0 */ -#undef FPS_REGNUM /* Floating point status register */ -#undef CPS_REGNUM /* Coprocessor status register */ - -/* sparclet register numbers */ -#define CCSR_REGNUM 72 - -#undef DEPRECATED_EXTRACT_RETURN_VALUE -#define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ - { \ - memcpy ((VALBUF), \ - (char *)(REGBUF) + REGISTER_RAW_SIZE (O0_REGNUM) * 8 + \ - (TYPE_LENGTH(TYPE) >= REGISTER_RAW_SIZE (O0_REGNUM) \ - ? 0 : REGISTER_RAW_SIZE (O0_REGNUM) - TYPE_LENGTH(TYPE)), \ - TYPE_LENGTH(TYPE)); \ - } -#undef DEPRECATED_STORE_RETURN_VALUE -#define DEPRECATED_STORE_RETURN_VALUE(TYPE,VALBUF) \ - { \ - /* Other values are returned in register %o0. */ \ - deprecated_write_register_bytes (REGISTER_BYTE (O0_REGNUM), (VALBUF), \ - TYPE_LENGTH (TYPE)); \ - } - -#endif /* GDB_MULTI_ARCH */ - -extern void sparclet_do_registers_info (int regnum, int all); -#undef DEPRECATED_DO_REGISTERS_INFO -#define DEPRECATED_DO_REGISTERS_INFO(REGNUM,ALL) sparclet_do_registers_info (REGNUM, ALL) - - -/* Offsets into jmp_buf. Not defined by Sun, but at least documented in a - comment in <machine/setjmp.h>! */ - -#define JB_ELEMENT_SIZE 4 /* Size of each element in jmp_buf */ - -#define JB_ONSSTACK 0 -#define JB_SIGMASK 1 -#define JB_SP 2 -#define JB_PC 3 -#define JB_NPC 4 -#define JB_PSR 5 -#define JB_G1 6 -#define JB_O0 7 -#define JB_WBCNT 8 - -/* Figure out where the longjmp will land. We expect that we have just entered - longjmp and haven't yet setup the stack frame, so the args are still in the - output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we - extract the pc (JB_PC) that we will land at. The pc is copied into ADDR. - This routine returns true on success */ - -extern int get_longjmp_target (CORE_ADDR *); - -#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR) +// OBSOLETE /* Target machine definitions for GDB for an embedded SPARC. +// OBSOLETE Copyright 1996, 1997, 2000 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE #define TARGET_SPARCLET 1 /* Still needed for non-multi-arch case */ +// OBSOLETE +// OBSOLETE #include "sparc/tm-sparc.h" +// OBSOLETE +// OBSOLETE /* Note: we are not defining GDB_MULTI_ARCH for the sparclet target +// OBSOLETE at this time, because we have not figured out how to detect the +// OBSOLETE sparclet target from the bfd structure. */ +// OBSOLETE +// OBSOLETE /* Sparclet regs, for debugging purposes. */ +// OBSOLETE +// OBSOLETE enum { +// OBSOLETE CCSR_REGNUM = 72, +// OBSOLETE CCPR_REGNUM = 73, +// OBSOLETE CCCRCR_REGNUM = 74, +// OBSOLETE CCOR_REGNUM = 75, +// OBSOLETE CCOBR_REGNUM = 76, +// OBSOLETE CCIBR_REGNUM = 77, +// OBSOLETE CCIR_REGNUM = 78 +// OBSOLETE }; +// OBSOLETE +// OBSOLETE /* Select the sparclet disassembler. Slightly different instruction set from +// OBSOLETE the V8 sparc. */ +// OBSOLETE +// OBSOLETE #undef TM_PRINT_INSN_MACH +// OBSOLETE #define TM_PRINT_INSN_MACH bfd_mach_sparc_sparclet +// OBSOLETE +// OBSOLETE /* overrides of tm-sparc.h */ +// OBSOLETE +// OBSOLETE #undef TARGET_BYTE_ORDER +// OBSOLETE +// OBSOLETE /* Sequence of bytes for breakpoint instruction (ta 1). */ +// OBSOLETE #undef BREAKPOINT +// OBSOLETE #define BIG_BREAKPOINT {0x91, 0xd0, 0x20, 0x01} +// OBSOLETE #define LITTLE_BREAKPOINT {0x01, 0x20, 0xd0, 0x91} +// OBSOLETE +// OBSOLETE #if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0) +// OBSOLETE /* +// OBSOLETE * The following defines must go away for MULTI_ARCH. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE #undef NUM_REGS /* formerly "72" */ +// OBSOLETE /* WIN FP CPU CCP ASR AWR APSR */ +// OBSOLETE #define NUM_REGS (32 + 32 + 8 + 8 + 8/*+ 32 + 1*/) +// OBSOLETE +// OBSOLETE #undef REGISTER_BYTES /* formerly "(32*4 + 32*4 + 8*4)" */ +// OBSOLETE #define REGISTER_BYTES (32*4 + 32*4 + 8*4 + 8*4 + 8*4/* + 32*4 + 1*4*/) +// OBSOLETE +// OBSOLETE /* Initializer for an array of names of registers. +// OBSOLETE There should be NUM_REGS strings in this initializer. */ +// OBSOLETE /* Sparclet has no fp! */ +// OBSOLETE /* Compiler maps types for floats by number, so can't +// OBSOLETE change the numbers here. */ +// OBSOLETE +// OBSOLETE #undef REGISTER_NAMES +// OBSOLETE #define REGISTER_NAMES \ +// OBSOLETE { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \ +// OBSOLETE "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", \ +// OBSOLETE "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ +// OBSOLETE "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7", \ +// OBSOLETE \ +// OBSOLETE "", "", "", "", "", "", "", "", /* no FPU regs */ \ +// OBSOLETE "", "", "", "", "", "", "", "", \ +// OBSOLETE "", "", "", "", "", "", "", "", \ +// OBSOLETE "", "", "", "", "", "", "", "", \ +// OBSOLETE /* no CPSR, FPSR */ \ +// OBSOLETE "y", "psr", "wim", "tbr", "pc", "npc", "", "", \ +// OBSOLETE \ +// OBSOLETE "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "", \ +// OBSOLETE \ +// OBSOLETE /* ASR15 ASR19 (don't display them) */ \ +// OBSOLETE "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22", \ +// OBSOLETE /* \ +// OBSOLETE "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7", \ +// OBSOLETE "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15", \ +// OBSOLETE "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23", \ +// OBSOLETE "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31", \ +// OBSOLETE "apsr", \ +// OBSOLETE */ \ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Remove FP dependant code which was defined in tm-sparc.h */ +// OBSOLETE #undef FP0_REGNUM /* Floating point register 0 */ +// OBSOLETE #undef FPS_REGNUM /* Floating point status register */ +// OBSOLETE #undef CPS_REGNUM /* Coprocessor status register */ +// OBSOLETE +// OBSOLETE /* sparclet register numbers */ +// OBSOLETE #define CCSR_REGNUM 72 +// OBSOLETE +// OBSOLETE #undef DEPRECATED_EXTRACT_RETURN_VALUE +// OBSOLETE #define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ +// OBSOLETE { \ +// OBSOLETE memcpy ((VALBUF), \ +// OBSOLETE (char *)(REGBUF) + REGISTER_RAW_SIZE (O0_REGNUM) * 8 + \ +// OBSOLETE (TYPE_LENGTH(TYPE) >= REGISTER_RAW_SIZE (O0_REGNUM) \ +// OBSOLETE ? 0 : REGISTER_RAW_SIZE (O0_REGNUM) - TYPE_LENGTH(TYPE)), \ +// OBSOLETE TYPE_LENGTH(TYPE)); \ +// OBSOLETE } +// OBSOLETE #undef DEPRECATED_STORE_RETURN_VALUE +// OBSOLETE #define DEPRECATED_STORE_RETURN_VALUE(TYPE,VALBUF) \ +// OBSOLETE { \ +// OBSOLETE /* Other values are returned in register %o0. */ \ +// OBSOLETE deprecated_write_register_bytes (REGISTER_BYTE (O0_REGNUM), (VALBUF), \ +// OBSOLETE TYPE_LENGTH (TYPE)); \ +// OBSOLETE } +// OBSOLETE +// OBSOLETE #endif /* GDB_MULTI_ARCH */ +// OBSOLETE +// OBSOLETE extern void sparclet_do_registers_info (int regnum, int all); +// OBSOLETE #undef DEPRECATED_DO_REGISTERS_INFO +// OBSOLETE #define DEPRECATED_DO_REGISTERS_INFO(REGNUM,ALL) sparclet_do_registers_info (REGNUM, ALL) +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Offsets into jmp_buf. Not defined by Sun, but at least documented in a +// OBSOLETE comment in <machine/setjmp.h>! */ +// OBSOLETE +// OBSOLETE #define JB_ELEMENT_SIZE 4 /* Size of each element in jmp_buf */ +// OBSOLETE +// OBSOLETE #define JB_ONSSTACK 0 +// OBSOLETE #define JB_SIGMASK 1 +// OBSOLETE #define JB_SP 2 +// OBSOLETE #define JB_PC 3 +// OBSOLETE #define JB_NPC 4 +// OBSOLETE #define JB_PSR 5 +// OBSOLETE #define JB_G1 6 +// OBSOLETE #define JB_O0 7 +// OBSOLETE #define JB_WBCNT 8 +// OBSOLETE +// OBSOLETE /* Figure out where the longjmp will land. We expect that we have just entered +// OBSOLETE longjmp and haven't yet setup the stack frame, so the args are still in the +// OBSOLETE output regs. %o0 (O0_REGNUM) points at the jmp_buf structure from which we +// OBSOLETE extract the pc (JB_PC) that we will land at. The pc is copied into ADDR. +// OBSOLETE This routine returns true on success */ +// OBSOLETE +// OBSOLETE extern int get_longjmp_target (CORE_ADDR *); +// OBSOLETE +// OBSOLETE #define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR) diff --git a/gdb/config/sparc/tm-sparclite.h b/gdb/config/sparc/tm-sparclite.h index fb8b6d5..bd8996b 100644 --- a/gdb/config/sparc/tm-sparclite.h +++ b/gdb/config/sparc/tm-sparclite.h @@ -1,123 +1,123 @@ -/* Macro definitions for GDB for a Fujitsu SPARClite. - Copyright 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003 - 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "regcache.h" - -#define TARGET_SPARCLITE 1 /* Still needed for non-multi-arch case */ - -#include "sparc/tm-sparc.h" - -/* Note: we are not defining GDB_MULTI_ARCH for the sparclet target - at this time, because we have not figured out how to detect the - sparclet target from the bfd structure. */ - -/* Sparclite regs, for debugging purposes */ - -enum { - DIA1_REGNUM = 72, /* debug instr address register 1 */ - DIA2_REGNUM = 73, /* debug instr address register 2 */ - DDA1_REGNUM = 74, /* debug data address register 1 */ - DDA2_REGNUM = 75, /* debug data address register 2 */ - DDV1_REGNUM = 76, /* debug data value register 1 */ - DDV2_REGNUM = 77, /* debug data value register 2 */ - DCR_REGNUM = 78, /* debug control register */ - DSR_REGNUM = 79 /* debug status regsiter */ -}; - -/* overrides of tm-sparc.h */ - -#undef TARGET_BYTE_ORDER - -/* Select the sparclite disassembler. Slightly different instruction set from - the V8 sparc. */ - -#undef TM_PRINT_INSN_MACH -#define TM_PRINT_INSN_MACH bfd_mach_sparc_sparclite - -/* Amount PC must be decremented by after a hardware instruction breakpoint. - This is often the number of bytes in BREAKPOINT - but not always. */ - -#define DECR_PC_AFTER_HW_BREAK 4 - -#if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0) -/* - * The following defines must go away for MULTI_ARCH. - */ - -#undef NUM_REGS -#define NUM_REGS 80 - -#undef REGISTER_BYTES -#define REGISTER_BYTES (32*4+32*4+8*4+8*4) - -#undef REGISTER_NAMES -#define REGISTER_NAMES \ -{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \ - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \ - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", \ - \ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ - \ - "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr", \ - "dia1", "dia2", "dda1", "dda2", "ddv1", "ddv2", "dcr", "dsr" } - -#define DIA1_REGNUM 72 /* debug instr address register 1 */ -#define DIA2_REGNUM 73 /* debug instr address register 2 */ -#define DDA1_REGNUM 74 /* debug data address register 1 */ -#define DDA2_REGNUM 75 /* debug data address register 2 */ -#define DDV1_REGNUM 76 /* debug data value register 1 */ -#define DDV2_REGNUM 77 /* debug data value register 2 */ -#define DCR_REGNUM 78 /* debug control register */ -#define DSR_REGNUM 79 /* debug status regsiter */ - -#endif /* GDB_MULTI_ARCH */ - -#define TARGET_HW_BREAK_LIMIT 2 -#define TARGET_HW_WATCH_LIMIT 2 - -/* Enable watchpoint macro's */ - -#define TARGET_HAS_HARDWARE_WATCHPOINTS - -#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \ - sparclite_check_watch_resources (type, cnt, ot) - -/* When a hardware watchpoint fires off the PC will be left at the - instruction which caused the watchpoint. It will be necessary for - GDB to step over the watchpoint. *** - - #define STOPPED_BY_WATCHPOINT(W) \ - ((W).kind == TARGET_WAITKIND_STOPPED \ - && (W).value.sig == TARGET_SIGNAL_TRAP \ - && ((int) read_register (IPSW_REGNUM) & 0x00100000)) - */ - -/* Use these macros for watchpoint insertion/deletion. */ -#define target_insert_watchpoint(addr, len, type) sparclite_insert_watchpoint (addr, len, type) -#define target_remove_watchpoint(addr, len, type) sparclite_remove_watchpoint (addr, len, type) -#define target_insert_hw_breakpoint(addr, len) sparclite_insert_hw_breakpoint (addr, len) -#define target_remove_hw_breakpoint(addr, len) sparclite_remove_hw_breakpoint (addr, len) -#define target_stopped_data_address() sparclite_stopped_data_address() +// OBSOLETE /* Macro definitions for GDB for a Fujitsu SPARClite. +// OBSOLETE Copyright 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE #define TARGET_SPARCLITE 1 /* Still needed for non-multi-arch case */ +// OBSOLETE +// OBSOLETE #include "sparc/tm-sparc.h" +// OBSOLETE +// OBSOLETE /* Note: we are not defining GDB_MULTI_ARCH for the sparclet target +// OBSOLETE at this time, because we have not figured out how to detect the +// OBSOLETE sparclet target from the bfd structure. */ +// OBSOLETE +// OBSOLETE /* Sparclite regs, for debugging purposes */ +// OBSOLETE +// OBSOLETE enum { +// OBSOLETE DIA1_REGNUM = 72, /* debug instr address register 1 */ +// OBSOLETE DIA2_REGNUM = 73, /* debug instr address register 2 */ +// OBSOLETE DDA1_REGNUM = 74, /* debug data address register 1 */ +// OBSOLETE DDA2_REGNUM = 75, /* debug data address register 2 */ +// OBSOLETE DDV1_REGNUM = 76, /* debug data value register 1 */ +// OBSOLETE DDV2_REGNUM = 77, /* debug data value register 2 */ +// OBSOLETE DCR_REGNUM = 78, /* debug control register */ +// OBSOLETE DSR_REGNUM = 79 /* debug status regsiter */ +// OBSOLETE }; +// OBSOLETE +// OBSOLETE /* overrides of tm-sparc.h */ +// OBSOLETE +// OBSOLETE #undef TARGET_BYTE_ORDER +// OBSOLETE +// OBSOLETE /* Select the sparclite disassembler. Slightly different instruction set from +// OBSOLETE the V8 sparc. */ +// OBSOLETE +// OBSOLETE #undef TM_PRINT_INSN_MACH +// OBSOLETE #define TM_PRINT_INSN_MACH bfd_mach_sparc_sparclite +// OBSOLETE +// OBSOLETE /* Amount PC must be decremented by after a hardware instruction breakpoint. +// OBSOLETE This is often the number of bytes in BREAKPOINT +// OBSOLETE but not always. */ +// OBSOLETE +// OBSOLETE #define DECR_PC_AFTER_HW_BREAK 4 +// OBSOLETE +// OBSOLETE #if !defined (GDB_MULTI_ARCH) || (GDB_MULTI_ARCH == 0) +// OBSOLETE /* +// OBSOLETE * The following defines must go away for MULTI_ARCH. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE #undef NUM_REGS +// OBSOLETE #define NUM_REGS 80 +// OBSOLETE +// OBSOLETE #undef REGISTER_BYTES +// OBSOLETE #define REGISTER_BYTES (32*4+32*4+8*4+8*4) +// OBSOLETE +// OBSOLETE #undef REGISTER_NAMES +// OBSOLETE #define REGISTER_NAMES \ +// OBSOLETE { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \ +// OBSOLETE "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \ +// OBSOLETE "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ +// OBSOLETE "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", \ +// OBSOLETE \ +// OBSOLETE "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ +// OBSOLETE "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ +// OBSOLETE "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ +// OBSOLETE "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ +// OBSOLETE \ +// OBSOLETE "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr", \ +// OBSOLETE "dia1", "dia2", "dda1", "dda2", "ddv1", "ddv2", "dcr", "dsr" } +// OBSOLETE +// OBSOLETE #define DIA1_REGNUM 72 /* debug instr address register 1 */ +// OBSOLETE #define DIA2_REGNUM 73 /* debug instr address register 2 */ +// OBSOLETE #define DDA1_REGNUM 74 /* debug data address register 1 */ +// OBSOLETE #define DDA2_REGNUM 75 /* debug data address register 2 */ +// OBSOLETE #define DDV1_REGNUM 76 /* debug data value register 1 */ +// OBSOLETE #define DDV2_REGNUM 77 /* debug data value register 2 */ +// OBSOLETE #define DCR_REGNUM 78 /* debug control register */ +// OBSOLETE #define DSR_REGNUM 79 /* debug status regsiter */ +// OBSOLETE +// OBSOLETE #endif /* GDB_MULTI_ARCH */ +// OBSOLETE +// OBSOLETE #define TARGET_HW_BREAK_LIMIT 2 +// OBSOLETE #define TARGET_HW_WATCH_LIMIT 2 +// OBSOLETE +// OBSOLETE /* Enable watchpoint macro's */ +// OBSOLETE +// OBSOLETE #define TARGET_HAS_HARDWARE_WATCHPOINTS +// OBSOLETE +// OBSOLETE #define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \ +// OBSOLETE sparclite_check_watch_resources (type, cnt, ot) +// OBSOLETE +// OBSOLETE /* When a hardware watchpoint fires off the PC will be left at the +// OBSOLETE instruction which caused the watchpoint. It will be necessary for +// OBSOLETE GDB to step over the watchpoint. *** +// OBSOLETE +// OBSOLETE #define STOPPED_BY_WATCHPOINT(W) \ +// OBSOLETE ((W).kind == TARGET_WAITKIND_STOPPED \ +// OBSOLETE && (W).value.sig == TARGET_SIGNAL_TRAP \ +// OBSOLETE && ((int) read_register (IPSW_REGNUM) & 0x00100000)) +// OBSOLETE */ +// OBSOLETE +// OBSOLETE /* Use these macros for watchpoint insertion/deletion. */ +// OBSOLETE #define target_insert_watchpoint(addr, len, type) sparclite_insert_watchpoint (addr, len, type) +// OBSOLETE #define target_remove_watchpoint(addr, len, type) sparclite_remove_watchpoint (addr, len, type) +// OBSOLETE #define target_insert_hw_breakpoint(addr, len) sparclite_insert_hw_breakpoint (addr, len) +// OBSOLETE #define target_remove_hw_breakpoint(addr, len) sparclite_remove_hw_breakpoint (addr, len) +// OBSOLETE #define target_stopped_data_address() sparclite_stopped_data_address() diff --git a/gdb/configure.tgt b/gdb/configure.tgt index df174a7..aeb9e271 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -229,9 +229,9 @@ sparc-*-sunos4*) gdb_target=sun4os4 ;; sparc-*-sunos5*) gdb_target=sun4sol2 ;; sparc-*-vxworks*) gdb_target=vxsparc ;; sparc-*-*) gdb_target=sun4os4 ;; -sparclet-*-*) gdb_target=sparclet;; -sparclite-*-*) gdb_target=sparclite ;; -sparc86x-*-*) gdb_target=sparclite ;; +# OBSOLETE sparclet-*-*) gdb_target=sparclet;; +# OBSOLETE sparclite-*-*) gdb_target=sparclite ;; +# OBSOLETE sparc86x-*-*) gdb_target=sparclite ;; # It's not clear what the right solution for "v8plus" systems is yet. # For now, stick with sparc-sun-solaris2 since that's what config.guess # should return. Work is still needed to get gdb to print the 64 bit diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 32f2801..e1a0089 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -66,11 +66,14 @@ /* Does the target have Floating Point registers? */ -#if defined(TARGET_SPARCLET) || defined(TARGET_SPARCLITE) -#define SPARC_HAS_FPU 0 -#else -#define SPARC_HAS_FPU 1 +#if 0 +// OBSOLETE #if defined(TARGET_SPARCLET) || defined(TARGET_SPARCLITE) +// OBSOLETE #define SPARC_HAS_FPU 0 +// OBSOLETE #else +// OBSOLETE #define SPARC_HAS_FPU 1 +// OBSOLETE #endif #endif +#define SPARC_HAS_FPU 1 /* Number of bytes devoted to Floating Point registers: */ #if (GDB_TARGET_IS_SPARC64) @@ -104,7 +107,9 @@ struct gdbarch_tdep { - int has_fpu; +#if 0 + // OBSOLETE int has_fpu; +#endif int fp_register_bytes; int y_regnum; int fp_max_regnum; @@ -134,11 +139,13 @@ extern int stop_after_trap; int deferred_stores = 0; /* Accumulated stores we want to do eventually. */ -/* Some machines, such as Fujitsu SPARClite 86x, have a bi-endian mode - where instructions are big-endian and data are little-endian. - This flag is set when we detect that the target is of this type. */ - -int bi_endian = 0; +#if 0 +// OBSOLETE /* Some machines, such as Fujitsu SPARClite 86x, have a bi-endian mode +// OBSOLETE where instructions are big-endian and data are little-endian. +// OBSOLETE This flag is set when we detect that the target is of this type. */ +// OBSOLETE +// OBSOLETE int bi_endian = 0; +#endif /* Fetch a single instruction. Even on bi-endian machines @@ -2174,21 +2181,23 @@ sparc_do_registers_info (int regnum, int all) regnum, all); } -static void -sparclet_print_registers_info (struct gdbarch *gdbarch, - struct ui_file *file, - struct frame_info *frame, - int regnum, int print_all) -{ - sparc_print_registers (gdbarch, file, frame, regnum, print_all, NULL); -} - -void -sparclet_do_registers_info (int regnum, int all) -{ - sparclet_print_registers_info (current_gdbarch, gdb_stdout, - deprecated_selected_frame, regnum, all); -} +#if 0 +// OBSOLETE static void +// OBSOLETE sparclet_print_registers_info (struct gdbarch *gdbarch, +// OBSOLETE struct ui_file *file, +// OBSOLETE struct frame_info *frame, +// OBSOLETE int regnum, int print_all) +// OBSOLETE { +// OBSOLETE sparc_print_registers (gdbarch, file, frame, regnum, print_all, NULL); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE sparclet_do_registers_info (int regnum, int all) +// OBSOLETE { +// OBSOLETE sparclet_print_registers_info (current_gdbarch, gdb_stdout, +// OBSOLETE deprecated_selected_frame, regnum, all); +// OBSOLETE } +#endif int @@ -2324,13 +2333,15 @@ sparc_store_return_value (struct type *type, char *valbuf) TYPE_LENGTH (type)); } -extern void -sparclet_store_return_value (struct type *type, char *valbuf) -{ - /* Other values are returned in register %o0. */ - deprecated_write_register_bytes (REGISTER_BYTE (O0_REGNUM), valbuf, - TYPE_LENGTH (type)); -} +#if 0 +// OBSOLETE extern void +// OBSOLETE sparclet_store_return_value (struct type *type, char *valbuf) +// OBSOLETE { +// OBSOLETE /* Other values are returned in register %o0. */ +// OBSOLETE deprecated_write_register_bytes (REGISTER_BYTE (O0_REGNUM), valbuf, +// OBSOLETE TYPE_LENGTH (type)); +// OBSOLETE } +#endif #ifndef CALL_DUMMY_CALL_OFFSET @@ -2396,40 +2407,43 @@ sparc_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, } } - /* If this is a bi-endian target, GDB has written the call dummy - in little-endian order. We must byte-swap it back to big-endian. */ - if (bi_endian) - { - for (i = 0; i < CALL_DUMMY_LENGTH; i += 4) - { - char tmp = dummy[i]; - dummy[i] = dummy[i + 3]; - dummy[i + 3] = tmp; - tmp = dummy[i + 1]; - dummy[i + 1] = dummy[i + 2]; - dummy[i + 2] = tmp; - } - } +#if 0 +// OBSOLETE /* If this is a bi-endian target, GDB has written the call dummy +// OBSOLETE in little-endian order. We must byte-swap it back to big-endian. */ +// OBSOLETE if (bi_endian) +// OBSOLETE { +// OBSOLETE for (i = 0; i < CALL_DUMMY_LENGTH; i += 4) +// OBSOLETE { +// OBSOLETE char tmp = dummy[i]; +// OBSOLETE dummy[i] = dummy[i + 3]; +// OBSOLETE dummy[i + 3] = tmp; +// OBSOLETE tmp = dummy[i + 1]; +// OBSOLETE dummy[i + 1] = dummy[i + 2]; +// OBSOLETE dummy[i + 2] = tmp; +// OBSOLETE } +// OBSOLETE } +#endif } -/* Set target byte order based on machine type. */ - -static int -sparc_target_architecture_hook (const bfd_arch_info_type *ap) -{ - int i, j; - - if (ap->mach == bfd_mach_sparc_sparclite_le) - { - target_byte_order = BFD_ENDIAN_LITTLE; - bi_endian = 1; - } - else - bi_endian = 0; - return 1; -} - +#if 0 +// OBSOLETE /* Set target byte order based on machine type. */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE sparc_target_architecture_hook (const bfd_arch_info_type *ap) +// OBSOLETE { +// OBSOLETE int i, j; +// OBSOLETE +// OBSOLETE if (ap->mach == bfd_mach_sparc_sparclite_le) +// OBSOLETE { +// OBSOLETE target_byte_order = BFD_ENDIAN_LITTLE; +// OBSOLETE bi_endian = 1; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE bi_endian = 0; +// OBSOLETE return 1; +// OBSOLETE } +#endif /* * Module "constructor" function. @@ -2447,7 +2461,7 @@ _initialize_sparc_tdep (void) tm_print_insn = gdb_print_insn_sparc; tm_print_insn_info.mach = TM_PRINT_INSN_MACH; /* Selects sparc/sparclite */ - target_architecture_hook = sparc_target_architecture_hook; + /* OBSOLETE target_architecture_hook = sparc_target_architecture_hook; */ } /* Compensate for stack bias. Note that we currently don't handle @@ -2677,18 +2691,19 @@ sparc64_extract_return_value (struct type *type, char *regbuf, char *valbuf) sp64_extract_return_value (type, regbuf, valbuf, 0); } -extern void -sparclet_extract_return_value (struct type *type, - char *regbuf, - char *valbuf) -{ - regbuf += REGISTER_RAW_SIZE (O0_REGNUM) * 8; - if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (O0_REGNUM)) - regbuf += REGISTER_RAW_SIZE (O0_REGNUM) - TYPE_LENGTH (type); - - memcpy ((void *) valbuf, regbuf, TYPE_LENGTH (type)); -} - +#if 0 +// OBSOLETE extern void +// OBSOLETE sparclet_extract_return_value (struct type *type, +// OBSOLETE char *regbuf, +// OBSOLETE char *valbuf) +// OBSOLETE { +// OBSOLETE regbuf += REGISTER_RAW_SIZE (O0_REGNUM) * 8; +// OBSOLETE if (TYPE_LENGTH (type) < REGISTER_RAW_SIZE (O0_REGNUM)) +// OBSOLETE regbuf += REGISTER_RAW_SIZE (O0_REGNUM) - TYPE_LENGTH (type); +// OBSOLETE +// OBSOLETE memcpy ((void *) valbuf, regbuf, TYPE_LENGTH (type)); +// OBSOLETE } +#endif extern CORE_ADDR sparc32_stack_align (CORE_ADDR addr) @@ -2769,66 +2784,70 @@ sparc64_register_name (int regno) return register_names[regno]; } -static const char * -sparclite_register_name (int regno) -{ - static char *register_names[] = - { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - - "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr", - "dia1", "dia2", "dda1", "dda2", "ddv1", "ddv2", "dcr", "dsr" - }; - - if (regno < 0 || - regno >= (sizeof (register_names) / sizeof (register_names[0]))) - return NULL; - else - return register_names[regno]; -} - -static const char * -sparclet_register_name (int regno) -{ - static char *register_names[] = - { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", - - "", "", "", "", "", "", "", "", /* no floating point registers */ - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - - "y", "psr", "wim", "tbr", "pc", "npc", "", "", /* no FPSR or CPSR */ - "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "", - - /* ASR15 ASR19 (don't display them) */ - "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22" - /* None of the rest get displayed */ #if 0 - "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7", - "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15", - "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23", - "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31", - "apsr" -#endif /* 0 */ - }; +// OBSOLETE static const char * +// OBSOLETE sparclite_register_name (int regno) +// OBSOLETE { +// OBSOLETE static char *register_names[] = +// OBSOLETE { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", +// OBSOLETE "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", +// OBSOLETE "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", +// OBSOLETE "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", +// OBSOLETE +// OBSOLETE "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", +// OBSOLETE "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", +// OBSOLETE "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", +// OBSOLETE "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", +// OBSOLETE +// OBSOLETE "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr", +// OBSOLETE "dia1", "dia2", "dda1", "dda2", "ddv1", "ddv2", "dcr", "dsr" +// OBSOLETE }; +// OBSOLETE +// OBSOLETE if (regno < 0 || +// OBSOLETE regno >= (sizeof (register_names) / sizeof (register_names[0]))) +// OBSOLETE return NULL; +// OBSOLETE else +// OBSOLETE return register_names[regno]; +// OBSOLETE } +#endif - if (regno < 0 || - regno >= (sizeof (register_names) / sizeof (register_names[0]))) - return NULL; - else - return register_names[regno]; -} +#if 0 +// OBSOLETE static const char * +// OBSOLETE sparclet_register_name (int regno) +// OBSOLETE { +// OBSOLETE static char *register_names[] = +// OBSOLETE { "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", +// OBSOLETE "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", +// OBSOLETE "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", +// OBSOLETE "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", +// OBSOLETE +// OBSOLETE "", "", "", "", "", "", "", "", /* no floating point registers */ +// OBSOLETE "", "", "", "", "", "", "", "", +// OBSOLETE "", "", "", "", "", "", "", "", +// OBSOLETE "", "", "", "", "", "", "", "", +// OBSOLETE +// OBSOLETE "y", "psr", "wim", "tbr", "pc", "npc", "", "", /* no FPSR or CPSR */ +// OBSOLETE "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "", +// OBSOLETE +// OBSOLETE /* ASR15 ASR19 (don't display them) */ +// OBSOLETE "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22" +// OBSOLETE /* None of the rest get displayed */ +// OBSOLETE #if 0 +// OBSOLETE "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7", +// OBSOLETE "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15", +// OBSOLETE "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23", +// OBSOLETE "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31", +// OBSOLETE "apsr" +// OBSOLETE #endif /* 0 */ +// OBSOLETE }; +// OBSOLETE +// OBSOLETE if (regno < 0 || +// OBSOLETE regno >= (sizeof (register_names) / sizeof (register_names[0]))) +// OBSOLETE return NULL; +// OBSOLETE else +// OBSOLETE return register_names[regno]; +// OBSOLETE } +#endif CORE_ADDR sparc_push_return_address (CORE_ADDR pc_unused, CORE_ADDR sp) @@ -3184,11 +3203,15 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) switch (info.bfd_arch_info->mach) { case bfd_mach_sparc: - case bfd_mach_sparc_sparclet: - case bfd_mach_sparc_sparclite: +#if 0 + // OBSOLETE case bfd_mach_sparc_sparclet: + // OBSOLETE case bfd_mach_sparc_sparclite: +#endif case bfd_mach_sparc_v8plus: case bfd_mach_sparc_v8plusa: - case bfd_mach_sparc_sparclite_le: +#if 0 + // OBSOLETE case bfd_mach_sparc_sparclite_le: +#endif /* 32-bit machine types: */ #ifdef SPARC32_CALL_DUMMY_ON_STACK @@ -3348,30 +3371,36 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4); set_gdbarch_register_name (gdbarch, sparc32_register_name); set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#if 0 + // OBSOLETE tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#endif tdep->fp_register_bytes = 32 * 4; tdep->print_insn_mach = bfd_mach_sparc; break; - case bfd_mach_sparc_sparclet: - set_gdbarch_deprecated_extract_return_value (gdbarch, sparclet_extract_return_value); - set_gdbarch_num_regs (gdbarch, 32 + 32 + 8 + 8 + 8); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparclet_register_name); - set_gdbarch_deprecated_store_return_value (gdbarch, sparclet_store_return_value); - tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 0; - tdep->print_insn_mach = bfd_mach_sparc_sparclet; - break; - case bfd_mach_sparc_sparclite: - set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value); - set_gdbarch_num_regs (gdbarch, 80); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparclite_register_name); - set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 0; - tdep->print_insn_mach = bfd_mach_sparc_sparclite; - break; +#if 0 + // OBSOLETE case bfd_mach_sparc_sparclet: + // OBSOLETE set_gdbarch_deprecated_extract_return_value (gdbarch, sparclet_extract_return_value); + // OBSOLETE set_gdbarch_num_regs (gdbarch, 32 + 32 + 8 + 8 + 8); + // OBSOLETE set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4 + 8*4); + // OBSOLETE set_gdbarch_register_name (gdbarch, sparclet_register_name); + // OBSOLETE set_gdbarch_deprecated_store_return_value (gdbarch, sparclet_store_return_value); + // OBSOLETE tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ + // OBSOLETE tdep->fp_register_bytes = 0; + // OBSOLETE tdep->print_insn_mach = bfd_mach_sparc_sparclet; + // OBSOLETE break; +#endif +#if 0 + // OBSOLETE case bfd_mach_sparc_sparclite: + // OBSOLETE set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value); + // OBSOLETE set_gdbarch_num_regs (gdbarch, 80); + // OBSOLETE set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4); + // OBSOLETE set_gdbarch_register_name (gdbarch, sparclite_register_name); + // OBSOLETE set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); + // OBSOLETE tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ + // OBSOLETE tdep->fp_register_bytes = 0; + // OBSOLETE tdep->print_insn_mach = bfd_mach_sparc_sparclite; + // OBSOLETE break; +#endif case bfd_mach_sparc_v8plus: set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value); set_gdbarch_num_regs (gdbarch, 72); @@ -3380,7 +3409,9 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); tdep->print_insn_mach = bfd_mach_sparc; tdep->fp_register_bytes = 32 * 4; - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#if 0 + // OBSOLETE tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#endif break; case bfd_mach_sparc_v8plusa: set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value); @@ -3388,27 +3419,33 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4); set_gdbarch_register_name (gdbarch, sparc32_register_name); set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#if 0 + // OBSOLETE tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#endif tdep->fp_register_bytes = 32 * 4; tdep->print_insn_mach = bfd_mach_sparc; break; - case bfd_mach_sparc_sparclite_le: - set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value); - set_gdbarch_num_regs (gdbarch, 80); - set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4); - set_gdbarch_register_name (gdbarch, sparclite_register_name); - set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ - tdep->fp_register_bytes = 0; - tdep->print_insn_mach = bfd_mach_sparc_sparclite; - break; +#if 0 +// OBSOLETE case bfd_mach_sparc_sparclite_le: +// OBSOLETE set_gdbarch_deprecated_extract_return_value (gdbarch, sparc32_extract_return_value); +// OBSOLETE set_gdbarch_num_regs (gdbarch, 80); +// OBSOLETE set_gdbarch_register_bytes (gdbarch, 32*4 + 32*4 + 8*4 + 8*4); +// OBSOLETE set_gdbarch_register_name (gdbarch, sparclite_register_name); +// OBSOLETE set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); +// OBSOLETE tdep->has_fpu = 0; /* (all but sparclet and sparclite) */ +// OBSOLETE tdep->fp_register_bytes = 0; +// OBSOLETE tdep->print_insn_mach = bfd_mach_sparc_sparclite; +// OBSOLETE break; +#endif case bfd_mach_sparc_v9: set_gdbarch_deprecated_extract_return_value (gdbarch, sparc64_extract_return_value); set_gdbarch_num_regs (gdbarch, 125); set_gdbarch_register_bytes (gdbarch, 32*8 + 32*8 + 45*8); set_gdbarch_register_name (gdbarch, sparc64_register_name); set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#if 0 + // OBSOLETE tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#endif tdep->fp_register_bytes = 64 * 4; tdep->print_insn_mach = bfd_mach_sparc_v9a; break; @@ -3418,7 +3455,9 @@ sparc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_register_bytes (gdbarch, 32*8 + 32*8 + 45*8); set_gdbarch_register_name (gdbarch, sparc64_register_name); set_gdbarch_deprecated_store_return_value (gdbarch, sparc_store_return_value); - tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#if 0 + // OBSOLETE tdep->has_fpu = 1; /* (all but sparclet and sparclite) */ +#endif tdep->fp_register_bytes = 64 * 4; tdep->print_insn_mach = bfd_mach_sparc_v9a; break; @@ -3438,8 +3477,10 @@ sparc_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) if (tdep == NULL) return; - fprintf_unfiltered (file, "sparc_dump_tdep: has_fpu = %d\n", - tdep->has_fpu); +#if 0 + // OBSOLETE fprintf_unfiltered (file, "sparc_dump_tdep: has_fpu = %d\n", + // OBSOLETE tdep->has_fpu); +#endif fprintf_unfiltered (file, "sparc_dump_tdep: fp_register_bytes = %d\n", tdep->fp_register_bytes); fprintf_unfiltered (file, "sparc_dump_tdep: y_regnum = %d\n", diff --git a/gdb/sparcl-stub.c b/gdb/sparcl-stub.c index 3fcdc0a..6ba55a0 100644 --- a/gdb/sparcl-stub.c +++ b/gdb/sparcl-stub.c @@ -1,946 +1,946 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for SPARC by Stu Grossman, Cygnus Support. - * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware - * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support. - * - * This code has been extensively tested on the Fujitsu SPARClite demo board. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * P set the value of a single CPU register OK or 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 <string.h> -#include <signal.h> -#include <sparclite.h> - -/************************************************************************ - * - * external low-level support routines - */ - -extern void putDebugChar (int c); /* write a single character */ -extern int getDebugChar (void); /* read and return a single char */ - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 2048 - -static int initialized = 0; /* !0 means we've been initialized */ - -extern void breakinst (); -static void set_mem_fault_trap (int enable); -static void get_in_break_mode (void); - -static const char hexchars[]="0123456789abcdef"; - -#define NUMREGS 80 - -/* Number of bytes of registers. */ -#define NUMREGBYTES (NUMREGS * 4) -enum regnames {G0, G1, G2, G3, G4, G5, G6, G7, - O0, O1, O2, O3, O4, O5, SP, O7, - L0, L1, L2, L3, L4, L5, L6, L7, - I0, I1, I2, I3, I4, I5, FP, I7, - - F0, F1, F2, F3, F4, F5, F6, F7, - F8, F9, F10, F11, F12, F13, F14, F15, - F16, F17, F18, F19, F20, F21, F22, F23, - F24, F25, F26, F27, F28, F29, F30, F31, - Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR, - DIA1, DIA2, DDA1, DDA2, DDV1, DDV2, DCR, DSR }; - -/*************************** ASSEMBLY CODE MACROS *************************/ -/* */ - -extern void trap_low(); - -/* Create private copies of common functions used by the stub. This prevents - nasty interactions between app code and the stub (for instance if user steps - into strlen, etc..) */ - -static char * -strcpy (char *dst, const char *src) -{ - char *retval = dst; - - while ((*dst++ = *src++) != '\000'); - - return retval; -} - -static void * -memcpy (void *vdst, const void *vsrc, int n) -{ - char *dst = vdst; - const char *src = vsrc; - char *retval = dst; - - while (n-- > 0) - *dst++ = *src++; - - return retval; -} - -asm(" - .reserve trapstack, 1000 * 4, \"bss\", 8 - - .data - .align 4 - -in_trap_handler: - .word 0 - - .text - .align 4 - -! This function is called when any SPARC trap (except window overflow or -! underflow) occurs. It makes sure that the invalid register window is still -! available before jumping into C code. It will also restore the world if you -! return from handle_exception. -! -! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly. -! Register usage throughout the routine is as follows: -! -! l0 - psr -! l1 - pc -! l2 - npc -! l3 - wim -! l4 - scratch and y reg -! l5 - scratch and tbr -! l6 - unused -! l7 - unused - - .globl _trap_low -_trap_low: - mov %psr, %l0 - mov %wim, %l3 - - srl %l3, %l0, %l4 ! wim >> cwp - cmp %l4, 1 - bne window_fine ! Branch if not in the invalid window - nop - -! Handle window overflow - - mov %g1, %l4 ! Save g1, we use it to hold the wim - srl %l3, 1, %g1 ! Rotate wim right - tst %g1 - bg good_wim ! Branch if new wim is non-zero - nop - -! At this point, we need to bring a 1 into the high order bit of the wim. -! Since we don't want to make any assumptions about the number of register -! windows, we figure it out dynamically so as to setup the wim correctly. - - not %g1 ! Fill g1 with ones - mov %g1, %wim ! Fill the wim with ones - nop - nop - nop - mov %wim, %g1 ! Read back the wim - inc %g1 ! Now g1 has 1 just to left of wim - srl %g1, 1, %g1 ! Now put 1 at top of wim - mov %g0, %wim ! Clear wim so that subsequent save - nop ! won't trap - nop - nop - -good_wim: - save %g0, %g0, %g0 ! Slip into next window - mov %g1, %wim ! Install the new wim - - std %l0, [%sp + 0 * 4] ! save L & I registers - std %l2, [%sp + 2 * 4] - std %l4, [%sp + 4 * 4] - std %l6, [%sp + 6 * 4] - - std %i0, [%sp + 8 * 4] - std %i2, [%sp + 10 * 4] - std %i4, [%sp + 12 * 4] - std %i6, [%sp + 14 * 4] - - restore ! Go back to trap window. - mov %l4, %g1 ! Restore %g1 - -window_fine: - sethi %hi(in_trap_handler), %l4 - ld [%lo(in_trap_handler) + %l4], %l5 - tst %l5 - bg recursive_trap - inc %l5 - - set trapstack+1000*4, %sp ! Switch to trap stack - -recursive_trap: - st %l5, [%lo(in_trap_handler) + %l4] - sub %sp,(16+1+6+1+80)*4,%sp ! Make room for input & locals - ! + hidden arg + arg spill - ! + doubleword alignment - ! + registers[72] local var - - std %g0, [%sp + (24 + 0) * 4] ! registers[Gx] - std %g2, [%sp + (24 + 2) * 4] - std %g4, [%sp + (24 + 4) * 4] - std %g6, [%sp + (24 + 6) * 4] - - std %i0, [%sp + (24 + 8) * 4] ! registers[Ox] - std %i2, [%sp + (24 + 10) * 4] - std %i4, [%sp + (24 + 12) * 4] - std %i6, [%sp + (24 + 14) * 4] - - mov %y, %l4 - mov %tbr, %l5 - st %l4, [%sp + (24 + 64) * 4] ! Y - st %l0, [%sp + (24 + 65) * 4] ! PSR - st %l3, [%sp + (24 + 66) * 4] ! WIM - st %l5, [%sp + (24 + 67) * 4] ! TBR - st %l1, [%sp + (24 + 68) * 4] ! PC - st %l2, [%sp + (24 + 69) * 4] ! NPC - - or %l0, 0xf20, %l4 - mov %l4, %psr ! Turn on traps, disable interrupts - - set 0x1000, %l1 - btst %l1, %l0 ! FP enabled? - be no_fpstore - nop - -! Must save fsr first, to flush the FQ. This may cause a deferred fp trap, so -! traps must be enabled to allow the trap handler to clean things up. - - st %fsr, [%sp + (24 + 70) * 4] - - std %f0, [%sp + (24 + 32) * 4] - std %f2, [%sp + (24 + 34) * 4] - std %f4, [%sp + (24 + 36) * 4] - std %f6, [%sp + (24 + 38) * 4] - std %f8, [%sp + (24 + 40) * 4] - std %f10, [%sp + (24 + 42) * 4] - std %f12, [%sp + (24 + 44) * 4] - std %f14, [%sp + (24 + 46) * 4] - std %f16, [%sp + (24 + 48) * 4] - std %f18, [%sp + (24 + 50) * 4] - std %f20, [%sp + (24 + 52) * 4] - std %f22, [%sp + (24 + 54) * 4] - std %f24, [%sp + (24 + 56) * 4] - std %f26, [%sp + (24 + 58) * 4] - std %f28, [%sp + (24 + 60) * 4] - std %f30, [%sp + (24 + 62) * 4] -no_fpstore: - - call _handle_exception - add %sp, 24 * 4, %o0 ! Pass address of registers - -! Reload all of the registers that aren't on the stack - - ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx] - ldd [%sp + (24 + 2) * 4], %g2 - ldd [%sp + (24 + 4) * 4], %g4 - ldd [%sp + (24 + 6) * 4], %g6 - - ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox] - ldd [%sp + (24 + 10) * 4], %i2 - ldd [%sp + (24 + 12) * 4], %i4 - ldd [%sp + (24 + 14) * 4], %i6 - - - ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR - ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC - - set 0x1000, %l5 - btst %l5, %l1 ! FP enabled? - be no_fpreload - nop - - ldd [%sp + (24 + 32) * 4], %f0 - ldd [%sp + (24 + 34) * 4], %f2 - ldd [%sp + (24 + 36) * 4], %f4 - ldd [%sp + (24 + 38) * 4], %f6 - ldd [%sp + (24 + 40) * 4], %f8 - ldd [%sp + (24 + 42) * 4], %f10 - ldd [%sp + (24 + 44) * 4], %f12 - ldd [%sp + (24 + 46) * 4], %f14 - ldd [%sp + (24 + 48) * 4], %f16 - ldd [%sp + (24 + 50) * 4], %f18 - ldd [%sp + (24 + 52) * 4], %f20 - ldd [%sp + (24 + 54) * 4], %f22 - ldd [%sp + (24 + 56) * 4], %f24 - ldd [%sp + (24 + 58) * 4], %f26 - ldd [%sp + (24 + 60) * 4], %f28 - ldd [%sp + (24 + 62) * 4], %f30 - - ld [%sp + (24 + 70) * 4], %fsr -no_fpreload: - - restore ! Ensure that previous window is valid - save %g0, %g0, %g0 ! by causing a window_underflow trap - - mov %l0, %y - mov %l1, %psr ! Make sure that traps are disabled - ! for rett - sethi %hi(in_trap_handler), %l4 - ld [%lo(in_trap_handler) + %l4], %l5 - dec %l5 - st %l5, [%lo(in_trap_handler) + %l4] - - jmpl %l2, %g0 ! Restore old PC - rett %l3 ! Restore old nPC -"); - -/* Convert ch from a hex digit to an int */ - -static int -hex (unsigned char ch) -{ - if (ch >= 'a' && ch <= 'f') - return ch-'a'+10; - if (ch >= '0' && ch <= '9') - return ch-'0'; - if (ch >= 'A' && ch <= 'F') - return ch-'A'+10; - return -1; -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -/* scan for the sequence $<data>#<checksum> */ - -unsigned char * -getpacket (void) -{ - unsigned char *buffer = &remcomInBuffer[0]; - unsigned char checksum; - unsigned char xmitcsum; - int count; - char ch; - - while (1) - { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar ()) != '$') - ; - -retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) - { - ch = getDebugChar (); - if (ch == '$') - goto retry; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - ch = getDebugChar (); - xmitcsum = hex (ch) << 4; - ch = getDebugChar (); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) - { - putDebugChar ('-'); /* failed checksum */ - } - else - { - putDebugChar ('+'); /* successful transfer */ - - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - return &buffer[3]; - } - - return &buffer[0]; - } - } - } -} - -/* send the packet in buffer. */ - -static void -putpacket (unsigned char *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch; - - /* $<packet info>#<checksum>. */ - do - { - putDebugChar('$'); - checksum = 0; - count = 0; - - while (ch = buffer[count]) - { - putDebugChar (ch); - checksum += ch; - count += 1; - } - - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum & 0xf]); - - } - while (getDebugChar() != '+'); -} - -/* Indicate to caller of mem2hex or hex2mem that there has been an - error. */ -static volatile int mem_err = 0; - -/* Convert the memory pointed to by mem into hex, placing result in buf. - * Return a pointer to the last char put in buf (null), in case of mem fault, - * return 0. - * If MAY_FAULT is non-zero, then we will handle memory faults by returning - * a 0, else treat a fault like any other fault in the stub. - */ - -static unsigned char * -mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault) -{ - unsigned char ch; - - set_mem_fault_trap(may_fault); - - while (count-- > 0) - { - ch = *mem++; - if (mem_err) - return 0; - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch & 0xf]; - } - - *buf = 0; - - set_mem_fault_trap(0); - - return buf; -} - -/* convert the hex array pointed to by buf into binary to be placed in mem - * return a pointer to the character AFTER the last byte written */ - -static char * -hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) -{ - int i; - unsigned char ch; - - set_mem_fault_trap(may_fault); - - for (i=0; i<count; i++) - { - ch = hex(*buf++) << 4; - ch |= hex(*buf++); - *mem++ = ch; - if (mem_err) - return 0; - } - - set_mem_fault_trap(0); - - return mem; -} - -/* This table contains the mapping between SPARC hardware trap types, and - signals, which are primarily what GDB understands. It also indicates - which hardware traps we need to commandeer when initializing the stub. */ - -static struct hard_trap_info -{ - unsigned char tt; /* Trap type code for SPARClite */ - unsigned char signo; /* Signal that we map this trap into */ -} hard_trap_info[] = { - {0x01, SIGSEGV}, /* instruction access error */ - {0x02, SIGILL}, /* privileged instruction */ - {0x03, SIGILL}, /* illegal instruction */ - {0x04, SIGEMT}, /* fp disabled */ - {0x07, SIGBUS}, /* mem address not aligned */ - {0x09, SIGSEGV}, /* data access exception */ - {0x0a, SIGEMT}, /* tag overflow */ - {0x20, SIGBUS}, /* r register access error */ - {0x21, SIGBUS}, /* instruction access error */ - {0x24, SIGEMT}, /* cp disabled */ - {0x29, SIGBUS}, /* data access error */ - {0x2a, SIGFPE}, /* divide by zero */ - {0x2b, SIGBUS}, /* data store error */ - {0x80+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */ - {0xff, SIGTRAP}, /* hardware breakpoint */ - {0, 0} /* Must be last */ -}; - -/* Set up exception handlers for tracing and breakpoints */ - -void -set_debug_traps (void) -{ - struct hard_trap_info *ht; - -/* Only setup fp traps if the FP is disabled. */ - - for (ht = hard_trap_info; - ht->tt != 0 && ht->signo != 0; - ht++) - if (ht->tt != 4 || ! (read_psr () & 0x1000)) - exceptionHandler(ht->tt, trap_low); - - initialized = 1; -} - -asm (" -! Trap handler for memory errors. This just sets mem_err to be non-zero. It -! assumes that %l1 is non-zero. This should be safe, as it is doubtful that -! 0 would ever contain code that could mem fault. This routine will skip -! past the faulting instruction after setting mem_err. - - .text - .align 4 - -_fltr_set_mem_err: - sethi %hi(_mem_err), %l0 - st %l1, [%l0 + %lo(_mem_err)] - jmpl %l2, %g0 - rett %l2+4 -"); - -static void -set_mem_fault_trap (int enable) -{ - extern void fltr_set_mem_err(); - mem_err = 0; - - if (enable) - exceptionHandler(9, fltr_set_mem_err); - else - exceptionHandler(9, trap_low); -} - -asm (" - .text - .align 4 - -_dummy_hw_breakpoint: - jmpl %l2, %g0 - rett %l2+4 - nop - nop -"); - -static void -get_in_break_mode (void) -{ - extern void dummy_hw_breakpoint(); - - exceptionHandler (255, dummy_hw_breakpoint); - - asm ("ta 255"); - - exceptionHandler (255, trap_low); -} - -/* Convert the SPARC hardware trap type code to a unix signal number. */ - -static int -computeSignal (int tt) -{ - struct hard_trap_info *ht; - - for (ht = hard_trap_info; ht->tt && ht->signo; ht++) - if (ht->tt == tt) - return ht->signo; - - return SIGHUP; /* default for things we don't know about */ -} - -/* - * While we find nice hex chars, build an int. - * Return number of chars processed. - */ - -static int -hexToInt(char **ptr, int *intValue) -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - - while (**ptr) - { - hexValue = hex(**ptr); - if (hexValue < 0) - break; - - *intValue = (*intValue << 4) | hexValue; - numChars ++; - - (*ptr)++; - } - - return (numChars); -} - -/* - * This function does all command procesing for interfacing to gdb. It - * returns 1 if you should skip the instruction at the trap address, 0 - * otherwise. - */ - -static void -handle_exception (unsigned long *registers) -{ - int tt; /* Trap type */ - int sigval; - int addr; - int length; - char *ptr; - unsigned long *sp; - unsigned long dsr; - -/* First, we must force all of the windows to be spilled out */ - - asm(" save %sp, -64, %sp - save %sp, -64, %sp - save %sp, -64, %sp - save %sp, -64, %sp - save %sp, -64, %sp - save %sp, -64, %sp - save %sp, -64, %sp - save %sp, -64, %sp - restore - restore - restore - restore - restore - restore - restore - restore -"); - - get_in_break_mode (); /* Enable DSU register writes */ - - registers[DIA1] = read_asi (1, 0xff00); - registers[DIA2] = read_asi (1, 0xff04); - registers[DDA1] = read_asi (1, 0xff08); - registers[DDA2] = read_asi (1, 0xff0c); - registers[DDV1] = read_asi (1, 0xff10); - registers[DDV2] = read_asi (1, 0xff14); - registers[DCR] = read_asi (1, 0xff18); - registers[DSR] = read_asi (1, 0xff1c); - - if (registers[PC] == (unsigned long)breakinst) - { - registers[PC] = registers[NPC]; - registers[NPC] += 4; - } - sp = (unsigned long *)registers[SP]; - - dsr = (unsigned long)registers[DSR]; - if (dsr & 0x3c) - tt = 255; - else - tt = (registers[TBR] >> 4) & 0xff; - - /* reply to host that an exception has occurred */ - sigval = computeSignal(tt); - ptr = remcomOutBuffer; - - *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[FP >> 4]; - *ptr++ = hexchars[FP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */ - *ptr++ = ';'; - - *ptr++ = hexchars[SP >> 4]; - *ptr++ = hexchars[SP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)&sp, ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[NPC >> 4]; - *ptr++ = hexchars[NPC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[NPC], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[O7 >> 4]; - *ptr++ = hexchars[O7 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[O7], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = 0; - - putpacket(remcomOutBuffer); - - while (1) - { - remcomOutBuffer[0] = 0; - - ptr = getpacket(); - switch (*ptr++) - { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval & 0xf]; - remcomOutBuffer[3] = 0; - break; - - case 'd': - /* toggle debug flag */ - break; - - case 'g': /* return the value of the CPU registers */ - memcpy (®isters[L0], sp, 16 * 4); /* Copy L & I regs from stack */ - mem2hex ((char *)registers, remcomOutBuffer, NUMREGBYTES, 0); - break; - - case 'G': /* Set the value of all registers */ - case 'P': /* Set the value of one register */ - { - unsigned long *newsp, psr; - - psr = registers[PSR]; - - if (ptr[-1] == 'P') - { - int regno; - - if (hexToInt (&ptr, ®no) - && *ptr++ == '=') - if (regno >= L0 && regno <= I7) - hex2mem (ptr, sp + regno - L0, 4, 0); - else - hex2mem (ptr, (char *)®isters[regno], 4, 0); - else - { - strcpy (remcomOutBuffer, "E01"); - break; - } - } - else - { - hex2mem (ptr, (char *)registers, NUMREGBYTES, 0); - memcpy (sp, ®isters[L0], 16 * 4); /* Copy L & I regs to stack */ - } - - /* See if the stack pointer has moved. If so, then copy the saved - locals and ins to the new location. This keeps the window - overflow and underflow routines happy. */ - - newsp = (unsigned long *)registers[SP]; - if (sp != newsp) - sp = memcpy(newsp, sp, 16 * 4); - - /* Don't allow CWP to be modified. */ - - if (psr != registers[PSR]) - registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f); - - strcpy(remcomOutBuffer,"OK"); - } - break; - - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* Try to read %x,%x. */ - - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length)) - { - if (mem2hex((char *)addr, remcomOutBuffer, length, 1)) - break; - - strcpy (remcomOutBuffer, "E03"); - } - else - strcpy(remcomOutBuffer,"E01"); - break; - - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - /* Try to read '%x,%x:'. */ - - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length) - && *ptr++ == ':') - { - if (hex2mem(ptr, (char *)addr, length, 1)) - strcpy(remcomOutBuffer, "OK"); - else - strcpy(remcomOutBuffer, "E03"); - } - else - strcpy(remcomOutBuffer, "E02"); - break; - - case 'c': /* cAA..AA Continue at address AA..AA(optional) */ - /* try to read optional parameter, pc unchanged if no parm */ - if (hexToInt(&ptr, &addr)) - { - registers[PC] = addr; - registers[NPC] = addr + 4; - } - -/* Need to flush the instruction cache here, as we may have deposited a - breakpoint, and the icache probably has no way of knowing that a data ref to - some location may have changed something that is in the instruction cache. - */ - - flush_i_cache (); - - if (!(registers[DSR] & 0x1) /* DSU enabled? */ - && !(registers[DCR] & 0x200)) /* Are we in break state? */ - { /* Yes, set the DSU regs */ - write_asi (1, 0xff00, registers[DIA1]); - write_asi (1, 0xff04, registers[DIA2]); - write_asi (1, 0xff08, registers[DDA1]); - write_asi (1, 0xff0c, registers[DDA2]); - write_asi (1, 0xff10, registers[DDV1]); - write_asi (1, 0xff14, registers[DDV2]); - write_asi (1, 0xff1c, registers[DSR]); - write_asi (1, 0xff18, registers[DCR] | 0x200); /* Clear break */ - } - - return; - - /* kill the program */ - case 'k' : /* do nothing */ - break; -#if 0 - case 't': /* Test feature */ - asm (" std %f30,[%sp]"); - break; -#endif - case 'r': /* Reset */ - asm ("call 0 - nop "); - break; - } /* switch */ - - /* reply to the request */ - putpacket(remcomOutBuffer); - } -} - -/* This function will generate a breakpoint exception. It is used at the - beginning of a program to sync up with a debugger and can be used - otherwise as a quick means to stop program execution and "break" into - the debugger. */ - -void -breakpoint (void) -{ - if (!initialized) - return; - - asm(" .globl _breakinst - - _breakinst: ta 1 - "); -} +// OBSOLETE /**************************************************************************** +// OBSOLETE +// OBSOLETE THIS SOFTWARE IS NOT COPYRIGHTED +// OBSOLETE +// OBSOLETE HP offers the following for use in the public domain. HP makes no +// OBSOLETE warranty with regard to the software or it's performance and the +// OBSOLETE user accepts the software "AS IS" with all faults. +// OBSOLETE +// OBSOLETE HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD +// OBSOLETE TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OBSOLETE OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// OBSOLETE +// OBSOLETE ****************************************************************************/ +// OBSOLETE +// OBSOLETE /**************************************************************************** +// OBSOLETE * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ +// OBSOLETE * +// OBSOLETE * Module name: remcom.c $ +// OBSOLETE * Revision: 1.34 $ +// OBSOLETE * Date: 91/03/09 12:29:49 $ +// OBSOLETE * Contributor: Lake Stevens Instrument Division$ +// OBSOLETE * +// OBSOLETE * Description: low level support for gdb debugger. $ +// OBSOLETE * +// OBSOLETE * Considerations: only works on target hardware $ +// OBSOLETE * +// OBSOLETE * Written by: Glenn Engel $ +// OBSOLETE * ModuleState: Experimental $ +// OBSOLETE * +// OBSOLETE * NOTES: See Below $ +// OBSOLETE * +// OBSOLETE * Modified for SPARC by Stu Grossman, Cygnus Support. +// OBSOLETE * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware +// OBSOLETE * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support. +// OBSOLETE * +// OBSOLETE * This code has been extensively tested on the Fujitsu SPARClite demo board. +// OBSOLETE * +// OBSOLETE * To enable debugger support, two things need to happen. One, a +// OBSOLETE * call to set_debug_traps() is necessary in order to allow any breakpoints +// OBSOLETE * or error conditions to be properly intercepted and reported to gdb. +// OBSOLETE * Two, a breakpoint needs to be generated to begin communication. This +// OBSOLETE * is most easily accomplished by a call to breakpoint(). Breakpoint() +// OBSOLETE * simulates a breakpoint by executing a trap #1. +// OBSOLETE * +// OBSOLETE ************* +// OBSOLETE * +// OBSOLETE * The following gdb commands are supported: +// OBSOLETE * +// OBSOLETE * command function Return value +// OBSOLETE * +// OBSOLETE * g return the value of the CPU registers hex data or ENN +// OBSOLETE * G set the value of the CPU registers OK or ENN +// OBSOLETE * P set the value of a single CPU register OK or ENN +// OBSOLETE * +// OBSOLETE * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN +// OBSOLETE * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN +// OBSOLETE * +// OBSOLETE * c Resume at current address SNN ( signal NN) +// OBSOLETE * cAA..AA Continue at address AA..AA SNN +// OBSOLETE * +// OBSOLETE * s Step one instruction SNN +// OBSOLETE * sAA..AA Step one instruction from AA..AA SNN +// OBSOLETE * +// OBSOLETE * k kill +// OBSOLETE * +// OBSOLETE * ? What was the last sigval ? SNN (signal NN) +// OBSOLETE * +// OBSOLETE * All commands and responses are sent with a packet which includes a +// OBSOLETE * checksum. A packet consists of +// OBSOLETE * +// OBSOLETE * $<packet info>#<checksum>. +// OBSOLETE * +// OBSOLETE * where +// OBSOLETE * <packet info> :: <characters representing the command or response> +// OBSOLETE * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>> +// OBSOLETE * +// OBSOLETE * When a packet is received, it is first acknowledged with either '+' or '-'. +// OBSOLETE * '+' indicates a successful transfer. '-' indicates a failed transfer. +// OBSOLETE * +// OBSOLETE * Example: +// OBSOLETE * +// OBSOLETE * Host: Reply: +// OBSOLETE * $m0,10#2a +$00010203040506070809101112131415#42 +// OBSOLETE * +// OBSOLETE ****************************************************************************/ +// OBSOLETE +// OBSOLETE #include <string.h> +// OBSOLETE #include <signal.h> +// OBSOLETE #include <sparclite.h> +// OBSOLETE +// OBSOLETE /************************************************************************ +// OBSOLETE * +// OBSOLETE * external low-level support routines +// OBSOLETE */ +// OBSOLETE +// OBSOLETE extern void putDebugChar (int c); /* write a single character */ +// OBSOLETE extern int getDebugChar (void); /* read and return a single char */ +// OBSOLETE +// OBSOLETE /************************************************************************/ +// OBSOLETE /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ +// OBSOLETE /* at least NUMREGBYTES*2 are needed for register packets */ +// OBSOLETE #define BUFMAX 2048 +// OBSOLETE +// OBSOLETE static int initialized = 0; /* !0 means we've been initialized */ +// OBSOLETE +// OBSOLETE extern void breakinst (); +// OBSOLETE static void set_mem_fault_trap (int enable); +// OBSOLETE static void get_in_break_mode (void); +// OBSOLETE +// OBSOLETE static const char hexchars[]="0123456789abcdef"; +// OBSOLETE +// OBSOLETE #define NUMREGS 80 +// OBSOLETE +// OBSOLETE /* Number of bytes of registers. */ +// OBSOLETE #define NUMREGBYTES (NUMREGS * 4) +// OBSOLETE enum regnames {G0, G1, G2, G3, G4, G5, G6, G7, +// OBSOLETE O0, O1, O2, O3, O4, O5, SP, O7, +// OBSOLETE L0, L1, L2, L3, L4, L5, L6, L7, +// OBSOLETE I0, I1, I2, I3, I4, I5, FP, I7, +// OBSOLETE +// OBSOLETE F0, F1, F2, F3, F4, F5, F6, F7, +// OBSOLETE F8, F9, F10, F11, F12, F13, F14, F15, +// OBSOLETE F16, F17, F18, F19, F20, F21, F22, F23, +// OBSOLETE F24, F25, F26, F27, F28, F29, F30, F31, +// OBSOLETE Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR, +// OBSOLETE DIA1, DIA2, DDA1, DDA2, DDV1, DDV2, DCR, DSR }; +// OBSOLETE +// OBSOLETE /*************************** ASSEMBLY CODE MACROS *************************/ +// OBSOLETE /* */ +// OBSOLETE +// OBSOLETE extern void trap_low(); +// OBSOLETE +// OBSOLETE /* Create private copies of common functions used by the stub. This prevents +// OBSOLETE nasty interactions between app code and the stub (for instance if user steps +// OBSOLETE into strlen, etc..) */ +// OBSOLETE +// OBSOLETE static char * +// OBSOLETE strcpy (char *dst, const char *src) +// OBSOLETE { +// OBSOLETE char *retval = dst; +// OBSOLETE +// OBSOLETE while ((*dst++ = *src++) != '\000'); +// OBSOLETE +// OBSOLETE return retval; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void * +// OBSOLETE memcpy (void *vdst, const void *vsrc, int n) +// OBSOLETE { +// OBSOLETE char *dst = vdst; +// OBSOLETE const char *src = vsrc; +// OBSOLETE char *retval = dst; +// OBSOLETE +// OBSOLETE while (n-- > 0) +// OBSOLETE *dst++ = *src++; +// OBSOLETE +// OBSOLETE return retval; +// OBSOLETE } +// OBSOLETE +// OBSOLETE asm(" +// OBSOLETE .reserve trapstack, 1000 * 4, \"bss\", 8 +// OBSOLETE +// OBSOLETE .data +// OBSOLETE .align 4 +// OBSOLETE +// OBSOLETE in_trap_handler: +// OBSOLETE .word 0 +// OBSOLETE +// OBSOLETE .text +// OBSOLETE .align 4 +// OBSOLETE +// OBSOLETE ! This function is called when any SPARC trap (except window overflow or +// OBSOLETE ! underflow) occurs. It makes sure that the invalid register window is still +// OBSOLETE ! available before jumping into C code. It will also restore the world if you +// OBSOLETE ! return from handle_exception. +// OBSOLETE ! +// OBSOLETE ! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly. +// OBSOLETE ! Register usage throughout the routine is as follows: +// OBSOLETE ! +// OBSOLETE ! l0 - psr +// OBSOLETE ! l1 - pc +// OBSOLETE ! l2 - npc +// OBSOLETE ! l3 - wim +// OBSOLETE ! l4 - scratch and y reg +// OBSOLETE ! l5 - scratch and tbr +// OBSOLETE ! l6 - unused +// OBSOLETE ! l7 - unused +// OBSOLETE +// OBSOLETE .globl _trap_low +// OBSOLETE _trap_low: +// OBSOLETE mov %psr, %l0 +// OBSOLETE mov %wim, %l3 +// OBSOLETE +// OBSOLETE srl %l3, %l0, %l4 ! wim >> cwp +// OBSOLETE cmp %l4, 1 +// OBSOLETE bne window_fine ! Branch if not in the invalid window +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! Handle window overflow +// OBSOLETE +// OBSOLETE mov %g1, %l4 ! Save g1, we use it to hold the wim +// OBSOLETE srl %l3, 1, %g1 ! Rotate wim right +// OBSOLETE tst %g1 +// OBSOLETE bg good_wim ! Branch if new wim is non-zero +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! At this point, we need to bring a 1 into the high order bit of the wim. +// OBSOLETE ! Since we don't want to make any assumptions about the number of register +// OBSOLETE ! windows, we figure it out dynamically so as to setup the wim correctly. +// OBSOLETE +// OBSOLETE not %g1 ! Fill g1 with ones +// OBSOLETE mov %g1, %wim ! Fill the wim with ones +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE mov %wim, %g1 ! Read back the wim +// OBSOLETE inc %g1 ! Now g1 has 1 just to left of wim +// OBSOLETE srl %g1, 1, %g1 ! Now put 1 at top of wim +// OBSOLETE mov %g0, %wim ! Clear wim so that subsequent save +// OBSOLETE nop ! won't trap +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE +// OBSOLETE good_wim: +// OBSOLETE save %g0, %g0, %g0 ! Slip into next window +// OBSOLETE mov %g1, %wim ! Install the new wim +// OBSOLETE +// OBSOLETE std %l0, [%sp + 0 * 4] ! save L & I registers +// OBSOLETE std %l2, [%sp + 2 * 4] +// OBSOLETE std %l4, [%sp + 4 * 4] +// OBSOLETE std %l6, [%sp + 6 * 4] +// OBSOLETE +// OBSOLETE std %i0, [%sp + 8 * 4] +// OBSOLETE std %i2, [%sp + 10 * 4] +// OBSOLETE std %i4, [%sp + 12 * 4] +// OBSOLETE std %i6, [%sp + 14 * 4] +// OBSOLETE +// OBSOLETE restore ! Go back to trap window. +// OBSOLETE mov %l4, %g1 ! Restore %g1 +// OBSOLETE +// OBSOLETE window_fine: +// OBSOLETE sethi %hi(in_trap_handler), %l4 +// OBSOLETE ld [%lo(in_trap_handler) + %l4], %l5 +// OBSOLETE tst %l5 +// OBSOLETE bg recursive_trap +// OBSOLETE inc %l5 +// OBSOLETE +// OBSOLETE set trapstack+1000*4, %sp ! Switch to trap stack +// OBSOLETE +// OBSOLETE recursive_trap: +// OBSOLETE st %l5, [%lo(in_trap_handler) + %l4] +// OBSOLETE sub %sp,(16+1+6+1+80)*4,%sp ! Make room for input & locals +// OBSOLETE ! + hidden arg + arg spill +// OBSOLETE ! + doubleword alignment +// OBSOLETE ! + registers[72] local var +// OBSOLETE +// OBSOLETE std %g0, [%sp + (24 + 0) * 4] ! registers[Gx] +// OBSOLETE std %g2, [%sp + (24 + 2) * 4] +// OBSOLETE std %g4, [%sp + (24 + 4) * 4] +// OBSOLETE std %g6, [%sp + (24 + 6) * 4] +// OBSOLETE +// OBSOLETE std %i0, [%sp + (24 + 8) * 4] ! registers[Ox] +// OBSOLETE std %i2, [%sp + (24 + 10) * 4] +// OBSOLETE std %i4, [%sp + (24 + 12) * 4] +// OBSOLETE std %i6, [%sp + (24 + 14) * 4] +// OBSOLETE +// OBSOLETE mov %y, %l4 +// OBSOLETE mov %tbr, %l5 +// OBSOLETE st %l4, [%sp + (24 + 64) * 4] ! Y +// OBSOLETE st %l0, [%sp + (24 + 65) * 4] ! PSR +// OBSOLETE st %l3, [%sp + (24 + 66) * 4] ! WIM +// OBSOLETE st %l5, [%sp + (24 + 67) * 4] ! TBR +// OBSOLETE st %l1, [%sp + (24 + 68) * 4] ! PC +// OBSOLETE st %l2, [%sp + (24 + 69) * 4] ! NPC +// OBSOLETE +// OBSOLETE or %l0, 0xf20, %l4 +// OBSOLETE mov %l4, %psr ! Turn on traps, disable interrupts +// OBSOLETE +// OBSOLETE set 0x1000, %l1 +// OBSOLETE btst %l1, %l0 ! FP enabled? +// OBSOLETE be no_fpstore +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! Must save fsr first, to flush the FQ. This may cause a deferred fp trap, so +// OBSOLETE ! traps must be enabled to allow the trap handler to clean things up. +// OBSOLETE +// OBSOLETE st %fsr, [%sp + (24 + 70) * 4] +// OBSOLETE +// OBSOLETE std %f0, [%sp + (24 + 32) * 4] +// OBSOLETE std %f2, [%sp + (24 + 34) * 4] +// OBSOLETE std %f4, [%sp + (24 + 36) * 4] +// OBSOLETE std %f6, [%sp + (24 + 38) * 4] +// OBSOLETE std %f8, [%sp + (24 + 40) * 4] +// OBSOLETE std %f10, [%sp + (24 + 42) * 4] +// OBSOLETE std %f12, [%sp + (24 + 44) * 4] +// OBSOLETE std %f14, [%sp + (24 + 46) * 4] +// OBSOLETE std %f16, [%sp + (24 + 48) * 4] +// OBSOLETE std %f18, [%sp + (24 + 50) * 4] +// OBSOLETE std %f20, [%sp + (24 + 52) * 4] +// OBSOLETE std %f22, [%sp + (24 + 54) * 4] +// OBSOLETE std %f24, [%sp + (24 + 56) * 4] +// OBSOLETE std %f26, [%sp + (24 + 58) * 4] +// OBSOLETE std %f28, [%sp + (24 + 60) * 4] +// OBSOLETE std %f30, [%sp + (24 + 62) * 4] +// OBSOLETE no_fpstore: +// OBSOLETE +// OBSOLETE call _handle_exception +// OBSOLETE add %sp, 24 * 4, %o0 ! Pass address of registers +// OBSOLETE +// OBSOLETE ! Reload all of the registers that aren't on the stack +// OBSOLETE +// OBSOLETE ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx] +// OBSOLETE ldd [%sp + (24 + 2) * 4], %g2 +// OBSOLETE ldd [%sp + (24 + 4) * 4], %g4 +// OBSOLETE ldd [%sp + (24 + 6) * 4], %g6 +// OBSOLETE +// OBSOLETE ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox] +// OBSOLETE ldd [%sp + (24 + 10) * 4], %i2 +// OBSOLETE ldd [%sp + (24 + 12) * 4], %i4 +// OBSOLETE ldd [%sp + (24 + 14) * 4], %i6 +// OBSOLETE +// OBSOLETE +// OBSOLETE ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR +// OBSOLETE ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC +// OBSOLETE +// OBSOLETE set 0x1000, %l5 +// OBSOLETE btst %l5, %l1 ! FP enabled? +// OBSOLETE be no_fpreload +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ldd [%sp + (24 + 32) * 4], %f0 +// OBSOLETE ldd [%sp + (24 + 34) * 4], %f2 +// OBSOLETE ldd [%sp + (24 + 36) * 4], %f4 +// OBSOLETE ldd [%sp + (24 + 38) * 4], %f6 +// OBSOLETE ldd [%sp + (24 + 40) * 4], %f8 +// OBSOLETE ldd [%sp + (24 + 42) * 4], %f10 +// OBSOLETE ldd [%sp + (24 + 44) * 4], %f12 +// OBSOLETE ldd [%sp + (24 + 46) * 4], %f14 +// OBSOLETE ldd [%sp + (24 + 48) * 4], %f16 +// OBSOLETE ldd [%sp + (24 + 50) * 4], %f18 +// OBSOLETE ldd [%sp + (24 + 52) * 4], %f20 +// OBSOLETE ldd [%sp + (24 + 54) * 4], %f22 +// OBSOLETE ldd [%sp + (24 + 56) * 4], %f24 +// OBSOLETE ldd [%sp + (24 + 58) * 4], %f26 +// OBSOLETE ldd [%sp + (24 + 60) * 4], %f28 +// OBSOLETE ldd [%sp + (24 + 62) * 4], %f30 +// OBSOLETE +// OBSOLETE ld [%sp + (24 + 70) * 4], %fsr +// OBSOLETE no_fpreload: +// OBSOLETE +// OBSOLETE restore ! Ensure that previous window is valid +// OBSOLETE save %g0, %g0, %g0 ! by causing a window_underflow trap +// OBSOLETE +// OBSOLETE mov %l0, %y +// OBSOLETE mov %l1, %psr ! Make sure that traps are disabled +// OBSOLETE ! for rett +// OBSOLETE sethi %hi(in_trap_handler), %l4 +// OBSOLETE ld [%lo(in_trap_handler) + %l4], %l5 +// OBSOLETE dec %l5 +// OBSOLETE st %l5, [%lo(in_trap_handler) + %l4] +// OBSOLETE +// OBSOLETE jmpl %l2, %g0 ! Restore old PC +// OBSOLETE rett %l3 ! Restore old nPC +// OBSOLETE "); +// OBSOLETE +// OBSOLETE /* Convert ch from a hex digit to an int */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE hex (unsigned char ch) +// OBSOLETE { +// OBSOLETE if (ch >= 'a' && ch <= 'f') +// OBSOLETE return ch-'a'+10; +// OBSOLETE if (ch >= '0' && ch <= '9') +// OBSOLETE return ch-'0'; +// OBSOLETE if (ch >= 'A' && ch <= 'F') +// OBSOLETE return ch-'A'+10; +// OBSOLETE return -1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static char remcomInBuffer[BUFMAX]; +// OBSOLETE static char remcomOutBuffer[BUFMAX]; +// OBSOLETE +// OBSOLETE /* scan for the sequence $<data>#<checksum> */ +// OBSOLETE +// OBSOLETE unsigned char * +// OBSOLETE getpacket (void) +// OBSOLETE { +// OBSOLETE unsigned char *buffer = &remcomInBuffer[0]; +// OBSOLETE unsigned char checksum; +// OBSOLETE unsigned char xmitcsum; +// OBSOLETE int count; +// OBSOLETE char ch; +// OBSOLETE +// OBSOLETE while (1) +// OBSOLETE { +// OBSOLETE /* wait around for the start character, ignore all other characters */ +// OBSOLETE while ((ch = getDebugChar ()) != '$') +// OBSOLETE ; +// OBSOLETE +// OBSOLETE retry: +// OBSOLETE checksum = 0; +// OBSOLETE xmitcsum = -1; +// OBSOLETE count = 0; +// OBSOLETE +// OBSOLETE /* now, read until a # or end of buffer is found */ +// OBSOLETE while (count < BUFMAX) +// OBSOLETE { +// OBSOLETE ch = getDebugChar (); +// OBSOLETE if (ch == '$') +// OBSOLETE goto retry; +// OBSOLETE if (ch == '#') +// OBSOLETE break; +// OBSOLETE checksum = checksum + ch; +// OBSOLETE buffer[count] = ch; +// OBSOLETE count = count + 1; +// OBSOLETE } +// OBSOLETE buffer[count] = 0; +// OBSOLETE +// OBSOLETE if (ch == '#') +// OBSOLETE { +// OBSOLETE ch = getDebugChar (); +// OBSOLETE xmitcsum = hex (ch) << 4; +// OBSOLETE ch = getDebugChar (); +// OBSOLETE xmitcsum += hex (ch); +// OBSOLETE +// OBSOLETE if (checksum != xmitcsum) +// OBSOLETE { +// OBSOLETE putDebugChar ('-'); /* failed checksum */ +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE putDebugChar ('+'); /* successful transfer */ +// OBSOLETE +// OBSOLETE /* if a sequence char is present, reply the sequence ID */ +// OBSOLETE if (buffer[2] == ':') +// OBSOLETE { +// OBSOLETE putDebugChar (buffer[0]); +// OBSOLETE putDebugChar (buffer[1]); +// OBSOLETE +// OBSOLETE return &buffer[3]; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return &buffer[0]; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* send the packet in buffer. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE putpacket (unsigned char *buffer) +// OBSOLETE { +// OBSOLETE unsigned char checksum; +// OBSOLETE int count; +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE /* $<packet info>#<checksum>. */ +// OBSOLETE do +// OBSOLETE { +// OBSOLETE putDebugChar('$'); +// OBSOLETE checksum = 0; +// OBSOLETE count = 0; +// OBSOLETE +// OBSOLETE while (ch = buffer[count]) +// OBSOLETE { +// OBSOLETE putDebugChar (ch); +// OBSOLETE checksum += ch; +// OBSOLETE count += 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE putDebugChar('#'); +// OBSOLETE putDebugChar(hexchars[checksum >> 4]); +// OBSOLETE putDebugChar(hexchars[checksum & 0xf]); +// OBSOLETE +// OBSOLETE } +// OBSOLETE while (getDebugChar() != '+'); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Indicate to caller of mem2hex or hex2mem that there has been an +// OBSOLETE error. */ +// OBSOLETE static volatile int mem_err = 0; +// OBSOLETE +// OBSOLETE /* Convert the memory pointed to by mem into hex, placing result in buf. +// OBSOLETE * Return a pointer to the last char put in buf (null), in case of mem fault, +// OBSOLETE * return 0. +// OBSOLETE * If MAY_FAULT is non-zero, then we will handle memory faults by returning +// OBSOLETE * a 0, else treat a fault like any other fault in the stub. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static unsigned char * +// OBSOLETE mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault) +// OBSOLETE { +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE set_mem_fault_trap(may_fault); +// OBSOLETE +// OBSOLETE while (count-- > 0) +// OBSOLETE { +// OBSOLETE ch = *mem++; +// OBSOLETE if (mem_err) +// OBSOLETE return 0; +// OBSOLETE *buf++ = hexchars[ch >> 4]; +// OBSOLETE *buf++ = hexchars[ch & 0xf]; +// OBSOLETE } +// OBSOLETE +// OBSOLETE *buf = 0; +// OBSOLETE +// OBSOLETE set_mem_fault_trap(0); +// OBSOLETE +// OBSOLETE return buf; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* convert the hex array pointed to by buf into binary to be placed in mem +// OBSOLETE * return a pointer to the character AFTER the last byte written */ +// OBSOLETE +// OBSOLETE static char * +// OBSOLETE hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE set_mem_fault_trap(may_fault); +// OBSOLETE +// OBSOLETE for (i=0; i<count; i++) +// OBSOLETE { +// OBSOLETE ch = hex(*buf++) << 4; +// OBSOLETE ch |= hex(*buf++); +// OBSOLETE *mem++ = ch; +// OBSOLETE if (mem_err) +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE set_mem_fault_trap(0); +// OBSOLETE +// OBSOLETE return mem; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* This table contains the mapping between SPARC hardware trap types, and +// OBSOLETE signals, which are primarily what GDB understands. It also indicates +// OBSOLETE which hardware traps we need to commandeer when initializing the stub. */ +// OBSOLETE +// OBSOLETE static struct hard_trap_info +// OBSOLETE { +// OBSOLETE unsigned char tt; /* Trap type code for SPARClite */ +// OBSOLETE unsigned char signo; /* Signal that we map this trap into */ +// OBSOLETE } hard_trap_info[] = { +// OBSOLETE {0x01, SIGSEGV}, /* instruction access error */ +// OBSOLETE {0x02, SIGILL}, /* privileged instruction */ +// OBSOLETE {0x03, SIGILL}, /* illegal instruction */ +// OBSOLETE {0x04, SIGEMT}, /* fp disabled */ +// OBSOLETE {0x07, SIGBUS}, /* mem address not aligned */ +// OBSOLETE {0x09, SIGSEGV}, /* data access exception */ +// OBSOLETE {0x0a, SIGEMT}, /* tag overflow */ +// OBSOLETE {0x20, SIGBUS}, /* r register access error */ +// OBSOLETE {0x21, SIGBUS}, /* instruction access error */ +// OBSOLETE {0x24, SIGEMT}, /* cp disabled */ +// OBSOLETE {0x29, SIGBUS}, /* data access error */ +// OBSOLETE {0x2a, SIGFPE}, /* divide by zero */ +// OBSOLETE {0x2b, SIGBUS}, /* data store error */ +// OBSOLETE {0x80+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */ +// OBSOLETE {0xff, SIGTRAP}, /* hardware breakpoint */ +// OBSOLETE {0, 0} /* Must be last */ +// OBSOLETE }; +// OBSOLETE +// OBSOLETE /* Set up exception handlers for tracing and breakpoints */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE set_debug_traps (void) +// OBSOLETE { +// OBSOLETE struct hard_trap_info *ht; +// OBSOLETE +// OBSOLETE /* Only setup fp traps if the FP is disabled. */ +// OBSOLETE +// OBSOLETE for (ht = hard_trap_info; +// OBSOLETE ht->tt != 0 && ht->signo != 0; +// OBSOLETE ht++) +// OBSOLETE if (ht->tt != 4 || ! (read_psr () & 0x1000)) +// OBSOLETE exceptionHandler(ht->tt, trap_low); +// OBSOLETE +// OBSOLETE initialized = 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE ! Trap handler for memory errors. This just sets mem_err to be non-zero. It +// OBSOLETE ! assumes that %l1 is non-zero. This should be safe, as it is doubtful that +// OBSOLETE ! 0 would ever contain code that could mem fault. This routine will skip +// OBSOLETE ! past the faulting instruction after setting mem_err. +// OBSOLETE +// OBSOLETE .text +// OBSOLETE .align 4 +// OBSOLETE +// OBSOLETE _fltr_set_mem_err: +// OBSOLETE sethi %hi(_mem_err), %l0 +// OBSOLETE st %l1, [%l0 + %lo(_mem_err)] +// OBSOLETE jmpl %l2, %g0 +// OBSOLETE rett %l2+4 +// OBSOLETE "); +// OBSOLETE +// OBSOLETE static void +// OBSOLETE set_mem_fault_trap (int enable) +// OBSOLETE { +// OBSOLETE extern void fltr_set_mem_err(); +// OBSOLETE mem_err = 0; +// OBSOLETE +// OBSOLETE if (enable) +// OBSOLETE exceptionHandler(9, fltr_set_mem_err); +// OBSOLETE else +// OBSOLETE exceptionHandler(9, trap_low); +// OBSOLETE } +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE .text +// OBSOLETE .align 4 +// OBSOLETE +// OBSOLETE _dummy_hw_breakpoint: +// OBSOLETE jmpl %l2, %g0 +// OBSOLETE rett %l2+4 +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE "); +// OBSOLETE +// OBSOLETE static void +// OBSOLETE get_in_break_mode (void) +// OBSOLETE { +// OBSOLETE extern void dummy_hw_breakpoint(); +// OBSOLETE +// OBSOLETE exceptionHandler (255, dummy_hw_breakpoint); +// OBSOLETE +// OBSOLETE asm ("ta 255"); +// OBSOLETE +// OBSOLETE exceptionHandler (255, trap_low); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Convert the SPARC hardware trap type code to a unix signal number. */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE computeSignal (int tt) +// OBSOLETE { +// OBSOLETE struct hard_trap_info *ht; +// OBSOLETE +// OBSOLETE for (ht = hard_trap_info; ht->tt && ht->signo; ht++) +// OBSOLETE if (ht->tt == tt) +// OBSOLETE return ht->signo; +// OBSOLETE +// OBSOLETE return SIGHUP; /* default for things we don't know about */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * While we find nice hex chars, build an int. +// OBSOLETE * Return number of chars processed. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE hexToInt(char **ptr, int *intValue) +// OBSOLETE { +// OBSOLETE int numChars = 0; +// OBSOLETE int hexValue; +// OBSOLETE +// OBSOLETE *intValue = 0; +// OBSOLETE +// OBSOLETE while (**ptr) +// OBSOLETE { +// OBSOLETE hexValue = hex(**ptr); +// OBSOLETE if (hexValue < 0) +// OBSOLETE break; +// OBSOLETE +// OBSOLETE *intValue = (*intValue << 4) | hexValue; +// OBSOLETE numChars ++; +// OBSOLETE +// OBSOLETE (*ptr)++; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return (numChars); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * This function does all command procesing for interfacing to gdb. It +// OBSOLETE * returns 1 if you should skip the instruction at the trap address, 0 +// OBSOLETE * otherwise. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE handle_exception (unsigned long *registers) +// OBSOLETE { +// OBSOLETE int tt; /* Trap type */ +// OBSOLETE int sigval; +// OBSOLETE int addr; +// OBSOLETE int length; +// OBSOLETE char *ptr; +// OBSOLETE unsigned long *sp; +// OBSOLETE unsigned long dsr; +// OBSOLETE +// OBSOLETE /* First, we must force all of the windows to be spilled out */ +// OBSOLETE +// OBSOLETE asm(" save %sp, -64, %sp +// OBSOLETE save %sp, -64, %sp +// OBSOLETE save %sp, -64, %sp +// OBSOLETE save %sp, -64, %sp +// OBSOLETE save %sp, -64, %sp +// OBSOLETE save %sp, -64, %sp +// OBSOLETE save %sp, -64, %sp +// OBSOLETE save %sp, -64, %sp +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE "); +// OBSOLETE +// OBSOLETE get_in_break_mode (); /* Enable DSU register writes */ +// OBSOLETE +// OBSOLETE registers[DIA1] = read_asi (1, 0xff00); +// OBSOLETE registers[DIA2] = read_asi (1, 0xff04); +// OBSOLETE registers[DDA1] = read_asi (1, 0xff08); +// OBSOLETE registers[DDA2] = read_asi (1, 0xff0c); +// OBSOLETE registers[DDV1] = read_asi (1, 0xff10); +// OBSOLETE registers[DDV2] = read_asi (1, 0xff14); +// OBSOLETE registers[DCR] = read_asi (1, 0xff18); +// OBSOLETE registers[DSR] = read_asi (1, 0xff1c); +// OBSOLETE +// OBSOLETE if (registers[PC] == (unsigned long)breakinst) +// OBSOLETE { +// OBSOLETE registers[PC] = registers[NPC]; +// OBSOLETE registers[NPC] += 4; +// OBSOLETE } +// OBSOLETE sp = (unsigned long *)registers[SP]; +// OBSOLETE +// OBSOLETE dsr = (unsigned long)registers[DSR]; +// OBSOLETE if (dsr & 0x3c) +// OBSOLETE tt = 255; +// OBSOLETE else +// OBSOLETE tt = (registers[TBR] >> 4) & 0xff; +// OBSOLETE +// OBSOLETE /* reply to host that an exception has occurred */ +// OBSOLETE sigval = computeSignal(tt); +// OBSOLETE ptr = remcomOutBuffer; +// OBSOLETE +// OBSOLETE *ptr++ = 'T'; +// OBSOLETE *ptr++ = hexchars[sigval >> 4]; +// OBSOLETE *ptr++ = hexchars[sigval & 0xf]; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[PC >> 4]; +// OBSOLETE *ptr++ = hexchars[PC & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[FP >> 4]; +// OBSOLETE *ptr++ = hexchars[FP & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */ +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[SP >> 4]; +// OBSOLETE *ptr++ = hexchars[SP & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((char *)&sp, ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[NPC >> 4]; +// OBSOLETE *ptr++ = hexchars[NPC & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((char *)®isters[NPC], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[O7 >> 4]; +// OBSOLETE *ptr++ = hexchars[O7 & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((char *)®isters[O7], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = 0; +// OBSOLETE +// OBSOLETE putpacket(remcomOutBuffer); +// OBSOLETE +// OBSOLETE while (1) +// OBSOLETE { +// OBSOLETE remcomOutBuffer[0] = 0; +// OBSOLETE +// OBSOLETE ptr = getpacket(); +// OBSOLETE switch (*ptr++) +// OBSOLETE { +// OBSOLETE case '?': +// OBSOLETE remcomOutBuffer[0] = 'S'; +// OBSOLETE remcomOutBuffer[1] = hexchars[sigval >> 4]; +// OBSOLETE remcomOutBuffer[2] = hexchars[sigval & 0xf]; +// OBSOLETE remcomOutBuffer[3] = 0; +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'd': +// OBSOLETE /* toggle debug flag */ +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'g': /* return the value of the CPU registers */ +// OBSOLETE memcpy (®isters[L0], sp, 16 * 4); /* Copy L & I regs from stack */ +// OBSOLETE mem2hex ((char *)registers, remcomOutBuffer, NUMREGBYTES, 0); +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'G': /* Set the value of all registers */ +// OBSOLETE case 'P': /* Set the value of one register */ +// OBSOLETE { +// OBSOLETE unsigned long *newsp, psr; +// OBSOLETE +// OBSOLETE psr = registers[PSR]; +// OBSOLETE +// OBSOLETE if (ptr[-1] == 'P') +// OBSOLETE { +// OBSOLETE int regno; +// OBSOLETE +// OBSOLETE if (hexToInt (&ptr, ®no) +// OBSOLETE && *ptr++ == '=') +// OBSOLETE if (regno >= L0 && regno <= I7) +// OBSOLETE hex2mem (ptr, sp + regno - L0, 4, 0); +// OBSOLETE else +// OBSOLETE hex2mem (ptr, (char *)®isters[regno], 4, 0); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE strcpy (remcomOutBuffer, "E01"); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE hex2mem (ptr, (char *)registers, NUMREGBYTES, 0); +// OBSOLETE memcpy (sp, ®isters[L0], 16 * 4); /* Copy L & I regs to stack */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* See if the stack pointer has moved. If so, then copy the saved +// OBSOLETE locals and ins to the new location. This keeps the window +// OBSOLETE overflow and underflow routines happy. */ +// OBSOLETE +// OBSOLETE newsp = (unsigned long *)registers[SP]; +// OBSOLETE if (sp != newsp) +// OBSOLETE sp = memcpy(newsp, sp, 16 * 4); +// OBSOLETE +// OBSOLETE /* Don't allow CWP to be modified. */ +// OBSOLETE +// OBSOLETE if (psr != registers[PSR]) +// OBSOLETE registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f); +// OBSOLETE +// OBSOLETE strcpy(remcomOutBuffer,"OK"); +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ +// OBSOLETE /* Try to read %x,%x. */ +// OBSOLETE +// OBSOLETE if (hexToInt(&ptr, &addr) +// OBSOLETE && *ptr++ == ',' +// OBSOLETE && hexToInt(&ptr, &length)) +// OBSOLETE { +// OBSOLETE if (mem2hex((char *)addr, remcomOutBuffer, length, 1)) +// OBSOLETE break; +// OBSOLETE +// OBSOLETE strcpy (remcomOutBuffer, "E03"); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE strcpy(remcomOutBuffer,"E01"); +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ +// OBSOLETE /* Try to read '%x,%x:'. */ +// OBSOLETE +// OBSOLETE if (hexToInt(&ptr, &addr) +// OBSOLETE && *ptr++ == ',' +// OBSOLETE && hexToInt(&ptr, &length) +// OBSOLETE && *ptr++ == ':') +// OBSOLETE { +// OBSOLETE if (hex2mem(ptr, (char *)addr, length, 1)) +// OBSOLETE strcpy(remcomOutBuffer, "OK"); +// OBSOLETE else +// OBSOLETE strcpy(remcomOutBuffer, "E03"); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE strcpy(remcomOutBuffer, "E02"); +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'c': /* cAA..AA Continue at address AA..AA(optional) */ +// OBSOLETE /* try to read optional parameter, pc unchanged if no parm */ +// OBSOLETE if (hexToInt(&ptr, &addr)) +// OBSOLETE { +// OBSOLETE registers[PC] = addr; +// OBSOLETE registers[NPC] = addr + 4; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Need to flush the instruction cache here, as we may have deposited a +// OBSOLETE breakpoint, and the icache probably has no way of knowing that a data ref to +// OBSOLETE some location may have changed something that is in the instruction cache. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE flush_i_cache (); +// OBSOLETE +// OBSOLETE if (!(registers[DSR] & 0x1) /* DSU enabled? */ +// OBSOLETE && !(registers[DCR] & 0x200)) /* Are we in break state? */ +// OBSOLETE { /* Yes, set the DSU regs */ +// OBSOLETE write_asi (1, 0xff00, registers[DIA1]); +// OBSOLETE write_asi (1, 0xff04, registers[DIA2]); +// OBSOLETE write_asi (1, 0xff08, registers[DDA1]); +// OBSOLETE write_asi (1, 0xff0c, registers[DDA2]); +// OBSOLETE write_asi (1, 0xff10, registers[DDV1]); +// OBSOLETE write_asi (1, 0xff14, registers[DDV2]); +// OBSOLETE write_asi (1, 0xff1c, registers[DSR]); +// OBSOLETE write_asi (1, 0xff18, registers[DCR] | 0x200); /* Clear break */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE return; +// OBSOLETE +// OBSOLETE /* kill the program */ +// OBSOLETE case 'k' : /* do nothing */ +// OBSOLETE break; +// OBSOLETE #if 0 +// OBSOLETE case 't': /* Test feature */ +// OBSOLETE asm (" std %f30,[%sp]"); +// OBSOLETE break; +// OBSOLETE #endif +// OBSOLETE case 'r': /* Reset */ +// OBSOLETE asm ("call 0 +// OBSOLETE nop "); +// OBSOLETE break; +// OBSOLETE } /* switch */ +// OBSOLETE +// OBSOLETE /* reply to the request */ +// OBSOLETE putpacket(remcomOutBuffer); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* This function will generate a breakpoint exception. It is used at the +// OBSOLETE beginning of a program to sync up with a debugger and can be used +// OBSOLETE otherwise as a quick means to stop program execution and "break" into +// OBSOLETE the debugger. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE breakpoint (void) +// OBSOLETE { +// OBSOLETE if (!initialized) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE asm(" .globl _breakinst +// OBSOLETE +// OBSOLETE _breakinst: ta 1 +// OBSOLETE "); +// OBSOLETE } diff --git a/gdb/sparcl-tdep.c b/gdb/sparcl-tdep.c index aa06747..8c376c5 100644 --- a/gdb/sparcl-tdep.c +++ b/gdb/sparcl-tdep.c @@ -1,869 +1,869 @@ -/* Target dependent code for the Fujitsu SPARClite for GDB, the GNU debugger. - Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001 - 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "gdbcore.h" -#include "breakpoint.h" -#include "target.h" -#include "serial.h" -#include "regcache.h" -#include <sys/types.h> - -#if (!defined(__GO32__) && !defined(_WIN32)) || defined(__CYGWIN__) -#define HAVE_SOCKETS -#include <sys/time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> -#endif - -static struct target_ops sparclite_ops; - -static char *remote_target_name = NULL; -static struct serial *remote_desc = NULL; -static int serial_flag; -#ifdef HAVE_SOCKETS -static int udp_fd = -1; -#endif - -static struct serial *open_tty (char *name); -static int send_resp (struct serial *desc, char c); -static void close_tty (void * ignore); -#ifdef HAVE_SOCKETS -static int recv_udp_buf (int fd, unsigned char *buf, int len, int timeout); -static int send_udp_buf (int fd, unsigned char *buf, int len); -#endif -static void sparclite_open (char *name, int from_tty); -static void sparclite_close (int quitting); -static void download (char *target_name, char *args, int from_tty, - void (*write_routine) (bfd * from_bfd, - asection * from_sec, - file_ptr from_addr, - bfd_vma to_addr, int len), - void (*start_routine) (bfd_vma entry)); -static void sparclite_serial_start (bfd_vma entry); -static void sparclite_serial_write (bfd * from_bfd, asection * from_sec, - file_ptr from_addr, - bfd_vma to_addr, int len); -#ifdef HAVE_SOCKETS -static unsigned short calc_checksum (unsigned char *buffer, int count); -static void sparclite_udp_start (bfd_vma entry); -static void sparclite_udp_write (bfd * from_bfd, asection * from_sec, - file_ptr from_addr, bfd_vma to_addr, - int len); -#endif -static void sparclite_download (char *filename, int from_tty); - -#define DDA2_SUP_ASI 0xb000000 -#define DDA1_SUP_ASI 0xb0000 - -#define DDA2_ASI_MASK 0xff000000 -#define DDA1_ASI_MASK 0xff0000 -#define DIA2_SUP_MODE 0x8000 -#define DIA1_SUP_MODE 0x4000 -#define DDA2_ENABLE 0x100 -#define DDA1_ENABLE 0x80 -#define DIA2_ENABLE 0x40 -#define DIA1_ENABLE 0x20 -#define DSINGLE_STEP 0x10 /* not used */ -#define DDV_TYPE_MASK 0xc -#define DDV_TYPE_LOAD 0x0 -#define DDV_TYPE_STORE 0x4 -#define DDV_TYPE_ACCESS 0x8 -#define DDV_TYPE_ALWAYS 0xc -#define DDV_COND 0x2 -#define DDV_MASK 0x1 - -int -sparclite_insert_watchpoint (CORE_ADDR addr, int len, int type) -{ - CORE_ADDR dcr; - - dcr = read_register (DCR_REGNUM); - - if (!(dcr & DDA1_ENABLE)) - { - write_register (DDA1_REGNUM, addr); - dcr &= ~(DDA1_ASI_MASK | DDV_TYPE_MASK); - dcr |= (DDA1_SUP_ASI | DDA1_ENABLE); - if (type == 1) - { - write_register (DDV1_REGNUM, 0); - write_register (DDV2_REGNUM, 0xffffffff); - dcr |= (DDV_TYPE_LOAD & (~DDV_COND & ~DDV_MASK)); - } - else if (type == 0) - { - write_register (DDV1_REGNUM, 0); - write_register (DDV2_REGNUM, 0xffffffff); - dcr |= (DDV_TYPE_STORE & (~DDV_COND & ~DDV_MASK)); - } - else - { - write_register (DDV1_REGNUM, 0); - write_register (DDV2_REGNUM, 0xffffffff); - dcr |= (DDV_TYPE_ACCESS); - } - write_register (DCR_REGNUM, dcr); - } - else if (!(dcr & DDA2_ENABLE)) - { - write_register (DDA2_REGNUM, addr); - dcr &= ~(DDA2_ASI_MASK & DDV_TYPE_MASK); - dcr |= (DDA2_SUP_ASI | DDA2_ENABLE); - if (type == 1) - { - write_register (DDV1_REGNUM, 0); - write_register (DDV2_REGNUM, 0xffffffff); - dcr |= (DDV_TYPE_LOAD & ~DDV_COND & ~DDV_MASK); - } - else if (type == 0) - { - write_register (DDV1_REGNUM, 0); - write_register (DDV2_REGNUM, 0xffffffff); - dcr |= (DDV_TYPE_STORE & ~DDV_COND & ~DDV_MASK); - } - else - { - write_register (DDV1_REGNUM, 0); - write_register (DDV2_REGNUM, 0xffffffff); - dcr |= (DDV_TYPE_ACCESS); - } - write_register (DCR_REGNUM, dcr); - } - else - return -1; - - return 0; -} - -int -sparclite_remove_watchpoint (CORE_ADDR addr, int len, int type) -{ - CORE_ADDR dcr, dda1, dda2; - - dcr = read_register (DCR_REGNUM); - dda1 = read_register (DDA1_REGNUM); - dda2 = read_register (DDA2_REGNUM); - - if ((dcr & DDA1_ENABLE) && addr == dda1) - write_register (DCR_REGNUM, (dcr & ~DDA1_ENABLE)); - else if ((dcr & DDA2_ENABLE) && addr == dda2) - write_register (DCR_REGNUM, (dcr & ~DDA2_ENABLE)); - else - return -1; - - return 0; -} - -int -sparclite_insert_hw_breakpoint (CORE_ADDR addr, int len) -{ - CORE_ADDR dcr; - - dcr = read_register (DCR_REGNUM); - - if (!(dcr & DIA1_ENABLE)) - { - write_register (DIA1_REGNUM, addr); - write_register (DCR_REGNUM, (dcr | DIA1_ENABLE | DIA1_SUP_MODE)); - } - else if (!(dcr & DIA2_ENABLE)) - { - write_register (DIA2_REGNUM, addr); - write_register (DCR_REGNUM, (dcr | DIA2_ENABLE | DIA2_SUP_MODE)); - } - else - return -1; - - return 0; -} - -int -sparclite_remove_hw_breakpoint (CORE_ADDR addr, int shadow) -{ - CORE_ADDR dcr, dia1, dia2; - - dcr = read_register (DCR_REGNUM); - dia1 = read_register (DIA1_REGNUM); - dia2 = read_register (DIA2_REGNUM); - - if ((dcr & DIA1_ENABLE) && addr == dia1) - write_register (DCR_REGNUM, (dcr & ~DIA1_ENABLE)); - else if ((dcr & DIA2_ENABLE) && addr == dia2) - write_register (DCR_REGNUM, (dcr & ~DIA2_ENABLE)); - else - return -1; - - return 0; -} - -int -sparclite_check_watch_resources (int type, int cnt, int ot) -{ - /* Watchpoints not supported on simulator. */ - if (strcmp (target_shortname, "sim") == 0) - return 0; - - if (type == bp_hardware_breakpoint) - { - if (TARGET_HW_BREAK_LIMIT == 0) - return 0; - else if (cnt <= TARGET_HW_BREAK_LIMIT) - return 1; - } - else - { - if (TARGET_HW_WATCH_LIMIT == 0) - return 0; - else if (ot) - return -1; - else if (cnt <= TARGET_HW_WATCH_LIMIT) - return 1; - } - return -1; -} - -CORE_ADDR -sparclite_stopped_data_address (void) -{ - CORE_ADDR dsr, dda1, dda2; - - dsr = read_register (DSR_REGNUM); - dda1 = read_register (DDA1_REGNUM); - dda2 = read_register (DDA2_REGNUM); - - if (dsr & 0x10) - return dda1; - else if (dsr & 0x20) - return dda2; - else - return 0; -} - -static struct serial * -open_tty (char *name) -{ - struct serial *desc; - - desc = serial_open (name); - if (!desc) - perror_with_name (name); - - if (baud_rate != -1) - { - if (serial_setbaudrate (desc, baud_rate)) - { - serial_close (desc); - perror_with_name (name); - } - } - - serial_raw (desc); - - serial_flush_input (desc); - - return desc; -} - -/* Read a single character from the remote end, masking it down to 7 bits. */ - -static int -readchar (struct serial *desc, int timeout) -{ - int ch; - char s[10]; - - ch = serial_readchar (desc, timeout); - - switch (ch) - { - case SERIAL_EOF: - error ("SPARClite remote connection closed"); - case SERIAL_ERROR: - perror_with_name ("SPARClite communication error"); - case SERIAL_TIMEOUT: - error ("SPARClite remote timeout"); - default: - if (remote_debug > 0) - { - sprintf (s, "[%02x]", ch & 0xff); - puts_debug ("read -->", s, "<--"); - } - return ch; - } -} - -static void -debug_serial_write (struct serial *desc, char *buf, int len) -{ - char s[10]; - - serial_write (desc, buf, len); - if (remote_debug > 0) - { - while (len-- > 0) - { - sprintf (s, "[%02x]", *buf & 0xff); - puts_debug ("Sent -->", s, "<--"); - buf++; - } - } -} - - -static int -send_resp (struct serial *desc, char c) -{ - debug_serial_write (desc, &c, 1); - return readchar (desc, remote_timeout); -} - -static void -close_tty (void *ignore) -{ - if (!remote_desc) - return; - - serial_close (remote_desc); - - remote_desc = NULL; -} - -#ifdef HAVE_SOCKETS -static int -recv_udp_buf (int fd, unsigned char *buf, int len, int timeout) -{ - int cc; - fd_set readfds; - - FD_ZERO (&readfds); - FD_SET (fd, &readfds); - - if (timeout >= 0) - { - struct timeval timebuf; - - timebuf.tv_sec = timeout; - timebuf.tv_usec = 0; - cc = select (fd + 1, &readfds, 0, 0, &timebuf); - } - else - cc = select (fd + 1, &readfds, 0, 0, 0); - - if (cc == 0) - return 0; - - if (cc != 1) - perror_with_name ("recv_udp_buf: Bad return value from select:"); - - cc = recv (fd, buf, len, 0); - - if (cc < 0) - perror_with_name ("Got an error from recv: "); -} - -static int -send_udp_buf (int fd, unsigned char *buf, int len) -{ - int cc; - - cc = send (fd, buf, len, 0); - - if (cc == len) - return; - - if (cc < 0) - perror_with_name ("Got an error from send: "); - - error ("Short count in send: tried %d, sent %d\n", len, cc); -} -#endif /* HAVE_SOCKETS */ - -static void -sparclite_open (char *name, int from_tty) -{ - struct cleanup *old_chain; - int c; - char *p; - - if (!name) - error ("You need to specify what device or hostname is associated with the SparcLite board."); - - target_preopen (from_tty); - - unpush_target (&sparclite_ops); - - if (remote_target_name) - xfree (remote_target_name); - - remote_target_name = xstrdup (name); - - /* We need a 'serial' or 'udp' keyword to disambiguate host:port, which can - mean either a serial port on a terminal server, or the IP address of a - SPARClite demo board. If there's no colon, then it pretty much has to be - a local device (except for DOS... grrmble) */ - - p = strchr (name, ' '); - - if (p) - { - *p++ = '\000'; - while ((*p != '\000') && isspace (*p)) - p++; - - if (strncmp (name, "serial", strlen (name)) == 0) - serial_flag = 1; - else if (strncmp (name, "udp", strlen (name)) == 0) - serial_flag = 0; - else - error ("Must specify either `serial' or `udp'."); - } - else - { - p = name; - - if (!strchr (name, ':')) - serial_flag = 1; /* No colon is unambiguous (local device) */ - else - error ("Usage: target sparclite serial /dev/ttyb\n\ -or: target sparclite udp host"); - } - - if (serial_flag) - { - remote_desc = open_tty (p); - - old_chain = make_cleanup (close_tty, 0 /*ignore*/); - - c = send_resp (remote_desc, 0x00); - - if (c != 0xaa) - error ("Unknown response (0x%x) from SparcLite. Try resetting the board.", - c); - - c = send_resp (remote_desc, 0x55); - - if (c != 0x55) - error ("Sparclite appears to be ill."); - } - else - { -#ifdef HAVE_SOCKETS - struct hostent *he; - struct sockaddr_in sockaddr; - unsigned char buffer[100]; - int cc; - - /* Setup the socket. Must be raw UDP. */ - - he = gethostbyname (p); - - if (!he) - error ("No such host %s.", p); - - udp_fd = socket (PF_INET, SOCK_DGRAM, 0); - - old_chain = make_cleanup (close, udp_fd); - - sockaddr.sin_family = PF_INET; - sockaddr.sin_port = htons (7000); - memcpy (&sockaddr.sin_addr.s_addr, he->h_addr, sizeof (struct in_addr)); - - if (connect (udp_fd, &sockaddr, sizeof (sockaddr))) - perror_with_name ("Connect failed"); - - buffer[0] = 0x5; - buffer[1] = 0; - - send_udp_buf (udp_fd, buffer, 2); /* Request version */ - cc = recv_udp_buf (udp_fd, buffer, sizeof (buffer), 5); /* Get response */ - if (cc == 0) - error ("SPARClite isn't responding."); - - if (cc < 3) - error ("SPARClite appears to be ill."); -#else - error ("UDP downloading is not supported for DOS hosts."); -#endif /* HAVE_SOCKETS */ - } - - printf_unfiltered ("[SPARClite appears to be alive]\n"); - - push_target (&sparclite_ops); - - discard_cleanups (old_chain); - - return; -} - -static void -sparclite_close (int quitting) -{ - if (serial_flag) - close_tty (0); -#ifdef HAVE_SOCKETS - else if (udp_fd != -1) - close (udp_fd); -#endif -} - -#define LOAD_ADDRESS 0x40000000 - -static void -download (char *target_name, char *args, int from_tty, - void (*write_routine) (bfd *from_bfd, asection *from_sec, - file_ptr from_addr, bfd_vma to_addr, int len), - void (*start_routine) (bfd_vma entry)) -{ - struct cleanup *old_chain; - asection *section; - bfd *pbfd; - bfd_vma entry; - int i; -#define WRITESIZE 1024 - char *filename; - int quiet; - int nostart; - - quiet = 0; - nostart = 0; - filename = NULL; - - while (*args != '\000') - { - char *arg; - - while (isspace (*args)) - args++; - - arg = args; - - while ((*args != '\000') && !isspace (*args)) - args++; - - if (*args != '\000') - *args++ = '\000'; - - if (*arg != '-') - filename = arg; - else if (strncmp (arg, "-quiet", strlen (arg)) == 0) - quiet = 1; - else if (strncmp (arg, "-nostart", strlen (arg)) == 0) - nostart = 1; - else - error ("unknown option `%s'", arg); - } - - if (!filename) - filename = get_exec_file (1); - - pbfd = bfd_openr (filename, gnutarget); - if (pbfd == NULL) - { - perror_with_name (filename); - return; - } - old_chain = make_cleanup_bfd_close (pbfd); - - if (!bfd_check_format (pbfd, bfd_object)) - error ("\"%s\" is not an object file: %s", filename, - bfd_errmsg (bfd_get_error ())); - - for (section = pbfd->sections; section; section = section->next) - { - if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) - { - bfd_vma section_address; - bfd_size_type section_size; - file_ptr fptr; - const char *section_name; - - section_name = bfd_get_section_name (pbfd, section); - - section_address = bfd_get_section_vma (pbfd, section); - - /* Adjust sections from a.out files, since they don't - carry their addresses with. */ - if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour) - { - if (strcmp (section_name, ".text") == 0) - section_address = bfd_get_start_address (pbfd); - else if (strcmp (section_name, ".data") == 0) - { - /* Read the first 8 bytes of the data section. - There should be the string 'DaTa' followed by - a word containing the actual section address. */ - struct data_marker - { - char signature[4]; /* 'DaTa' */ - unsigned char sdata[4]; /* &sdata */ - } - marker; - bfd_get_section_contents (pbfd, section, &marker, 0, - sizeof (marker)); - if (strncmp (marker.signature, "DaTa", 4) == 0) - { - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - section_address = bfd_getb32 (marker.sdata); - else - section_address = bfd_getl32 (marker.sdata); - } - } - } - - section_size = bfd_get_section_size_before_reloc (section); - - if (!quiet) - printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n", - bfd_get_section_name (pbfd, section), - section_address, - section_size); - - fptr = 0; - while (section_size > 0) - { - int count; - static char inds[] = "|/-\\"; - static int k = 0; - - QUIT; - - count = min (section_size, WRITESIZE); - - write_routine (pbfd, section, fptr, section_address, count); - - if (!quiet) - { - printf_unfiltered ("\r%c", inds[k++ % 4]); - gdb_flush (gdb_stdout); - } - - section_address += count; - fptr += count; - section_size -= count; - } - } - } - - if (!nostart) - { - entry = bfd_get_start_address (pbfd); - - if (!quiet) - printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry); - - start_routine (entry); - } - - do_cleanups (old_chain); -} - -static void -sparclite_serial_start (bfd_vma entry) -{ - char buffer[5]; - int i; - - buffer[0] = 0x03; - store_unsigned_integer (buffer + 1, 4, entry); - - debug_serial_write (remote_desc, buffer, 1 + 4); - i = readchar (remote_desc, remote_timeout); - if (i != 0x55) - error ("Can't start SparcLite. Error code %d\n", i); -} - -static void -sparclite_serial_write (bfd *from_bfd, asection *from_sec, file_ptr from_addr, - bfd_vma to_addr, int len) -{ - char buffer[4 + 4 + WRITESIZE]; /* addr + len + data */ - unsigned char checksum; - int i; - - store_unsigned_integer (buffer, 4, to_addr); /* Address */ - store_unsigned_integer (buffer + 4, 4, len); /* Length */ - - bfd_get_section_contents (from_bfd, from_sec, buffer + 8, from_addr, len); - - checksum = 0; - for (i = 0; i < len; i++) - checksum += buffer[8 + i]; - - i = send_resp (remote_desc, 0x01); - - if (i != 0x5a) - error ("Bad response from load command (0x%x)", i); - - debug_serial_write (remote_desc, buffer, 4 + 4 + len); - i = readchar (remote_desc, remote_timeout); - - if (i != checksum) - error ("Bad checksum from load command (0x%x)", i); -} - -#ifdef HAVE_SOCKETS - -static unsigned short -calc_checksum (unsigned char *buffer, int count) -{ - unsigned short checksum; - - checksum = 0; - for (; count > 0; count -= 2, buffer += 2) - checksum += (*buffer << 8) | *(buffer + 1); - - if (count != 0) - checksum += *buffer << 8; - - return checksum; -} - -static void -sparclite_udp_start (bfd_vma entry) -{ - unsigned char buffer[6]; - int i; - - buffer[0] = 0x3; - buffer[1] = 0; - buffer[2] = entry >> 24; - buffer[3] = entry >> 16; - buffer[4] = entry >> 8; - buffer[5] = entry; - - send_udp_buf (udp_fd, buffer, 6); /* Send start addr */ - i = recv_udp_buf (udp_fd, buffer, sizeof (buffer), -1); /* Get response */ - - if (i < 1 || buffer[0] != 0x55) - error ("Failed to take start address."); -} - -static void -sparclite_udp_write (bfd *from_bfd, asection *from_sec, file_ptr from_addr, - bfd_vma to_addr, int len) -{ - unsigned char buffer[2000]; - unsigned short checksum; - static int pkt_num = 0; - static unsigned long old_addr = -1; - int i; - - while (1) - { - if (to_addr != old_addr) - { - buffer[0] = 0x1; /* Load command */ - buffer[1] = 0x1; /* Loading address */ - buffer[2] = to_addr >> 24; - buffer[3] = to_addr >> 16; - buffer[4] = to_addr >> 8; - buffer[5] = to_addr; - - checksum = 0; - for (i = 0; i < 6; i++) - checksum += buffer[i]; - checksum &= 0xff; - - send_udp_buf (udp_fd, buffer, 6); - i = recv_udp_buf (udp_fd, buffer, sizeof buffer, -1); - - if (i < 1) - error ("Got back short checksum for load addr."); - - if (checksum != buffer[0]) - error ("Got back bad checksum for load addr."); - - pkt_num = 0; /* Load addr resets packet seq # */ - old_addr = to_addr; - } - - bfd_get_section_contents (from_bfd, from_sec, buffer + 6, from_addr, - len); - - checksum = calc_checksum (buffer + 6, len); - - buffer[0] = 0x1; /* Load command */ - buffer[1] = 0x2; /* Loading data */ - buffer[2] = pkt_num >> 8; - buffer[3] = pkt_num; - buffer[4] = checksum >> 8; - buffer[5] = checksum; - - send_udp_buf (udp_fd, buffer, len + 6); - i = recv_udp_buf (udp_fd, buffer, sizeof buffer, 3); - - if (i == 0) - { - fprintf_unfiltered (gdb_stderr, "send_data: timeout sending %d bytes to address 0x%x retrying\n", len, to_addr); - continue; - } - - if (buffer[0] != 0xff) - error ("Got back bad response for load data."); - - old_addr += len; - pkt_num++; - - return; - } -} - -#endif /* HAVE_SOCKETS */ - -static void -sparclite_download (char *filename, int from_tty) -{ - if (!serial_flag) -#ifdef HAVE_SOCKETS - download (remote_target_name, filename, from_tty, sparclite_udp_write, - sparclite_udp_start); -#else - internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* sparclite_open should prevent this! */ -#endif - else - download (remote_target_name, filename, from_tty, sparclite_serial_write, - sparclite_serial_start); -} - -/* Set up the sparclite target vector. */ - -static void -init_sparclite_ops (void) -{ - sparclite_ops.to_shortname = "sparclite"; - sparclite_ops.to_longname = "SPARClite download target"; - sparclite_ops.to_doc = "Download to a remote SPARClite target board via serial of UDP.\n\ -Specify the device it is connected to (e.g. /dev/ttya)."; - sparclite_ops.to_open = sparclite_open; - sparclite_ops.to_close = sparclite_close; - sparclite_ops.to_load = sparclite_download; - sparclite_ops.to_stratum = download_stratum; - sparclite_ops.to_magic = OPS_MAGIC; -} - -void -_initialize_sparcl_tdep (void) -{ - init_sparclite_ops (); - add_target (&sparclite_ops); -} +// OBSOLETE /* Target dependent code for the Fujitsu SPARClite for GDB, the GNU debugger. +// OBSOLETE Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001 +// OBSOLETE Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "defs.h" +// OBSOLETE #include "gdbcore.h" +// OBSOLETE #include "breakpoint.h" +// OBSOLETE #include "target.h" +// OBSOLETE #include "serial.h" +// OBSOLETE #include "regcache.h" +// OBSOLETE #include <sys/types.h> +// OBSOLETE +// OBSOLETE #if (!defined(__GO32__) && !defined(_WIN32)) || defined(__CYGWIN__) +// OBSOLETE #define HAVE_SOCKETS +// OBSOLETE #include <sys/time.h> +// OBSOLETE #include <sys/socket.h> +// OBSOLETE #include <netinet/in.h> +// OBSOLETE #include <netdb.h> +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE static struct target_ops sparclite_ops; +// OBSOLETE +// OBSOLETE static char *remote_target_name = NULL; +// OBSOLETE static struct serial *remote_desc = NULL; +// OBSOLETE static int serial_flag; +// OBSOLETE #ifdef HAVE_SOCKETS +// OBSOLETE static int udp_fd = -1; +// OBSOLETE #endif +// OBSOLETE +// OBSOLETE static struct serial *open_tty (char *name); +// OBSOLETE static int send_resp (struct serial *desc, char c); +// OBSOLETE static void close_tty (void * ignore); +// OBSOLETE #ifdef HAVE_SOCKETS +// OBSOLETE static int recv_udp_buf (int fd, unsigned char *buf, int len, int timeout); +// OBSOLETE static int send_udp_buf (int fd, unsigned char *buf, int len); +// OBSOLETE #endif +// OBSOLETE static void sparclite_open (char *name, int from_tty); +// OBSOLETE static void sparclite_close (int quitting); +// OBSOLETE static void download (char *target_name, char *args, int from_tty, +// OBSOLETE void (*write_routine) (bfd * from_bfd, +// OBSOLETE asection * from_sec, +// OBSOLETE file_ptr from_addr, +// OBSOLETE bfd_vma to_addr, int len), +// OBSOLETE void (*start_routine) (bfd_vma entry)); +// OBSOLETE static void sparclite_serial_start (bfd_vma entry); +// OBSOLETE static void sparclite_serial_write (bfd * from_bfd, asection * from_sec, +// OBSOLETE file_ptr from_addr, +// OBSOLETE bfd_vma to_addr, int len); +// OBSOLETE #ifdef HAVE_SOCKETS +// OBSOLETE static unsigned short calc_checksum (unsigned char *buffer, int count); +// OBSOLETE static void sparclite_udp_start (bfd_vma entry); +// OBSOLETE static void sparclite_udp_write (bfd * from_bfd, asection * from_sec, +// OBSOLETE file_ptr from_addr, bfd_vma to_addr, +// OBSOLETE int len); +// OBSOLETE #endif +// OBSOLETE static void sparclite_download (char *filename, int from_tty); +// OBSOLETE +// OBSOLETE #define DDA2_SUP_ASI 0xb000000 +// OBSOLETE #define DDA1_SUP_ASI 0xb0000 +// OBSOLETE +// OBSOLETE #define DDA2_ASI_MASK 0xff000000 +// OBSOLETE #define DDA1_ASI_MASK 0xff0000 +// OBSOLETE #define DIA2_SUP_MODE 0x8000 +// OBSOLETE #define DIA1_SUP_MODE 0x4000 +// OBSOLETE #define DDA2_ENABLE 0x100 +// OBSOLETE #define DDA1_ENABLE 0x80 +// OBSOLETE #define DIA2_ENABLE 0x40 +// OBSOLETE #define DIA1_ENABLE 0x20 +// OBSOLETE #define DSINGLE_STEP 0x10 /* not used */ +// OBSOLETE #define DDV_TYPE_MASK 0xc +// OBSOLETE #define DDV_TYPE_LOAD 0x0 +// OBSOLETE #define DDV_TYPE_STORE 0x4 +// OBSOLETE #define DDV_TYPE_ACCESS 0x8 +// OBSOLETE #define DDV_TYPE_ALWAYS 0xc +// OBSOLETE #define DDV_COND 0x2 +// OBSOLETE #define DDV_MASK 0x1 +// OBSOLETE +// OBSOLETE int +// OBSOLETE sparclite_insert_watchpoint (CORE_ADDR addr, int len, int type) +// OBSOLETE { +// OBSOLETE CORE_ADDR dcr; +// OBSOLETE +// OBSOLETE dcr = read_register (DCR_REGNUM); +// OBSOLETE +// OBSOLETE if (!(dcr & DDA1_ENABLE)) +// OBSOLETE { +// OBSOLETE write_register (DDA1_REGNUM, addr); +// OBSOLETE dcr &= ~(DDA1_ASI_MASK | DDV_TYPE_MASK); +// OBSOLETE dcr |= (DDA1_SUP_ASI | DDA1_ENABLE); +// OBSOLETE if (type == 1) +// OBSOLETE { +// OBSOLETE write_register (DDV1_REGNUM, 0); +// OBSOLETE write_register (DDV2_REGNUM, 0xffffffff); +// OBSOLETE dcr |= (DDV_TYPE_LOAD & (~DDV_COND & ~DDV_MASK)); +// OBSOLETE } +// OBSOLETE else if (type == 0) +// OBSOLETE { +// OBSOLETE write_register (DDV1_REGNUM, 0); +// OBSOLETE write_register (DDV2_REGNUM, 0xffffffff); +// OBSOLETE dcr |= (DDV_TYPE_STORE & (~DDV_COND & ~DDV_MASK)); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE write_register (DDV1_REGNUM, 0); +// OBSOLETE write_register (DDV2_REGNUM, 0xffffffff); +// OBSOLETE dcr |= (DDV_TYPE_ACCESS); +// OBSOLETE } +// OBSOLETE write_register (DCR_REGNUM, dcr); +// OBSOLETE } +// OBSOLETE else if (!(dcr & DDA2_ENABLE)) +// OBSOLETE { +// OBSOLETE write_register (DDA2_REGNUM, addr); +// OBSOLETE dcr &= ~(DDA2_ASI_MASK & DDV_TYPE_MASK); +// OBSOLETE dcr |= (DDA2_SUP_ASI | DDA2_ENABLE); +// OBSOLETE if (type == 1) +// OBSOLETE { +// OBSOLETE write_register (DDV1_REGNUM, 0); +// OBSOLETE write_register (DDV2_REGNUM, 0xffffffff); +// OBSOLETE dcr |= (DDV_TYPE_LOAD & ~DDV_COND & ~DDV_MASK); +// OBSOLETE } +// OBSOLETE else if (type == 0) +// OBSOLETE { +// OBSOLETE write_register (DDV1_REGNUM, 0); +// OBSOLETE write_register (DDV2_REGNUM, 0xffffffff); +// OBSOLETE dcr |= (DDV_TYPE_STORE & ~DDV_COND & ~DDV_MASK); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE write_register (DDV1_REGNUM, 0); +// OBSOLETE write_register (DDV2_REGNUM, 0xffffffff); +// OBSOLETE dcr |= (DDV_TYPE_ACCESS); +// OBSOLETE } +// OBSOLETE write_register (DCR_REGNUM, dcr); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE return -1; +// OBSOLETE +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE sparclite_remove_watchpoint (CORE_ADDR addr, int len, int type) +// OBSOLETE { +// OBSOLETE CORE_ADDR dcr, dda1, dda2; +// OBSOLETE +// OBSOLETE dcr = read_register (DCR_REGNUM); +// OBSOLETE dda1 = read_register (DDA1_REGNUM); +// OBSOLETE dda2 = read_register (DDA2_REGNUM); +// OBSOLETE +// OBSOLETE if ((dcr & DDA1_ENABLE) && addr == dda1) +// OBSOLETE write_register (DCR_REGNUM, (dcr & ~DDA1_ENABLE)); +// OBSOLETE else if ((dcr & DDA2_ENABLE) && addr == dda2) +// OBSOLETE write_register (DCR_REGNUM, (dcr & ~DDA2_ENABLE)); +// OBSOLETE else +// OBSOLETE return -1; +// OBSOLETE +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE sparclite_insert_hw_breakpoint (CORE_ADDR addr, int len) +// OBSOLETE { +// OBSOLETE CORE_ADDR dcr; +// OBSOLETE +// OBSOLETE dcr = read_register (DCR_REGNUM); +// OBSOLETE +// OBSOLETE if (!(dcr & DIA1_ENABLE)) +// OBSOLETE { +// OBSOLETE write_register (DIA1_REGNUM, addr); +// OBSOLETE write_register (DCR_REGNUM, (dcr | DIA1_ENABLE | DIA1_SUP_MODE)); +// OBSOLETE } +// OBSOLETE else if (!(dcr & DIA2_ENABLE)) +// OBSOLETE { +// OBSOLETE write_register (DIA2_REGNUM, addr); +// OBSOLETE write_register (DCR_REGNUM, (dcr | DIA2_ENABLE | DIA2_SUP_MODE)); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE return -1; +// OBSOLETE +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE sparclite_remove_hw_breakpoint (CORE_ADDR addr, int shadow) +// OBSOLETE { +// OBSOLETE CORE_ADDR dcr, dia1, dia2; +// OBSOLETE +// OBSOLETE dcr = read_register (DCR_REGNUM); +// OBSOLETE dia1 = read_register (DIA1_REGNUM); +// OBSOLETE dia2 = read_register (DIA2_REGNUM); +// OBSOLETE +// OBSOLETE if ((dcr & DIA1_ENABLE) && addr == dia1) +// OBSOLETE write_register (DCR_REGNUM, (dcr & ~DIA1_ENABLE)); +// OBSOLETE else if ((dcr & DIA2_ENABLE) && addr == dia2) +// OBSOLETE write_register (DCR_REGNUM, (dcr & ~DIA2_ENABLE)); +// OBSOLETE else +// OBSOLETE return -1; +// OBSOLETE +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE int +// OBSOLETE sparclite_check_watch_resources (int type, int cnt, int ot) +// OBSOLETE { +// OBSOLETE /* Watchpoints not supported on simulator. */ +// OBSOLETE if (strcmp (target_shortname, "sim") == 0) +// OBSOLETE return 0; +// OBSOLETE +// OBSOLETE if (type == bp_hardware_breakpoint) +// OBSOLETE { +// OBSOLETE if (TARGET_HW_BREAK_LIMIT == 0) +// OBSOLETE return 0; +// OBSOLETE else if (cnt <= TARGET_HW_BREAK_LIMIT) +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE if (TARGET_HW_WATCH_LIMIT == 0) +// OBSOLETE return 0; +// OBSOLETE else if (ot) +// OBSOLETE return -1; +// OBSOLETE else if (cnt <= TARGET_HW_WATCH_LIMIT) +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE return -1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE sparclite_stopped_data_address (void) +// OBSOLETE { +// OBSOLETE CORE_ADDR dsr, dda1, dda2; +// OBSOLETE +// OBSOLETE dsr = read_register (DSR_REGNUM); +// OBSOLETE dda1 = read_register (DDA1_REGNUM); +// OBSOLETE dda2 = read_register (DDA2_REGNUM); +// OBSOLETE +// OBSOLETE if (dsr & 0x10) +// OBSOLETE return dda1; +// OBSOLETE else if (dsr & 0x20) +// OBSOLETE return dda2; +// OBSOLETE else +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static struct serial * +// OBSOLETE open_tty (char *name) +// OBSOLETE { +// OBSOLETE struct serial *desc; +// OBSOLETE +// OBSOLETE desc = serial_open (name); +// OBSOLETE if (!desc) +// OBSOLETE perror_with_name (name); +// OBSOLETE +// OBSOLETE if (baud_rate != -1) +// OBSOLETE { +// OBSOLETE if (serial_setbaudrate (desc, baud_rate)) +// OBSOLETE { +// OBSOLETE serial_close (desc); +// OBSOLETE perror_with_name (name); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE serial_raw (desc); +// OBSOLETE +// OBSOLETE serial_flush_input (desc); +// OBSOLETE +// OBSOLETE return desc; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Read a single character from the remote end, masking it down to 7 bits. */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE readchar (struct serial *desc, int timeout) +// OBSOLETE { +// OBSOLETE int ch; +// OBSOLETE char s[10]; +// OBSOLETE +// OBSOLETE ch = serial_readchar (desc, timeout); +// OBSOLETE +// OBSOLETE switch (ch) +// OBSOLETE { +// OBSOLETE case SERIAL_EOF: +// OBSOLETE error ("SPARClite remote connection closed"); +// OBSOLETE case SERIAL_ERROR: +// OBSOLETE perror_with_name ("SPARClite communication error"); +// OBSOLETE case SERIAL_TIMEOUT: +// OBSOLETE error ("SPARClite remote timeout"); +// OBSOLETE default: +// OBSOLETE if (remote_debug > 0) +// OBSOLETE { +// OBSOLETE sprintf (s, "[%02x]", ch & 0xff); +// OBSOLETE puts_debug ("read -->", s, "<--"); +// OBSOLETE } +// OBSOLETE return ch; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE debug_serial_write (struct serial *desc, char *buf, int len) +// OBSOLETE { +// OBSOLETE char s[10]; +// OBSOLETE +// OBSOLETE serial_write (desc, buf, len); +// OBSOLETE if (remote_debug > 0) +// OBSOLETE { +// OBSOLETE while (len-- > 0) +// OBSOLETE { +// OBSOLETE sprintf (s, "[%02x]", *buf & 0xff); +// OBSOLETE puts_debug ("Sent -->", s, "<--"); +// OBSOLETE buf++; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE static int +// OBSOLETE send_resp (struct serial *desc, char c) +// OBSOLETE { +// OBSOLETE debug_serial_write (desc, &c, 1); +// OBSOLETE return readchar (desc, remote_timeout); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE close_tty (void *ignore) +// OBSOLETE { +// OBSOLETE if (!remote_desc) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE serial_close (remote_desc); +// OBSOLETE +// OBSOLETE remote_desc = NULL; +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifdef HAVE_SOCKETS +// OBSOLETE static int +// OBSOLETE recv_udp_buf (int fd, unsigned char *buf, int len, int timeout) +// OBSOLETE { +// OBSOLETE int cc; +// OBSOLETE fd_set readfds; +// OBSOLETE +// OBSOLETE FD_ZERO (&readfds); +// OBSOLETE FD_SET (fd, &readfds); +// OBSOLETE +// OBSOLETE if (timeout >= 0) +// OBSOLETE { +// OBSOLETE struct timeval timebuf; +// OBSOLETE +// OBSOLETE timebuf.tv_sec = timeout; +// OBSOLETE timebuf.tv_usec = 0; +// OBSOLETE cc = select (fd + 1, &readfds, 0, 0, &timebuf); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE cc = select (fd + 1, &readfds, 0, 0, 0); +// OBSOLETE +// OBSOLETE if (cc == 0) +// OBSOLETE return 0; +// OBSOLETE +// OBSOLETE if (cc != 1) +// OBSOLETE perror_with_name ("recv_udp_buf: Bad return value from select:"); +// OBSOLETE +// OBSOLETE cc = recv (fd, buf, len, 0); +// OBSOLETE +// OBSOLETE if (cc < 0) +// OBSOLETE perror_with_name ("Got an error from recv: "); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static int +// OBSOLETE send_udp_buf (int fd, unsigned char *buf, int len) +// OBSOLETE { +// OBSOLETE int cc; +// OBSOLETE +// OBSOLETE cc = send (fd, buf, len, 0); +// OBSOLETE +// OBSOLETE if (cc == len) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE if (cc < 0) +// OBSOLETE perror_with_name ("Got an error from send: "); +// OBSOLETE +// OBSOLETE error ("Short count in send: tried %d, sent %d\n", len, cc); +// OBSOLETE } +// OBSOLETE #endif /* HAVE_SOCKETS */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclite_open (char *name, int from_tty) +// OBSOLETE { +// OBSOLETE struct cleanup *old_chain; +// OBSOLETE int c; +// OBSOLETE char *p; +// OBSOLETE +// OBSOLETE if (!name) +// OBSOLETE error ("You need to specify what device or hostname is associated with the SparcLite board."); +// OBSOLETE +// OBSOLETE target_preopen (from_tty); +// OBSOLETE +// OBSOLETE unpush_target (&sparclite_ops); +// OBSOLETE +// OBSOLETE if (remote_target_name) +// OBSOLETE xfree (remote_target_name); +// OBSOLETE +// OBSOLETE remote_target_name = xstrdup (name); +// OBSOLETE +// OBSOLETE /* We need a 'serial' or 'udp' keyword to disambiguate host:port, which can +// OBSOLETE mean either a serial port on a terminal server, or the IP address of a +// OBSOLETE SPARClite demo board. If there's no colon, then it pretty much has to be +// OBSOLETE a local device (except for DOS... grrmble) */ +// OBSOLETE +// OBSOLETE p = strchr (name, ' '); +// OBSOLETE +// OBSOLETE if (p) +// OBSOLETE { +// OBSOLETE *p++ = '\000'; +// OBSOLETE while ((*p != '\000') && isspace (*p)) +// OBSOLETE p++; +// OBSOLETE +// OBSOLETE if (strncmp (name, "serial", strlen (name)) == 0) +// OBSOLETE serial_flag = 1; +// OBSOLETE else if (strncmp (name, "udp", strlen (name)) == 0) +// OBSOLETE serial_flag = 0; +// OBSOLETE else +// OBSOLETE error ("Must specify either `serial' or `udp'."); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE p = name; +// OBSOLETE +// OBSOLETE if (!strchr (name, ':')) +// OBSOLETE serial_flag = 1; /* No colon is unambiguous (local device) */ +// OBSOLETE else +// OBSOLETE error ("Usage: target sparclite serial /dev/ttyb\n\ +// OBSOLETE or: target sparclite udp host"); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (serial_flag) +// OBSOLETE { +// OBSOLETE remote_desc = open_tty (p); +// OBSOLETE +// OBSOLETE old_chain = make_cleanup (close_tty, 0 /*ignore*/); +// OBSOLETE +// OBSOLETE c = send_resp (remote_desc, 0x00); +// OBSOLETE +// OBSOLETE if (c != 0xaa) +// OBSOLETE error ("Unknown response (0x%x) from SparcLite. Try resetting the board.", +// OBSOLETE c); +// OBSOLETE +// OBSOLETE c = send_resp (remote_desc, 0x55); +// OBSOLETE +// OBSOLETE if (c != 0x55) +// OBSOLETE error ("Sparclite appears to be ill."); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE #ifdef HAVE_SOCKETS +// OBSOLETE struct hostent *he; +// OBSOLETE struct sockaddr_in sockaddr; +// OBSOLETE unsigned char buffer[100]; +// OBSOLETE int cc; +// OBSOLETE +// OBSOLETE /* Setup the socket. Must be raw UDP. */ +// OBSOLETE +// OBSOLETE he = gethostbyname (p); +// OBSOLETE +// OBSOLETE if (!he) +// OBSOLETE error ("No such host %s.", p); +// OBSOLETE +// OBSOLETE udp_fd = socket (PF_INET, SOCK_DGRAM, 0); +// OBSOLETE +// OBSOLETE old_chain = make_cleanup (close, udp_fd); +// OBSOLETE +// OBSOLETE sockaddr.sin_family = PF_INET; +// OBSOLETE sockaddr.sin_port = htons (7000); +// OBSOLETE memcpy (&sockaddr.sin_addr.s_addr, he->h_addr, sizeof (struct in_addr)); +// OBSOLETE +// OBSOLETE if (connect (udp_fd, &sockaddr, sizeof (sockaddr))) +// OBSOLETE perror_with_name ("Connect failed"); +// OBSOLETE +// OBSOLETE buffer[0] = 0x5; +// OBSOLETE buffer[1] = 0; +// OBSOLETE +// OBSOLETE send_udp_buf (udp_fd, buffer, 2); /* Request version */ +// OBSOLETE cc = recv_udp_buf (udp_fd, buffer, sizeof (buffer), 5); /* Get response */ +// OBSOLETE if (cc == 0) +// OBSOLETE error ("SPARClite isn't responding."); +// OBSOLETE +// OBSOLETE if (cc < 3) +// OBSOLETE error ("SPARClite appears to be ill."); +// OBSOLETE #else +// OBSOLETE error ("UDP downloading is not supported for DOS hosts."); +// OBSOLETE #endif /* HAVE_SOCKETS */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE printf_unfiltered ("[SPARClite appears to be alive]\n"); +// OBSOLETE +// OBSOLETE push_target (&sparclite_ops); +// OBSOLETE +// OBSOLETE discard_cleanups (old_chain); +// OBSOLETE +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclite_close (int quitting) +// OBSOLETE { +// OBSOLETE if (serial_flag) +// OBSOLETE close_tty (0); +// OBSOLETE #ifdef HAVE_SOCKETS +// OBSOLETE else if (udp_fd != -1) +// OBSOLETE close (udp_fd); +// OBSOLETE #endif +// OBSOLETE } +// OBSOLETE +// OBSOLETE #define LOAD_ADDRESS 0x40000000 +// OBSOLETE +// OBSOLETE static void +// OBSOLETE download (char *target_name, char *args, int from_tty, +// OBSOLETE void (*write_routine) (bfd *from_bfd, asection *from_sec, +// OBSOLETE file_ptr from_addr, bfd_vma to_addr, int len), +// OBSOLETE void (*start_routine) (bfd_vma entry)) +// OBSOLETE { +// OBSOLETE struct cleanup *old_chain; +// OBSOLETE asection *section; +// OBSOLETE bfd *pbfd; +// OBSOLETE bfd_vma entry; +// OBSOLETE int i; +// OBSOLETE #define WRITESIZE 1024 +// OBSOLETE char *filename; +// OBSOLETE int quiet; +// OBSOLETE int nostart; +// OBSOLETE +// OBSOLETE quiet = 0; +// OBSOLETE nostart = 0; +// OBSOLETE filename = NULL; +// OBSOLETE +// OBSOLETE while (*args != '\000') +// OBSOLETE { +// OBSOLETE char *arg; +// OBSOLETE +// OBSOLETE while (isspace (*args)) +// OBSOLETE args++; +// OBSOLETE +// OBSOLETE arg = args; +// OBSOLETE +// OBSOLETE while ((*args != '\000') && !isspace (*args)) +// OBSOLETE args++; +// OBSOLETE +// OBSOLETE if (*args != '\000') +// OBSOLETE *args++ = '\000'; +// OBSOLETE +// OBSOLETE if (*arg != '-') +// OBSOLETE filename = arg; +// OBSOLETE else if (strncmp (arg, "-quiet", strlen (arg)) == 0) +// OBSOLETE quiet = 1; +// OBSOLETE else if (strncmp (arg, "-nostart", strlen (arg)) == 0) +// OBSOLETE nostart = 1; +// OBSOLETE else +// OBSOLETE error ("unknown option `%s'", arg); +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (!filename) +// OBSOLETE filename = get_exec_file (1); +// OBSOLETE +// OBSOLETE pbfd = bfd_openr (filename, gnutarget); +// OBSOLETE if (pbfd == NULL) +// OBSOLETE { +// OBSOLETE perror_with_name (filename); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE old_chain = make_cleanup_bfd_close (pbfd); +// OBSOLETE +// OBSOLETE if (!bfd_check_format (pbfd, bfd_object)) +// OBSOLETE error ("\"%s\" is not an object file: %s", filename, +// OBSOLETE bfd_errmsg (bfd_get_error ())); +// OBSOLETE +// OBSOLETE for (section = pbfd->sections; section; section = section->next) +// OBSOLETE { +// OBSOLETE if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) +// OBSOLETE { +// OBSOLETE bfd_vma section_address; +// OBSOLETE bfd_size_type section_size; +// OBSOLETE file_ptr fptr; +// OBSOLETE const char *section_name; +// OBSOLETE +// OBSOLETE section_name = bfd_get_section_name (pbfd, section); +// OBSOLETE +// OBSOLETE section_address = bfd_get_section_vma (pbfd, section); +// OBSOLETE +// OBSOLETE /* Adjust sections from a.out files, since they don't +// OBSOLETE carry their addresses with. */ +// OBSOLETE if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour) +// OBSOLETE { +// OBSOLETE if (strcmp (section_name, ".text") == 0) +// OBSOLETE section_address = bfd_get_start_address (pbfd); +// OBSOLETE else if (strcmp (section_name, ".data") == 0) +// OBSOLETE { +// OBSOLETE /* Read the first 8 bytes of the data section. +// OBSOLETE There should be the string 'DaTa' followed by +// OBSOLETE a word containing the actual section address. */ +// OBSOLETE struct data_marker +// OBSOLETE { +// OBSOLETE char signature[4]; /* 'DaTa' */ +// OBSOLETE unsigned char sdata[4]; /* &sdata */ +// OBSOLETE } +// OBSOLETE marker; +// OBSOLETE bfd_get_section_contents (pbfd, section, &marker, 0, +// OBSOLETE sizeof (marker)); +// OBSOLETE if (strncmp (marker.signature, "DaTa", 4) == 0) +// OBSOLETE { +// OBSOLETE if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) +// OBSOLETE section_address = bfd_getb32 (marker.sdata); +// OBSOLETE else +// OBSOLETE section_address = bfd_getl32 (marker.sdata); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE section_size = bfd_get_section_size_before_reloc (section); +// OBSOLETE +// OBSOLETE if (!quiet) +// OBSOLETE printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n", +// OBSOLETE bfd_get_section_name (pbfd, section), +// OBSOLETE section_address, +// OBSOLETE section_size); +// OBSOLETE +// OBSOLETE fptr = 0; +// OBSOLETE while (section_size > 0) +// OBSOLETE { +// OBSOLETE int count; +// OBSOLETE static char inds[] = "|/-\\"; +// OBSOLETE static int k = 0; +// OBSOLETE +// OBSOLETE QUIT; +// OBSOLETE +// OBSOLETE count = min (section_size, WRITESIZE); +// OBSOLETE +// OBSOLETE write_routine (pbfd, section, fptr, section_address, count); +// OBSOLETE +// OBSOLETE if (!quiet) +// OBSOLETE { +// OBSOLETE printf_unfiltered ("\r%c", inds[k++ % 4]); +// OBSOLETE gdb_flush (gdb_stdout); +// OBSOLETE } +// OBSOLETE +// OBSOLETE section_address += count; +// OBSOLETE fptr += count; +// OBSOLETE section_size -= count; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (!nostart) +// OBSOLETE { +// OBSOLETE entry = bfd_get_start_address (pbfd); +// OBSOLETE +// OBSOLETE if (!quiet) +// OBSOLETE printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry); +// OBSOLETE +// OBSOLETE start_routine (entry); +// OBSOLETE } +// OBSOLETE +// OBSOLETE do_cleanups (old_chain); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclite_serial_start (bfd_vma entry) +// OBSOLETE { +// OBSOLETE char buffer[5]; +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE buffer[0] = 0x03; +// OBSOLETE store_unsigned_integer (buffer + 1, 4, entry); +// OBSOLETE +// OBSOLETE debug_serial_write (remote_desc, buffer, 1 + 4); +// OBSOLETE i = readchar (remote_desc, remote_timeout); +// OBSOLETE if (i != 0x55) +// OBSOLETE error ("Can't start SparcLite. Error code %d\n", i); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclite_serial_write (bfd *from_bfd, asection *from_sec, file_ptr from_addr, +// OBSOLETE bfd_vma to_addr, int len) +// OBSOLETE { +// OBSOLETE char buffer[4 + 4 + WRITESIZE]; /* addr + len + data */ +// OBSOLETE unsigned char checksum; +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE store_unsigned_integer (buffer, 4, to_addr); /* Address */ +// OBSOLETE store_unsigned_integer (buffer + 4, 4, len); /* Length */ +// OBSOLETE +// OBSOLETE bfd_get_section_contents (from_bfd, from_sec, buffer + 8, from_addr, len); +// OBSOLETE +// OBSOLETE checksum = 0; +// OBSOLETE for (i = 0; i < len; i++) +// OBSOLETE checksum += buffer[8 + i]; +// OBSOLETE +// OBSOLETE i = send_resp (remote_desc, 0x01); +// OBSOLETE +// OBSOLETE if (i != 0x5a) +// OBSOLETE error ("Bad response from load command (0x%x)", i); +// OBSOLETE +// OBSOLETE debug_serial_write (remote_desc, buffer, 4 + 4 + len); +// OBSOLETE i = readchar (remote_desc, remote_timeout); +// OBSOLETE +// OBSOLETE if (i != checksum) +// OBSOLETE error ("Bad checksum from load command (0x%x)", i); +// OBSOLETE } +// OBSOLETE +// OBSOLETE #ifdef HAVE_SOCKETS +// OBSOLETE +// OBSOLETE static unsigned short +// OBSOLETE calc_checksum (unsigned char *buffer, int count) +// OBSOLETE { +// OBSOLETE unsigned short checksum; +// OBSOLETE +// OBSOLETE checksum = 0; +// OBSOLETE for (; count > 0; count -= 2, buffer += 2) +// OBSOLETE checksum += (*buffer << 8) | *(buffer + 1); +// OBSOLETE +// OBSOLETE if (count != 0) +// OBSOLETE checksum += *buffer << 8; +// OBSOLETE +// OBSOLETE return checksum; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclite_udp_start (bfd_vma entry) +// OBSOLETE { +// OBSOLETE unsigned char buffer[6]; +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE buffer[0] = 0x3; +// OBSOLETE buffer[1] = 0; +// OBSOLETE buffer[2] = entry >> 24; +// OBSOLETE buffer[3] = entry >> 16; +// OBSOLETE buffer[4] = entry >> 8; +// OBSOLETE buffer[5] = entry; +// OBSOLETE +// OBSOLETE send_udp_buf (udp_fd, buffer, 6); /* Send start addr */ +// OBSOLETE i = recv_udp_buf (udp_fd, buffer, sizeof (buffer), -1); /* Get response */ +// OBSOLETE +// OBSOLETE if (i < 1 || buffer[0] != 0x55) +// OBSOLETE error ("Failed to take start address."); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclite_udp_write (bfd *from_bfd, asection *from_sec, file_ptr from_addr, +// OBSOLETE bfd_vma to_addr, int len) +// OBSOLETE { +// OBSOLETE unsigned char buffer[2000]; +// OBSOLETE unsigned short checksum; +// OBSOLETE static int pkt_num = 0; +// OBSOLETE static unsigned long old_addr = -1; +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE while (1) +// OBSOLETE { +// OBSOLETE if (to_addr != old_addr) +// OBSOLETE { +// OBSOLETE buffer[0] = 0x1; /* Load command */ +// OBSOLETE buffer[1] = 0x1; /* Loading address */ +// OBSOLETE buffer[2] = to_addr >> 24; +// OBSOLETE buffer[3] = to_addr >> 16; +// OBSOLETE buffer[4] = to_addr >> 8; +// OBSOLETE buffer[5] = to_addr; +// OBSOLETE +// OBSOLETE checksum = 0; +// OBSOLETE for (i = 0; i < 6; i++) +// OBSOLETE checksum += buffer[i]; +// OBSOLETE checksum &= 0xff; +// OBSOLETE +// OBSOLETE send_udp_buf (udp_fd, buffer, 6); +// OBSOLETE i = recv_udp_buf (udp_fd, buffer, sizeof buffer, -1); +// OBSOLETE +// OBSOLETE if (i < 1) +// OBSOLETE error ("Got back short checksum for load addr."); +// OBSOLETE +// OBSOLETE if (checksum != buffer[0]) +// OBSOLETE error ("Got back bad checksum for load addr."); +// OBSOLETE +// OBSOLETE pkt_num = 0; /* Load addr resets packet seq # */ +// OBSOLETE old_addr = to_addr; +// OBSOLETE } +// OBSOLETE +// OBSOLETE bfd_get_section_contents (from_bfd, from_sec, buffer + 6, from_addr, +// OBSOLETE len); +// OBSOLETE +// OBSOLETE checksum = calc_checksum (buffer + 6, len); +// OBSOLETE +// OBSOLETE buffer[0] = 0x1; /* Load command */ +// OBSOLETE buffer[1] = 0x2; /* Loading data */ +// OBSOLETE buffer[2] = pkt_num >> 8; +// OBSOLETE buffer[3] = pkt_num; +// OBSOLETE buffer[4] = checksum >> 8; +// OBSOLETE buffer[5] = checksum; +// OBSOLETE +// OBSOLETE send_udp_buf (udp_fd, buffer, len + 6); +// OBSOLETE i = recv_udp_buf (udp_fd, buffer, sizeof buffer, 3); +// OBSOLETE +// OBSOLETE if (i == 0) +// OBSOLETE { +// OBSOLETE fprintf_unfiltered (gdb_stderr, "send_data: timeout sending %d bytes to address 0x%x retrying\n", len, to_addr); +// OBSOLETE continue; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (buffer[0] != 0xff) +// OBSOLETE error ("Got back bad response for load data."); +// OBSOLETE +// OBSOLETE old_addr += len; +// OBSOLETE pkt_num++; +// OBSOLETE +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE #endif /* HAVE_SOCKETS */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclite_download (char *filename, int from_tty) +// OBSOLETE { +// OBSOLETE if (!serial_flag) +// OBSOLETE #ifdef HAVE_SOCKETS +// OBSOLETE download (remote_target_name, filename, from_tty, sparclite_udp_write, +// OBSOLETE sparclite_udp_start); +// OBSOLETE #else +// OBSOLETE internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* sparclite_open should prevent this! */ +// OBSOLETE #endif +// OBSOLETE else +// OBSOLETE download (remote_target_name, filename, from_tty, sparclite_serial_write, +// OBSOLETE sparclite_serial_start); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Set up the sparclite target vector. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE init_sparclite_ops (void) +// OBSOLETE { +// OBSOLETE sparclite_ops.to_shortname = "sparclite"; +// OBSOLETE sparclite_ops.to_longname = "SPARClite download target"; +// OBSOLETE sparclite_ops.to_doc = "Download to a remote SPARClite target board via serial of UDP.\n\ +// OBSOLETE Specify the device it is connected to (e.g. /dev/ttya)."; +// OBSOLETE sparclite_ops.to_open = sparclite_open; +// OBSOLETE sparclite_ops.to_close = sparclite_close; +// OBSOLETE sparclite_ops.to_load = sparclite_download; +// OBSOLETE sparclite_ops.to_stratum = download_stratum; +// OBSOLETE sparclite_ops.to_magic = OPS_MAGIC; +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE _initialize_sparcl_tdep (void) +// OBSOLETE { +// OBSOLETE init_sparclite_ops (); +// OBSOLETE add_target (&sparclite_ops); +// OBSOLETE } diff --git a/gdb/sparclet-rom.c b/gdb/sparclet-rom.c index fa2ca1e..9247131 100644 --- a/gdb/sparclet-rom.c +++ b/gdb/sparclet-rom.c @@ -1,316 +1,316 @@ -/* Remote target glue for the SPARC Sparclet ROM monitor. - - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "srec.h" -#include "symtab.h" -#include "symfile.h" /* for generic_load */ -#include "regcache.h" -#include <time.h> - -extern void report_transfer_performance (unsigned long, time_t, time_t); - -static struct target_ops sparclet_ops; - -static void sparclet_open (char *args, int from_tty); - -/* This array of registers need to match the indexes used by GDB. - This exists because the various ROM monitors use different strings - than does GDB, and don't necessarily support all the registers - either. So, typing "info reg sp" becomes a "r30". */ - -/*PSR 0x00000080 impl ver icc AW LE EE EC EF PIL S PS ET CWP WIM - 0x0 0x0 0x0 0 0 0 0 0 0x0 1 0 0 0x00 0x2 - 0000010 - INS LOCALS OUTS GLOBALS - 0 0x00000000 0x00000000 0x00000000 0x00000000 - 1 0x00000000 0x00000000 0x00000000 0x00000000 - 2 0x00000000 0x00000000 0x00000000 0x00000000 - 3 0x00000000 0x00000000 0x00000000 0x00000000 - 4 0x00000000 0x00000000 0x00000000 0x00000000 - 5 0x00000000 0x00001000 0x00000000 0x00000000 - 6 0x00000000 0x00000000 0x123f0000 0x00000000 - 7 0x00000000 0x00000000 0x00000000 0x00000000 - pc: 0x12010000 0x00000000 unimp - npc: 0x12010004 0x00001000 unimp 0x1000 - tbr: 0x00000000 - y: 0x00000000 - */ -/* these correspond to the offsets from tm-* files from config directories */ - -/* is wim part of psr?? */ -/* monitor wants lower case */ -static char *sparclet_regnames[] = { - "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7", - - "", "", "", "", "", "", "", "", /* no FPU regs */ - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - /* no CPSR, FPSR */ - "y", "psr", "wim", "tbr", "pc", "npc", "", "", - - "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "", - - /* ASR15 ASR19 (don't display them) */ - "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22", -/* - "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7", - "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15", - "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23", - "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31", - "apsr", - */ -}; - - - -/* Function: sparclet_supply_register - Just returns with no action. - This function is required, because parse_register_dump (monitor.c) - expects to be able to call it. If we don't supply something, it will - call a null pointer and core-dump. Since this function does not - actually do anything, GDB will request the registers individually. */ - -static void -sparclet_supply_register (char *regname, int regnamelen, char *val, int vallen) -{ - return; -} - -static void -sparclet_load (struct serial *desc, char *file, int hashmark) -{ - bfd *abfd; - asection *s; - int i; - CORE_ADDR load_offset; - time_t start_time, end_time; - unsigned long data_count = 0; - - /* enable user to specify address for downloading as 2nd arg to load */ - - i = sscanf (file, "%*s 0x%lx", &load_offset); - if (i >= 1) - { - char *p; - - for (p = file; *p != '\000' && !isspace (*p); p++); - - *p = '\000'; - } - else - load_offset = 0; - - abfd = bfd_openr (file, 0); - if (!abfd) - { - printf_filtered ("Unable to open file %s\n", file); - return; - } - - if (bfd_check_format (abfd, bfd_object) == 0) - { - printf_filtered ("File is not an object file\n"); - return; - } - - start_time = time (NULL); - - for (s = abfd->sections; s; s = s->next) - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size; - bfd_vma vma; - - vma = bfd_get_section_vma (abfd, s) + load_offset; - section_size = bfd_section_size (abfd, s); - - data_count += section_size; - - printf_filtered ("%s\t: 0x%4x .. 0x%4x ", - bfd_get_section_name (abfd, s), vma, - vma + section_size); - gdb_flush (gdb_stdout); - - monitor_printf ("load c r %x %x\r", vma, section_size); - - monitor_expect ("load: loading ", NULL, 0); - monitor_expect ("\r", NULL, 0); - - for (i = 0; i < section_size; i += 2048) - { - int numbytes; - char buf[2048]; - - numbytes = min (sizeof buf, section_size - i); - - bfd_get_section_contents (abfd, s, buf, i, numbytes); - - serial_write (desc, buf, numbytes); - - if (hashmark) - { - putchar_unfiltered ('#'); - gdb_flush (gdb_stdout); - } - } /* Per-packet (or S-record) loop */ - - monitor_expect_prompt (NULL, 0); - - putchar_unfiltered ('\n'); - } /* Loadable sections */ - - monitor_printf ("reg pc %x\r", bfd_get_start_address (abfd)); - monitor_expect_prompt (NULL, 0); - monitor_printf ("reg npc %x\r", bfd_get_start_address (abfd) + 4); - monitor_expect_prompt (NULL, 0); - - monitor_printf ("run\r"); - - end_time = time (NULL); - - if (hashmark) - putchar_unfiltered ('\n'); - - report_transfer_performance (data_count, start_time, end_time); - - pop_target (); - push_remote_target (monitor_get_dev_name (), 1); - - throw_exception (RETURN_QUIT); -} - -/* Define the monitor command strings. Since these are passed directly - through to a printf style function, we may include formatting - strings. We also need a CR or LF on the end. */ - -/* need to pause the monitor for timing reasons, so slow it down */ - -static char *sparclet_inits[] = -{"\n\r\r\n", NULL}; - -static struct monitor_ops sparclet_cmds; - -static void -init_sparclet_cmds (void) -{ - sparclet_cmds.flags = MO_CLR_BREAK_USES_ADDR | - MO_HEX_PREFIX | - MO_NO_ECHO_ON_OPEN | - MO_NO_ECHO_ON_SETMEM | - MO_RUN_FIRST_TIME | - MO_GETMEM_READ_SINGLE; /* flags */ - sparclet_cmds.init = sparclet_inits; /* Init strings */ - sparclet_cmds.cont = "cont\r"; /* continue command */ - sparclet_cmds.step = "step\r"; /* single step */ - sparclet_cmds.stop = "\r"; /* break interrupts the program */ - sparclet_cmds.set_break = "+bp %x\r"; /* set a breakpoint */ - sparclet_cmds.clr_break = "-bp %x\r"; /* can't use "br" because only 2 hw bps are supported */ - sparclet_cmds.clr_all_break = "-bp %x\r"; /* clear a breakpoint */ - "-bp\r"; /* clear all breakpoints */ - sparclet_cmds.fill = "fill %x -n %x -v %x -b\r"; /* fill (start length val) */ - /* can't use "fi" because it takes words, not bytes */ - /* ex [addr] [-n count] [-b|-s|-l] default: ex cur -n 1 -b */ - sparclet_cmds.setmem.cmdb = "ex %x -b\r%x\rq\r"; /* setmem.cmdb (addr, value) */ - sparclet_cmds.setmem.cmdw = "ex %x -s\r%x\rq\r"; /* setmem.cmdw (addr, value) */ - sparclet_cmds.setmem.cmdl = "ex %x -l\r%x\rq\r"; /* setmem.cmdl (addr, value) */ - sparclet_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - sparclet_cmds.setmem.resp_delim = NULL; /*": " *//* setmem.resp_delim */ - sparclet_cmds.setmem.term = NULL; /*"? " *//* setmem.term */ - sparclet_cmds.setmem.term_cmd = NULL; /*"q\r" *//* setmem.term_cmd */ - /* since the parsing of multiple bytes is difficult due to - interspersed addresses, we'll only read 1 value at a time, - even tho these can handle a count */ - /* we can use -n to set count to read, but may have to parse? */ - sparclet_cmds.getmem.cmdb = "ex %x -n 1 -b\r"; /* getmem.cmdb (addr, #bytes) */ - sparclet_cmds.getmem.cmdw = "ex %x -n 1 -s\r"; /* getmem.cmdw (addr, #swords) */ - sparclet_cmds.getmem.cmdl = "ex %x -n 1 -l\r"; /* getmem.cmdl (addr, #words) */ - sparclet_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, #dwords) */ - sparclet_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - sparclet_cmds.getmem.term = NULL; /* getmem.term */ - sparclet_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ - sparclet_cmds.setreg.cmd = "reg %s 0x%x\r"; /* setreg.cmd (name, value) */ - sparclet_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - sparclet_cmds.setreg.term = NULL; /* setreg.term */ - sparclet_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ - sparclet_cmds.getreg.cmd = "reg %s\r"; /* getreg.cmd (name) */ - sparclet_cmds.getreg.resp_delim = " "; /* getreg.resp_delim */ - sparclet_cmds.getreg.term = NULL; /* getreg.term */ - sparclet_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ - sparclet_cmds.dump_registers = "reg\r"; /* dump_registers */ - sparclet_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */ - sparclet_cmds.supply_register = sparclet_supply_register; /* supply_register */ - sparclet_cmds.load_routine = sparclet_load; /* load_routine */ - sparclet_cmds.load = NULL; /* download command (srecs on console) */ - sparclet_cmds.loadresp = NULL; /* load response */ - sparclet_cmds.prompt = "monitor>"; /* monitor command prompt */ - /* yikes! gdb core dumps without this delimitor!! */ - sparclet_cmds.line_term = "\r"; /* end-of-command delimitor */ - sparclet_cmds.cmd_end = NULL; /* optional command terminator */ - sparclet_cmds.target = &sparclet_ops; /* target operations */ - sparclet_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - sparclet_cmds.regnames = sparclet_regnames; /* registers names */ - sparclet_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ -}; - -static void -sparclet_open (char *args, int from_tty) -{ - monitor_open (args, &sparclet_cmds, from_tty); -} - -void -_initialize_sparclet (void) -{ - int i; - init_sparclet_cmds (); - - for (i = 0; i < NUM_REGS; i++) - if (sparclet_regnames[i][0] == 'c' || - sparclet_regnames[i][0] == 'a') - sparclet_regnames[i] = 0; /* mon can't report c* or a* regs */ - - sparclet_regnames[0] = 0; /* mon won't report %G0 */ - - init_monitor_ops (&sparclet_ops); - sparclet_ops.to_shortname = "sparclet"; /* for the target command */ - sparclet_ops.to_longname = "SPARC Sparclet monitor"; - /* use SW breaks; target only supports 2 HW breakpoints */ - sparclet_ops.to_insert_breakpoint = memory_insert_breakpoint; - sparclet_ops.to_remove_breakpoint = memory_remove_breakpoint; - - sparclet_ops.to_doc = - "Use a board running the Sparclet debug monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - - sparclet_ops.to_open = sparclet_open; - add_target (&sparclet_ops); -} +// OBSOLETE /* Remote target glue for the SPARC Sparclet ROM monitor. +// OBSOLETE +// OBSOLETE Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free +// OBSOLETE Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE +// OBSOLETE #include "defs.h" +// OBSOLETE #include "gdbcore.h" +// OBSOLETE #include "target.h" +// OBSOLETE #include "monitor.h" +// OBSOLETE #include "serial.h" +// OBSOLETE #include "srec.h" +// OBSOLETE #include "symtab.h" +// OBSOLETE #include "symfile.h" /* for generic_load */ +// OBSOLETE #include "regcache.h" +// OBSOLETE #include <time.h> +// OBSOLETE +// OBSOLETE extern void report_transfer_performance (unsigned long, time_t, time_t); +// OBSOLETE +// OBSOLETE static struct target_ops sparclet_ops; +// OBSOLETE +// OBSOLETE static void sparclet_open (char *args, int from_tty); +// OBSOLETE +// OBSOLETE /* This array of registers need to match the indexes used by GDB. +// OBSOLETE This exists because the various ROM monitors use different strings +// OBSOLETE than does GDB, and don't necessarily support all the registers +// OBSOLETE either. So, typing "info reg sp" becomes a "r30". */ +// OBSOLETE +// OBSOLETE /*PSR 0x00000080 impl ver icc AW LE EE EC EF PIL S PS ET CWP WIM +// OBSOLETE 0x0 0x0 0x0 0 0 0 0 0 0x0 1 0 0 0x00 0x2 +// OBSOLETE 0000010 +// OBSOLETE INS LOCALS OUTS GLOBALS +// OBSOLETE 0 0x00000000 0x00000000 0x00000000 0x00000000 +// OBSOLETE 1 0x00000000 0x00000000 0x00000000 0x00000000 +// OBSOLETE 2 0x00000000 0x00000000 0x00000000 0x00000000 +// OBSOLETE 3 0x00000000 0x00000000 0x00000000 0x00000000 +// OBSOLETE 4 0x00000000 0x00000000 0x00000000 0x00000000 +// OBSOLETE 5 0x00000000 0x00001000 0x00000000 0x00000000 +// OBSOLETE 6 0x00000000 0x00000000 0x123f0000 0x00000000 +// OBSOLETE 7 0x00000000 0x00000000 0x00000000 0x00000000 +// OBSOLETE pc: 0x12010000 0x00000000 unimp +// OBSOLETE npc: 0x12010004 0x00001000 unimp 0x1000 +// OBSOLETE tbr: 0x00000000 +// OBSOLETE y: 0x00000000 +// OBSOLETE */ +// OBSOLETE /* these correspond to the offsets from tm-* files from config directories */ +// OBSOLETE +// OBSOLETE /* is wim part of psr?? */ +// OBSOLETE /* monitor wants lower case */ +// OBSOLETE static char *sparclet_regnames[] = { +// OBSOLETE "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", +// OBSOLETE "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", +// OBSOLETE "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", +// OBSOLETE "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7", +// OBSOLETE +// OBSOLETE "", "", "", "", "", "", "", "", /* no FPU regs */ +// OBSOLETE "", "", "", "", "", "", "", "", +// OBSOLETE "", "", "", "", "", "", "", "", +// OBSOLETE "", "", "", "", "", "", "", "", +// OBSOLETE /* no CPSR, FPSR */ +// OBSOLETE "y", "psr", "wim", "tbr", "pc", "npc", "", "", +// OBSOLETE +// OBSOLETE "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "", +// OBSOLETE +// OBSOLETE /* ASR15 ASR19 (don't display them) */ +// OBSOLETE "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22", +// OBSOLETE /* +// OBSOLETE "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7", +// OBSOLETE "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15", +// OBSOLETE "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23", +// OBSOLETE "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31", +// OBSOLETE "apsr", +// OBSOLETE */ +// OBSOLETE }; +// OBSOLETE +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: sparclet_supply_register +// OBSOLETE Just returns with no action. +// OBSOLETE This function is required, because parse_register_dump (monitor.c) +// OBSOLETE expects to be able to call it. If we don't supply something, it will +// OBSOLETE call a null pointer and core-dump. Since this function does not +// OBSOLETE actually do anything, GDB will request the registers individually. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclet_supply_register (char *regname, int regnamelen, char *val, int vallen) +// OBSOLETE { +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclet_load (struct serial *desc, char *file, int hashmark) +// OBSOLETE { +// OBSOLETE bfd *abfd; +// OBSOLETE asection *s; +// OBSOLETE int i; +// OBSOLETE CORE_ADDR load_offset; +// OBSOLETE time_t start_time, end_time; +// OBSOLETE unsigned long data_count = 0; +// OBSOLETE +// OBSOLETE /* enable user to specify address for downloading as 2nd arg to load */ +// OBSOLETE +// OBSOLETE i = sscanf (file, "%*s 0x%lx", &load_offset); +// OBSOLETE if (i >= 1) +// OBSOLETE { +// OBSOLETE char *p; +// OBSOLETE +// OBSOLETE for (p = file; *p != '\000' && !isspace (*p); p++); +// OBSOLETE +// OBSOLETE *p = '\000'; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE load_offset = 0; +// OBSOLETE +// OBSOLETE abfd = bfd_openr (file, 0); +// OBSOLETE if (!abfd) +// OBSOLETE { +// OBSOLETE printf_filtered ("Unable to open file %s\n", file); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE if (bfd_check_format (abfd, bfd_object) == 0) +// OBSOLETE { +// OBSOLETE printf_filtered ("File is not an object file\n"); +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE +// OBSOLETE start_time = time (NULL); +// OBSOLETE +// OBSOLETE for (s = abfd->sections; s; s = s->next) +// OBSOLETE if (s->flags & SEC_LOAD) +// OBSOLETE { +// OBSOLETE bfd_size_type section_size; +// OBSOLETE bfd_vma vma; +// OBSOLETE +// OBSOLETE vma = bfd_get_section_vma (abfd, s) + load_offset; +// OBSOLETE section_size = bfd_section_size (abfd, s); +// OBSOLETE +// OBSOLETE data_count += section_size; +// OBSOLETE +// OBSOLETE printf_filtered ("%s\t: 0x%4x .. 0x%4x ", +// OBSOLETE bfd_get_section_name (abfd, s), vma, +// OBSOLETE vma + section_size); +// OBSOLETE gdb_flush (gdb_stdout); +// OBSOLETE +// OBSOLETE monitor_printf ("load c r %x %x\r", vma, section_size); +// OBSOLETE +// OBSOLETE monitor_expect ("load: loading ", NULL, 0); +// OBSOLETE monitor_expect ("\r", NULL, 0); +// OBSOLETE +// OBSOLETE for (i = 0; i < section_size; i += 2048) +// OBSOLETE { +// OBSOLETE int numbytes; +// OBSOLETE char buf[2048]; +// OBSOLETE +// OBSOLETE numbytes = min (sizeof buf, section_size - i); +// OBSOLETE +// OBSOLETE bfd_get_section_contents (abfd, s, buf, i, numbytes); +// OBSOLETE +// OBSOLETE serial_write (desc, buf, numbytes); +// OBSOLETE +// OBSOLETE if (hashmark) +// OBSOLETE { +// OBSOLETE putchar_unfiltered ('#'); +// OBSOLETE gdb_flush (gdb_stdout); +// OBSOLETE } +// OBSOLETE } /* Per-packet (or S-record) loop */ +// OBSOLETE +// OBSOLETE monitor_expect_prompt (NULL, 0); +// OBSOLETE +// OBSOLETE putchar_unfiltered ('\n'); +// OBSOLETE } /* Loadable sections */ +// OBSOLETE +// OBSOLETE monitor_printf ("reg pc %x\r", bfd_get_start_address (abfd)); +// OBSOLETE monitor_expect_prompt (NULL, 0); +// OBSOLETE monitor_printf ("reg npc %x\r", bfd_get_start_address (abfd) + 4); +// OBSOLETE monitor_expect_prompt (NULL, 0); +// OBSOLETE +// OBSOLETE monitor_printf ("run\r"); +// OBSOLETE +// OBSOLETE end_time = time (NULL); +// OBSOLETE +// OBSOLETE if (hashmark) +// OBSOLETE putchar_unfiltered ('\n'); +// OBSOLETE +// OBSOLETE report_transfer_performance (data_count, start_time, end_time); +// OBSOLETE +// OBSOLETE pop_target (); +// OBSOLETE push_remote_target (monitor_get_dev_name (), 1); +// OBSOLETE +// OBSOLETE throw_exception (RETURN_QUIT); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Define the monitor command strings. Since these are passed directly +// OBSOLETE through to a printf style function, we may include formatting +// OBSOLETE strings. We also need a CR or LF on the end. */ +// OBSOLETE +// OBSOLETE /* need to pause the monitor for timing reasons, so slow it down */ +// OBSOLETE +// OBSOLETE static char *sparclet_inits[] = +// OBSOLETE {"\n\r\r\n", NULL}; +// OBSOLETE +// OBSOLETE static struct monitor_ops sparclet_cmds; +// OBSOLETE +// OBSOLETE static void +// OBSOLETE init_sparclet_cmds (void) +// OBSOLETE { +// OBSOLETE sparclet_cmds.flags = MO_CLR_BREAK_USES_ADDR | +// OBSOLETE MO_HEX_PREFIX | +// OBSOLETE MO_NO_ECHO_ON_OPEN | +// OBSOLETE MO_NO_ECHO_ON_SETMEM | +// OBSOLETE MO_RUN_FIRST_TIME | +// OBSOLETE MO_GETMEM_READ_SINGLE; /* flags */ +// OBSOLETE sparclet_cmds.init = sparclet_inits; /* Init strings */ +// OBSOLETE sparclet_cmds.cont = "cont\r"; /* continue command */ +// OBSOLETE sparclet_cmds.step = "step\r"; /* single step */ +// OBSOLETE sparclet_cmds.stop = "\r"; /* break interrupts the program */ +// OBSOLETE sparclet_cmds.set_break = "+bp %x\r"; /* set a breakpoint */ +// OBSOLETE sparclet_cmds.clr_break = "-bp %x\r"; /* can't use "br" because only 2 hw bps are supported */ +// OBSOLETE sparclet_cmds.clr_all_break = "-bp %x\r"; /* clear a breakpoint */ +// OBSOLETE "-bp\r"; /* clear all breakpoints */ +// OBSOLETE sparclet_cmds.fill = "fill %x -n %x -v %x -b\r"; /* fill (start length val) */ +// OBSOLETE /* can't use "fi" because it takes words, not bytes */ +// OBSOLETE /* ex [addr] [-n count] [-b|-s|-l] default: ex cur -n 1 -b */ +// OBSOLETE sparclet_cmds.setmem.cmdb = "ex %x -b\r%x\rq\r"; /* setmem.cmdb (addr, value) */ +// OBSOLETE sparclet_cmds.setmem.cmdw = "ex %x -s\r%x\rq\r"; /* setmem.cmdw (addr, value) */ +// OBSOLETE sparclet_cmds.setmem.cmdl = "ex %x -l\r%x\rq\r"; /* setmem.cmdl (addr, value) */ +// OBSOLETE sparclet_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ +// OBSOLETE sparclet_cmds.setmem.resp_delim = NULL; /*": " *//* setmem.resp_delim */ +// OBSOLETE sparclet_cmds.setmem.term = NULL; /*"? " *//* setmem.term */ +// OBSOLETE sparclet_cmds.setmem.term_cmd = NULL; /*"q\r" *//* setmem.term_cmd */ +// OBSOLETE /* since the parsing of multiple bytes is difficult due to +// OBSOLETE interspersed addresses, we'll only read 1 value at a time, +// OBSOLETE even tho these can handle a count */ +// OBSOLETE /* we can use -n to set count to read, but may have to parse? */ +// OBSOLETE sparclet_cmds.getmem.cmdb = "ex %x -n 1 -b\r"; /* getmem.cmdb (addr, #bytes) */ +// OBSOLETE sparclet_cmds.getmem.cmdw = "ex %x -n 1 -s\r"; /* getmem.cmdw (addr, #swords) */ +// OBSOLETE sparclet_cmds.getmem.cmdl = "ex %x -n 1 -l\r"; /* getmem.cmdl (addr, #words) */ +// OBSOLETE sparclet_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, #dwords) */ +// OBSOLETE sparclet_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ +// OBSOLETE sparclet_cmds.getmem.term = NULL; /* getmem.term */ +// OBSOLETE sparclet_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */ +// OBSOLETE sparclet_cmds.setreg.cmd = "reg %s 0x%x\r"; /* setreg.cmd (name, value) */ +// OBSOLETE sparclet_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ +// OBSOLETE sparclet_cmds.setreg.term = NULL; /* setreg.term */ +// OBSOLETE sparclet_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */ +// OBSOLETE sparclet_cmds.getreg.cmd = "reg %s\r"; /* getreg.cmd (name) */ +// OBSOLETE sparclet_cmds.getreg.resp_delim = " "; /* getreg.resp_delim */ +// OBSOLETE sparclet_cmds.getreg.term = NULL; /* getreg.term */ +// OBSOLETE sparclet_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */ +// OBSOLETE sparclet_cmds.dump_registers = "reg\r"; /* dump_registers */ +// OBSOLETE sparclet_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */ +// OBSOLETE sparclet_cmds.supply_register = sparclet_supply_register; /* supply_register */ +// OBSOLETE sparclet_cmds.load_routine = sparclet_load; /* load_routine */ +// OBSOLETE sparclet_cmds.load = NULL; /* download command (srecs on console) */ +// OBSOLETE sparclet_cmds.loadresp = NULL; /* load response */ +// OBSOLETE sparclet_cmds.prompt = "monitor>"; /* monitor command prompt */ +// OBSOLETE /* yikes! gdb core dumps without this delimitor!! */ +// OBSOLETE sparclet_cmds.line_term = "\r"; /* end-of-command delimitor */ +// OBSOLETE sparclet_cmds.cmd_end = NULL; /* optional command terminator */ +// OBSOLETE sparclet_cmds.target = &sparclet_ops; /* target operations */ +// OBSOLETE sparclet_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ +// OBSOLETE sparclet_cmds.regnames = sparclet_regnames; /* registers names */ +// OBSOLETE sparclet_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ +// OBSOLETE }; +// OBSOLETE +// OBSOLETE static void +// OBSOLETE sparclet_open (char *args, int from_tty) +// OBSOLETE { +// OBSOLETE monitor_open (args, &sparclet_cmds, from_tty); +// OBSOLETE } +// OBSOLETE +// OBSOLETE void +// OBSOLETE _initialize_sparclet (void) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE init_sparclet_cmds (); +// OBSOLETE +// OBSOLETE for (i = 0; i < NUM_REGS; i++) +// OBSOLETE if (sparclet_regnames[i][0] == 'c' || +// OBSOLETE sparclet_regnames[i][0] == 'a') +// OBSOLETE sparclet_regnames[i] = 0; /* mon can't report c* or a* regs */ +// OBSOLETE +// OBSOLETE sparclet_regnames[0] = 0; /* mon won't report %G0 */ +// OBSOLETE +// OBSOLETE init_monitor_ops (&sparclet_ops); +// OBSOLETE sparclet_ops.to_shortname = "sparclet"; /* for the target command */ +// OBSOLETE sparclet_ops.to_longname = "SPARC Sparclet monitor"; +// OBSOLETE /* use SW breaks; target only supports 2 HW breakpoints */ +// OBSOLETE sparclet_ops.to_insert_breakpoint = memory_insert_breakpoint; +// OBSOLETE sparclet_ops.to_remove_breakpoint = memory_remove_breakpoint; +// OBSOLETE +// OBSOLETE sparclet_ops.to_doc = +// OBSOLETE "Use a board running the Sparclet debug monitor.\n\ +// OBSOLETE Specify the serial device it is connected to (e.g. /dev/ttya)."; +// OBSOLETE +// OBSOLETE sparclet_ops.to_open = sparclet_open; +// OBSOLETE add_target (&sparclet_ops); +// OBSOLETE } diff --git a/gdb/sparclet-stub.c b/gdb/sparclet-stub.c index f593df7..88740f2 100644 --- a/gdb/sparclet-stub.c +++ b/gdb/sparclet-stub.c @@ -1,1167 +1,1167 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for SPARC by Stu Grossman, Cygnus Support. - * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware - * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support. - * - * This code has been extensively tested on the Fujitsu SPARClite demo board. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * P set the value of a single CPU register OK or 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 <string.h> -#include <signal.h> - -/************************************************************************ - * - * external low-level support routines - */ - -extern void putDebugChar(); /* write a single character */ -extern int getDebugChar(); /* read and return a single char */ - -/************************************************************************/ -/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ -/* at least NUMREGBYTES*2 are needed for register packets */ -#define BUFMAX 2048 - -static int initialized = 0; /* !0 means we've been initialized */ -static int remote_debug = 0; /* turn on verbose debugging */ - -extern void breakinst(); -void _cprint(); -static void hw_breakpoint(); -static void set_mem_fault_trap(); -static void get_in_break_mode(); -static unsigned char *mem2hex(); - -static const char hexchars[]="0123456789abcdef"; - -#define NUMREGS 121 - -static unsigned long saved_stack_pointer; - -/* Number of bytes of registers. */ -#define NUMREGBYTES (NUMREGS * 4) -enum regnames { G0, G1, G2, G3, G4, G5, G6, G7, - O0, O1, O2, O3, O4, O5, SP, O7, - L0, L1, L2, L3, L4, L5, L6, L7, - I0, I1, I2, I3, I4, I5, FP, I7, - - F0, F1, F2, F3, F4, F5, F6, F7, - F8, F9, F10, F11, F12, F13, F14, F15, - F16, F17, F18, F19, F20, F21, F22, F23, - F24, F25, F26, F27, F28, F29, F30, F31, - - Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR, - CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR, UNUSED1, - - ASR1, ASR15, ASR17, ASR18, ASR19, ASR20, ASR21, ASR22, - /* the following not actually implemented */ - AWR0, AWR1, AWR2, AWR3, AWR4, AWR5, AWR6, AWR7, - AWR8, AWR9, AWR10, AWR11, AWR12, AWR13, AWR14, AWR15, - AWR16, AWR17, AWR18, AWR19, AWR20, AWR21, AWR22, AWR23, - AWR24, AWR25, AWR26, AWR27, AWR28, AWR29, AWR30, AWR31, - APSR -}; - -/*************************** ASSEMBLY CODE MACROS *************************/ -/* */ - -extern void trap_low(); - -asm(" - .reserve trapstack, 1000 * 4, \"bss\", 8 - - .data - .align 4 - -in_trap_handler: - .word 0 - - .text - .align 4 - -! This function is called when any SPARC trap (except window overflow or -! underflow) occurs. It makes sure that the invalid register window is still -! available before jumping into C code. It will also restore the world if you -! return from handle_exception. -! -! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly. - - .globl _trap_low -_trap_low: - mov %psr, %l0 - mov %wim, %l3 - - srl %l3, %l0, %l4 ! wim >> cwp - and %l4, 0xff, %l4 ! Mask off windows 28, 29 - cmp %l4, 1 - bne window_fine ! Branch if not in the invalid window - nop - -! Handle window overflow - - mov %g1, %l4 ! Save g1, we use it to hold the wim - srl %l3, 1, %g1 ! Rotate wim right - and %g1, 0xff, %g1 ! Mask off windows 28, 29 - tst %g1 - bg good_wim ! Branch if new wim is non-zero - nop - -! At this point, we need to bring a 1 into the high order bit of the wim. -! Since we don't want to make any assumptions about the number of register -! windows, we figure it out dynamically so as to setup the wim correctly. - - ! The normal way doesn't work on the sparclet as register windows - ! 28 and 29 are special purpose windows. - !not %g1 ! Fill g1 with ones - !mov %g1, %wim ! Fill the wim with ones - !nop - !nop - !nop - !mov %wim, %g1 ! Read back the wim - !inc %g1 ! Now g1 has 1 just to left of wim - !srl %g1, 1, %g1 ! Now put 1 at top of wim - - mov 0x80, %g1 ! Hack for sparclet - - ! This doesn't work on the sparclet. - !mov %g0, %wim ! Clear wim so that subsequent save - ! won't trap - andn %l3, 0xff, %l5 ! Clear wim but not windows 28, 29 - mov %l5, %wim - nop - nop - nop - -good_wim: - save %g0, %g0, %g0 ! Slip into next window - mov %g1, %wim ! Install the new wim - - std %l0, [%sp + 0 * 4] ! save L & I registers - std %l2, [%sp + 2 * 4] - std %l4, [%sp + 4 * 4] - std %l6, [%sp + 6 * 4] - - std %i0, [%sp + 8 * 4] - std %i2, [%sp + 10 * 4] - std %i4, [%sp + 12 * 4] - std %i6, [%sp + 14 * 4] - - restore ! Go back to trap window. - mov %l4, %g1 ! Restore %g1 - -window_fine: - sethi %hi(in_trap_handler), %l4 - ld [%lo(in_trap_handler) + %l4], %l5 - tst %l5 - bg recursive_trap - inc %l5 - - set trapstack+1000*4, %sp ! Switch to trap stack - -recursive_trap: - st %l5, [%lo(in_trap_handler) + %l4] - sub %sp,(16+1+6+1+88)*4,%sp ! Make room for input & locals - ! + hidden arg + arg spill - ! + doubleword alignment - ! + registers[121] - - std %g0, [%sp + (24 + 0) * 4] ! registers[Gx] - std %g2, [%sp + (24 + 2) * 4] - std %g4, [%sp + (24 + 4) * 4] - std %g6, [%sp + (24 + 6) * 4] - - std %i0, [%sp + (24 + 8) * 4] ! registers[Ox] - std %i2, [%sp + (24 + 10) * 4] - std %i4, [%sp + (24 + 12) * 4] - std %i6, [%sp + (24 + 14) * 4] - - ! FP regs (sparclet doesn't have fpu) - - mov %y, %l4 - mov %tbr, %l5 - st %l4, [%sp + (24 + 64) * 4] ! Y - st %l0, [%sp + (24 + 65) * 4] ! PSR - st %l3, [%sp + (24 + 66) * 4] ! WIM - st %l5, [%sp + (24 + 67) * 4] ! TBR - st %l1, [%sp + (24 + 68) * 4] ! PC - st %l2, [%sp + (24 + 69) * 4] ! NPC - ! CPSR and FPSR not impl - or %l0, 0xf20, %l4 - mov %l4, %psr ! Turn on traps, disable interrupts - nop - nop - nop - -! Save coprocessor state. -! See SK/demo/hdlc_demo/ldc_swap_context.S. - - mov %psr, %l0 - sethi %hi(0x2000), %l5 ! EC bit in PSR - or %l5, %l0, %l5 - mov %l5, %psr ! enable coprocessor - nop ! 3 nops after write to %psr (needed?) - nop - nop - crdcxt %ccsr, %l1 ! capture CCSR - mov 0x6, %l2 - cwrcxt %l2, %ccsr ! set CCP state machine for CCFR - crdcxt %ccfr, %l2 ! capture CCOR - cwrcxt %l2, %ccfr ! tickle CCFR - crdcxt %ccfr, %l3 ! capture CCOBR - cwrcxt %l3, %ccfr ! tickle CCFR - crdcxt %ccfr, %l4 ! capture CCIBR - cwrcxt %l4, %ccfr ! tickle CCFR - crdcxt %ccfr, %l5 ! capture CCIR - cwrcxt %l5, %ccfr ! tickle CCFR - crdcxt %ccpr, %l6 ! capture CCPR - crdcxt %cccrcr, %l7 ! capture CCCRCR - st %l1, [%sp + (24 + 72) * 4] ! save CCSR - st %l2, [%sp + (24 + 75) * 4] ! save CCOR - st %l3, [%sp + (24 + 76) * 4] ! save CCOBR - st %l4, [%sp + (24 + 77) * 4] ! save CCIBR - st %l5, [%sp + (24 + 78) * 4] ! save CCIR - st %l6, [%sp + (24 + 73) * 4] ! save CCPR - st %l7, [%sp + (24 + 74) * 4] ! save CCCRCR - mov %l0, %psr ! restore original PSR - nop ! 3 nops after write to %psr (needed?) - nop - nop - -! End of saving coprocessor state. -! Save asr regs - -! Part of this is silly -- we should not display ASR15 or ASR19 at all. - - sethi %hi(0x01000000), %l6 - st %l6, [%sp + (24 + 81) * 4] ! ASR15 == NOP - sethi %hi(0xdeadc0de), %l6 - or %l6, %lo(0xdeadc0de), %l6 - st %l6, [%sp + (24 + 84) * 4] ! ASR19 == DEADC0DE - - rd %asr1, %l4 - st %l4, [%sp + (24 + 80) * 4] -! rd %asr15, %l4 ! must not read ASR15 -! st %l4, [%sp + (24 + 81) * 4] ! (illegal instr trap) - rd %asr17, %l4 - st %l4, [%sp + (24 + 82) * 4] - rd %asr18, %l4 - st %l4, [%sp + (24 + 83) * 4] -! rd %asr19, %l4 ! must not read asr19 -! st %l4, [%sp + (24 + 84) * 4] ! (halts the CPU) - rd %asr20, %l4 - st %l4, [%sp + (24 + 85) * 4] - rd %asr21, %l4 - st %l4, [%sp + (24 + 86) * 4] - rd %asr22, %l4 - st %l4, [%sp + (24 + 87) * 4] - -! End of saving asr regs - - call _handle_exception - add %sp, 24 * 4, %o0 ! Pass address of registers - -! Reload all of the registers that aren't on the stack - - ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx] - ldd [%sp + (24 + 2) * 4], %g2 - ldd [%sp + (24 + 4) * 4], %g4 - ldd [%sp + (24 + 6) * 4], %g6 - - ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox] - ldd [%sp + (24 + 10) * 4], %i2 - ldd [%sp + (24 + 12) * 4], %i4 - ldd [%sp + (24 + 14) * 4], %i6 - - ! FP regs (sparclet doesn't have fpu) - -! Update the coprocessor registers. -! See SK/demo/hdlc_demo/ldc_swap_context.S. - - mov %psr, %l0 - sethi %hi(0x2000), %l5 ! EC bit in PSR - or %l5, %l0, %l5 - mov %l5, %psr ! enable coprocessor - nop ! 3 nops after write to %psr (needed?) - nop - nop - - mov 0x6, %l2 - cwrcxt %l2, %ccsr ! set CCP state machine for CCFR - - ld [%sp + (24 + 72) * 4], %l1 ! saved CCSR - ld [%sp + (24 + 75) * 4], %l2 ! saved CCOR - ld [%sp + (24 + 76) * 4], %l3 ! saved CCOBR - ld [%sp + (24 + 77) * 4], %l4 ! saved CCIBR - ld [%sp + (24 + 78) * 4], %l5 ! saved CCIR - ld [%sp + (24 + 73) * 4], %l6 ! saved CCPR - ld [%sp + (24 + 74) * 4], %l7 ! saved CCCRCR - - cwrcxt %l2, %ccfr ! restore CCOR - cwrcxt %l3, %ccfr ! restore CCOBR - cwrcxt %l4, %ccfr ! restore CCIBR - cwrcxt %l5, %ccfr ! restore CCIR - cwrcxt %l6, %ccpr ! restore CCPR - cwrcxt %l7, %cccrcr ! restore CCCRCR - cwrcxt %l1, %ccsr ! restore CCSR - - mov %l0, %psr ! restore PSR - nop ! 3 nops after write to %psr (needed?) - nop - nop - -! End of coprocessor handling stuff. -! Update asr regs - - ld [%sp + (24 + 80) * 4], %l4 - wr %l4, %asr1 -! ld [%sp + (24 + 81) * 4], %l4 ! can't write asr15 -! wr %l4, %asr15 - ld [%sp + (24 + 82) * 4], %l4 - wr %l4, %asr17 - ld [%sp + (24 + 83) * 4], %l4 - wr %l4, %asr18 -! ld [%sp + (24 + 84) * 4], %l4 ! can't write asr19 -! wr %l4, %asr19 -! ld [%sp + (24 + 85) * 4], %l4 ! can't write asr20 -! wr %l4, %asr20 -! ld [%sp + (24 + 86) * 4], %l4 ! can't write asr21 -! wr %l4, %asr21 - ld [%sp + (24 + 87) * 4], %l4 - wr %l4, %asr22 - -! End of restoring asr regs - - - ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR - ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC - - restore ! Ensure that previous window is valid - save %g0, %g0, %g0 ! by causing a window_underflow trap - - mov %l0, %y - mov %l1, %psr ! Make sure that traps are disabled - ! for rett - nop ! 3 nops after write to %psr (needed?) - nop - nop - - sethi %hi(in_trap_handler), %l4 - ld [%lo(in_trap_handler) + %l4], %l5 - dec %l5 - st %l5, [%lo(in_trap_handler) + %l4] - - jmpl %l2, %g0 ! Restore old PC - rett %l3 ! Restore old nPC -"); - -/* Convert ch from a hex digit to an int */ - -static int -hex (unsigned char ch) -{ - if (ch >= 'a' && ch <= 'f') - return ch-'a'+10; - if (ch >= '0' && ch <= '9') - return ch-'0'; - if (ch >= 'A' && ch <= 'F') - return ch-'A'+10; - return -1; -} - -static char remcomInBuffer[BUFMAX]; -static char remcomOutBuffer[BUFMAX]; - -/* scan for the sequence $<data>#<checksum> */ - -unsigned char * -getpacket (void) -{ - unsigned char *buffer = &remcomInBuffer[0]; - unsigned char checksum; - unsigned char xmitcsum; - int count; - char ch; - - while (1) - { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar ()) != '$') - ; - -retry: - checksum = 0; - xmitcsum = -1; - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) - { - ch = getDebugChar (); - if (ch == '$') - goto retry; - if (ch == '#') - break; - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') - { - ch = getDebugChar (); - xmitcsum = hex (ch) << 4; - ch = getDebugChar (); - xmitcsum += hex (ch); - - if (checksum != xmitcsum) - { - putDebugChar ('-'); /* failed checksum */ - } - else - { - putDebugChar ('+'); /* successful transfer */ - - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') - { - putDebugChar (buffer[0]); - putDebugChar (buffer[1]); - - return &buffer[3]; - } - - return &buffer[0]; - } - } - } -} - -/* send the packet in buffer. */ - -static void -putpacket (unsigned char *buffer) -{ - unsigned char checksum; - int count; - unsigned char ch; - - /* $<packet info>#<checksum>. */ - do - { - putDebugChar('$'); - checksum = 0; - count = 0; - - while (ch = buffer[count]) - { - putDebugChar(ch); - checksum += ch; - count += 1; - } - - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum & 0xf]); - - } - while (getDebugChar() != '+'); -} - -/* Indicate to caller of mem2hex or hex2mem that there has been an - error. */ -static volatile int mem_err = 0; - -/* Convert the memory pointed to by mem into hex, placing result in buf. - * Return a pointer to the last char put in buf (null), in case of mem fault, - * return 0. - * If MAY_FAULT is non-zero, then we will handle memory faults by returning - * a 0, else treat a fault like any other fault in the stub. - */ - -static unsigned char * -mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault) -{ - unsigned char ch; - - set_mem_fault_trap(may_fault); - - while (count-- > 0) - { - ch = *mem++; - if (mem_err) - return 0; - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch & 0xf]; - } - - *buf = 0; - - set_mem_fault_trap(0); - - return buf; -} - -/* convert the hex array pointed to by buf into binary to be placed in mem - * return a pointer to the character AFTER the last byte written */ - -static char * -hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) -{ - int i; - unsigned char ch; - - set_mem_fault_trap(may_fault); - - for (i=0; i<count; i++) - { - ch = hex(*buf++) << 4; - ch |= hex(*buf++); - *mem++ = ch; - if (mem_err) - return 0; - } - - set_mem_fault_trap(0); - - return mem; -} - -/* This table contains the mapping between SPARC hardware trap types, and - signals, which are primarily what GDB understands. It also indicates - which hardware traps we need to commandeer when initializing the stub. */ - -static struct hard_trap_info -{ - unsigned char tt; /* Trap type code for SPARClite */ - unsigned char signo; /* Signal that we map this trap into */ -} hard_trap_info[] = { - {1, SIGSEGV}, /* instruction access exception */ - {0x3b, SIGSEGV}, /* instruction access error */ - {2, SIGILL}, /* illegal instruction */ - {3, SIGILL}, /* privileged instruction */ - {4, SIGEMT}, /* fp disabled */ - {0x24, SIGEMT}, /* cp disabled */ - {7, SIGBUS}, /* mem address not aligned */ - {0x29, SIGSEGV}, /* data access exception */ - {10, SIGEMT}, /* tag overflow */ - {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */ - {0, 0} /* Must be last */ -}; - -/* Set up exception handlers for tracing and breakpoints */ - -void -set_debug_traps (void) -{ - struct hard_trap_info *ht; - - for (ht = hard_trap_info; ht->tt && ht->signo; ht++) - exceptionHandler(ht->tt, trap_low); - - initialized = 1; -} - -asm (" -! Trap handler for memory errors. This just sets mem_err to be non-zero. It -! assumes that %l1 is non-zero. This should be safe, as it is doubtful that -! 0 would ever contain code that could mem fault. This routine will skip -! past the faulting instruction after setting mem_err. - - .text - .align 4 - -_fltr_set_mem_err: - sethi %hi(_mem_err), %l0 - st %l1, [%l0 + %lo(_mem_err)] - jmpl %l2, %g0 - rett %l2+4 -"); - -static void -set_mem_fault_trap (int enable) -{ - extern void fltr_set_mem_err(); - mem_err = 0; - - if (enable) - exceptionHandler(0x29, fltr_set_mem_err); - else - exceptionHandler(0x29, trap_low); -} - -asm (" - .text - .align 4 - -_dummy_hw_breakpoint: - jmpl %l2, %g0 - rett %l2+4 - nop - nop -"); - -static void -set_hw_breakpoint_trap (int enable) -{ - extern void dummy_hw_breakpoint(); - - if (enable) - exceptionHandler(255, dummy_hw_breakpoint); - else - exceptionHandler(255, trap_low); -} - -static void -get_in_break_mode (void) -{ -#if 0 - int x; - mesg("get_in_break_mode, sp = "); - phex(&x); -#endif - set_hw_breakpoint_trap(1); - - asm(" - sethi %hi(0xff10), %l4 - or %l4, %lo(0xff10), %l4 - sta %g0, [%l4]0x1 - nop - nop - nop - "); - - set_hw_breakpoint_trap(0); -} - -/* Convert the SPARC hardware trap type code to a unix signal number. */ - -static int -computeSignal (int tt) -{ - struct hard_trap_info *ht; - - for (ht = hard_trap_info; ht->tt && ht->signo; ht++) - if (ht->tt == tt) - return ht->signo; - - return SIGHUP; /* default for things we don't know about */ -} - -/* - * While we find nice hex chars, build an int. - * Return number of chars processed. - */ - -static int -hexToInt(char **ptr, int *intValue) -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - - while (**ptr) - { - hexValue = hex(**ptr); - if (hexValue < 0) - break; - - *intValue = (*intValue << 4) | hexValue; - numChars ++; - - (*ptr)++; - } - - return (numChars); -} - -/* - * This function does all command procesing for interfacing to gdb. It - * returns 1 if you should skip the instruction at the trap address, 0 - * otherwise. - */ - -static void -handle_exception (unsigned long *registers) -{ - int tt; /* Trap type */ - int sigval; - int addr; - int length; - char *ptr; - unsigned long *sp; - unsigned long dsr; - -/* First, we must force all of the windows to be spilled out */ - - asm(" - ! Ugh. sparclet has broken save - !save %sp, -64, %sp - save - add %fp,-64,%sp - !save %sp, -64, %sp - save - add %fp,-64,%sp - !save %sp, -64, %sp - save - add %fp,-64,%sp - !save %sp, -64, %sp - save - add %fp,-64,%sp - !save %sp, -64, %sp - save - add %fp,-64,%sp - !save %sp, -64, %sp - save - add %fp,-64,%sp - !save %sp, -64, %sp - save - add %fp,-64,%sp - !save %sp, -64, %sp - save - add %fp,-64,%sp - restore - restore - restore - restore - restore - restore - restore - restore -"); - - if (registers[PC] == (unsigned long)breakinst) - { - registers[PC] = registers[NPC]; - registers[NPC] += 4; - } - sp = (unsigned long *)registers[SP]; - - tt = (registers[TBR] >> 4) & 0xff; - - /* reply to host that an exception has occurred */ - sigval = computeSignal(tt); - ptr = remcomOutBuffer; - - *ptr++ = 'T'; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[FP >> 4]; - *ptr++ = hexchars[FP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */ - *ptr++ = ';'; - - *ptr++ = hexchars[SP >> 4]; - *ptr++ = hexchars[SP & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)&sp, ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[NPC >> 4]; - *ptr++ = hexchars[NPC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[NPC], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[O7 >> 4]; - *ptr++ = hexchars[O7 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((char *)®isters[O7], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = 0; - - putpacket(remcomOutBuffer); - - while (1) - { - remcomOutBuffer[0] = 0; - - ptr = getpacket(); - switch (*ptr++) - { - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval & 0xf]; - remcomOutBuffer[3] = 0; - break; - - case 'd': - remote_debug = !(remote_debug); /* toggle debug flag */ - break; - - case 'g': /* return the value of the CPU registers */ - { - ptr = remcomOutBuffer; - ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */ - ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */ - memset(ptr, '0', 32 * 8); /* Floating point */ - ptr = mem2hex((char *)®isters[Y], - ptr + 32 * 4 * 2, - 8 * 4, - 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ - ptr = mem2hex((char *)®isters[CCSR], - ptr, - 8 * 4, - 0); /* CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR */ - ptr = mem2hex((char *)®isters[ASR1], - ptr, - 8 * 4, - 0); /* ASR1,ASR15,ASR17,ASR18,ASR19,ASR20,ASR21,ASR22 */ -#if 0 /* not implemented */ - ptr = mem2hex((char *) ®isters[AWR0], - ptr, - 32 * 4, - 0); /* Alternate Window Registers */ -#endif - } - break; - - case 'G': /* set value of all the CPU registers - return OK */ - case 'P': /* set value of one CPU register - return OK */ - { - unsigned long *newsp, psr; - - psr = registers[PSR]; - - if (ptr[-1] == 'P') /* do a single register */ - { - int regno; - - if (hexToInt (&ptr, ®no) - && *ptr++ == '=') - if (regno >= L0 && regno <= I7) - hex2mem (ptr, sp + regno - L0, 4, 0); - else - hex2mem (ptr, (char *)®isters[regno], 4, 0); - else - { - strcpy (remcomOutBuffer, "E01"); - break; - } - } - else - { - hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */ - hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */ - hex2mem(ptr + 64 * 4 * 2, (char *)®isters[Y], - 8 * 4, 0); /* Y,PSR,WIM,TBR,PC,NPC,FPSR,CPSR */ - hex2mem(ptr + 72 * 4 * 2, (char *)®isters[CCSR], - 8 * 4, 0); /* CCSR,CCPR,CCCRCR,CCOR,CCOBR,CCIBR,CCIR */ - hex2mem(ptr + 80 * 4 * 2, (char *)®isters[ASR1], - 8 * 4, 0); /* ASR1 ... ASR22 */ -#if 0 /* not implemented */ - hex2mem(ptr + 88 * 4 * 2, (char *)®isters[AWR0], - 8 * 4, 0); /* Alternate Window Registers */ -#endif - } - /* See if the stack pointer has moved. If so, then copy the saved - locals and ins to the new location. This keeps the window - overflow and underflow routines happy. */ - - newsp = (unsigned long *)registers[SP]; - if (sp != newsp) - sp = memcpy(newsp, sp, 16 * 4); - - /* Don't allow CWP to be modified. */ - - if (psr != registers[PSR]) - registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f); - - strcpy(remcomOutBuffer,"OK"); - } - break; - - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* Try to read %x,%x. */ - - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length)) - { - if (mem2hex((char *)addr, remcomOutBuffer, length, 1)) - break; - - strcpy (remcomOutBuffer, "E03"); - } - else - strcpy(remcomOutBuffer,"E01"); - break; - - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - /* Try to read '%x,%x:'. */ - - if (hexToInt(&ptr, &addr) - && *ptr++ == ',' - && hexToInt(&ptr, &length) - && *ptr++ == ':') - { - if (hex2mem(ptr, (char *)addr, length, 1)) - strcpy(remcomOutBuffer, "OK"); - else - strcpy(remcomOutBuffer, "E03"); - } - else - strcpy(remcomOutBuffer, "E02"); - break; - - case 'c': /* cAA..AA Continue at address AA..AA(optional) */ - /* try to read optional parameter, pc unchanged if no parm */ - - if (hexToInt(&ptr, &addr)) - { - registers[PC] = addr; - registers[NPC] = addr + 4; - } - -/* Need to flush the instruction cache here, as we may have deposited a - breakpoint, and the icache probably has no way of knowing that a data ref to - some location may have changed something that is in the instruction cache. - */ - - flush_i_cache(); - return; - - /* kill the program */ - case 'k' : /* do nothing */ - break; -#if 0 - case 't': /* Test feature */ - asm (" std %f30,[%sp]"); - break; -#endif - case 'r': /* Reset */ - asm ("call 0 - nop "); - break; - } /* switch */ - - /* reply to the request */ - putpacket(remcomOutBuffer); - } -} - -/* This function will generate a breakpoint exception. It is used at the - beginning of a program to sync up with a debugger and can be used - otherwise as a quick means to stop program execution and "break" into - the debugger. */ - -void -breakpoint (void) -{ - if (!initialized) - return; - - asm(" .globl _breakinst - - _breakinst: ta 1 - "); -} - -static void -hw_breakpoint (void) -{ - asm(" - ta 127 - "); -} - -#if 0 /* experimental and never finished, left here for reference */ -static void -splet_temp(void) -{ - asm(" sub %sp,(16+1+6+1+121)*4,%sp ! Make room for input & locals - ! + hidden arg + arg spill - ! + doubleword alignment - ! + registers[121] - -! Leave a trail of breadcrumbs! (save register save area for debugging) - mov %sp, %l0 - add %l0, 24*4, %l0 - sethi %hi(_debug_registers), %l1 - st %l0, [%lo(_debug_registers) + %l1] - -! Save the Alternate Register Set: (not implemented yet) -! To save the Alternate Register set, we must: -! 1) Save the current SP in some global location. -! 2) Swap the register sets. -! 3) Save the Alternate SP in the Y register -! 4) Fetch the SP that we saved in step 1. -! 5) Use that to save the rest of the regs (not forgetting ASP in Y) -! 6) Restore the Alternate SP from Y -! 7) Swap the registers back. - -! 1) Copy the current stack pointer to global _SAVED_STACK_POINTER: - sethi %hi(_saved_stack_pointer), %l0 - st %sp, [%lo(_saved_stack_pointer) + %l0] - -! 2) Swap the register sets: - mov %psr, %l1 - sethi %hi(0x10000), %l2 - xor %l1, %l2, %l1 - mov %l1, %psr - nop ! 3 nops after write to %psr (needed?) - nop - nop - -! 3) Save Alternate L0 in Y - wr %l0, 0, %y - -! 4) Load former SP into alternate SP, using L0 - sethi %hi(_saved_stack_pointer), %l0 - or %lo(_saved_stack_pointer), %l0, %l0 - swap [%l0], %sp - -! 4.5) Restore alternate L0 - rd %y, %l0 - -! 5) Save the Alternate Window Registers - st %r0, [%sp + (24 + 88) * 4] ! AWR0 - st %r1, [%sp + (24 + 89) * 4] ! AWR1 - st %r2, [%sp + (24 + 90) * 4] ! AWR2 - st %r3, [%sp + (24 + 91) * 4] ! AWR3 - st %r4, [%sp + (24 + 92) * 4] ! AWR4 - st %r5, [%sp + (24 + 93) * 4] ! AWR5 - st %r6, [%sp + (24 + 94) * 4] ! AWR6 - st %r7, [%sp + (24 + 95) * 4] ! AWR7 - st %r8, [%sp + (24 + 96) * 4] ! AWR8 - st %r9, [%sp + (24 + 97) * 4] ! AWR9 - st %r10, [%sp + (24 + 98) * 4] ! AWR10 - st %r11, [%sp + (24 + 99) * 4] ! AWR11 - st %r12, [%sp + (24 + 100) * 4] ! AWR12 - st %r13, [%sp + (24 + 101) * 4] ! AWR13 -! st %r14, [%sp + (24 + 102) * 4] ! AWR14 (SP) - st %r15, [%sp + (24 + 103) * 4] ! AWR15 - st %r16, [%sp + (24 + 104) * 4] ! AWR16 - st %r17, [%sp + (24 + 105) * 4] ! AWR17 - st %r18, [%sp + (24 + 106) * 4] ! AWR18 - st %r19, [%sp + (24 + 107) * 4] ! AWR19 - st %r20, [%sp + (24 + 108) * 4] ! AWR20 - st %r21, [%sp + (24 + 109) * 4] ! AWR21 - st %r22, [%sp + (24 + 110) * 4] ! AWR22 - st %r23, [%sp + (24 + 111) * 4] ! AWR23 - st %r24, [%sp + (24 + 112) * 4] ! AWR24 - st %r25, [%sp + (24 + 113) * 4] ! AWR25 - st %r26, [%sp + (24 + 114) * 4] ! AWR26 - st %r27, [%sp + (24 + 115) * 4] ! AWR27 - st %r28, [%sp + (24 + 116) * 4] ! AWR28 - st %r29, [%sp + (24 + 117) * 4] ! AWR29 - st %r30, [%sp + (24 + 118) * 4] ! AWR30 - st %r31, [%sp + (24 + 119) * 4] ! AWR21 - -! Get the Alternate PSR (I hope...) - - rd %psr, %l2 - st %l2, [%sp + (24 + 120) * 4] ! APSR - -! Don't forget the alternate stack pointer - - rd %y, %l3 - st %l3, [%sp + (24 + 102) * 4] ! AWR14 (SP) - -! 6) Restore the Alternate SP (saved in Y) - - rd %y, %o6 - - -! 7) Swap the registers back: - - mov %psr, %l1 - sethi %hi(0x10000), %l2 - xor %l1, %l2, %l1 - mov %l1, %psr - nop ! 3 nops after write to %psr (needed?) - nop - nop -"); -} - -#endif +// OBSOLETE /**************************************************************************** +// OBSOLETE +// OBSOLETE THIS SOFTWARE IS NOT COPYRIGHTED +// OBSOLETE +// OBSOLETE HP offers the following for use in the public domain. HP makes no +// OBSOLETE warranty with regard to the software or it's performance and the +// OBSOLETE user accepts the software "AS IS" with all faults. +// OBSOLETE +// OBSOLETE HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD +// OBSOLETE TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OBSOLETE OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// OBSOLETE +// OBSOLETE ****************************************************************************/ +// OBSOLETE +// OBSOLETE /**************************************************************************** +// OBSOLETE * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ +// OBSOLETE * +// OBSOLETE * Module name: remcom.c $ +// OBSOLETE * Revision: 1.34 $ +// OBSOLETE * Date: 91/03/09 12:29:49 $ +// OBSOLETE * Contributor: Lake Stevens Instrument Division$ +// OBSOLETE * +// OBSOLETE * Description: low level support for gdb debugger. $ +// OBSOLETE * +// OBSOLETE * Considerations: only works on target hardware $ +// OBSOLETE * +// OBSOLETE * Written by: Glenn Engel $ +// OBSOLETE * ModuleState: Experimental $ +// OBSOLETE * +// OBSOLETE * NOTES: See Below $ +// OBSOLETE * +// OBSOLETE * Modified for SPARC by Stu Grossman, Cygnus Support. +// OBSOLETE * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware +// OBSOLETE * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support. +// OBSOLETE * +// OBSOLETE * This code has been extensively tested on the Fujitsu SPARClite demo board. +// OBSOLETE * +// OBSOLETE * To enable debugger support, two things need to happen. One, a +// OBSOLETE * call to set_debug_traps() is necessary in order to allow any breakpoints +// OBSOLETE * or error conditions to be properly intercepted and reported to gdb. +// OBSOLETE * Two, a breakpoint needs to be generated to begin communication. This +// OBSOLETE * is most easily accomplished by a call to breakpoint(). Breakpoint() +// OBSOLETE * simulates a breakpoint by executing a trap #1. +// OBSOLETE * +// OBSOLETE ************* +// OBSOLETE * +// OBSOLETE * The following gdb commands are supported: +// OBSOLETE * +// OBSOLETE * command function Return value +// OBSOLETE * +// OBSOLETE * g return the value of the CPU registers hex data or ENN +// OBSOLETE * G set the value of the CPU registers OK or ENN +// OBSOLETE * P set the value of a single CPU register OK or ENN +// OBSOLETE * +// OBSOLETE * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN +// OBSOLETE * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN +// OBSOLETE * +// OBSOLETE * c Resume at current address SNN ( signal NN) +// OBSOLETE * cAA..AA Continue at address AA..AA SNN +// OBSOLETE * +// OBSOLETE * s Step one instruction SNN +// OBSOLETE * sAA..AA Step one instruction from AA..AA SNN +// OBSOLETE * +// OBSOLETE * k kill +// OBSOLETE * +// OBSOLETE * ? What was the last sigval ? SNN (signal NN) +// OBSOLETE * +// OBSOLETE * All commands and responses are sent with a packet which includes a +// OBSOLETE * checksum. A packet consists of +// OBSOLETE * +// OBSOLETE * $<packet info>#<checksum>. +// OBSOLETE * +// OBSOLETE * where +// OBSOLETE * <packet info> :: <characters representing the command or response> +// OBSOLETE * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>> +// OBSOLETE * +// OBSOLETE * When a packet is received, it is first acknowledged with either '+' or '-'. +// OBSOLETE * '+' indicates a successful transfer. '-' indicates a failed transfer. +// OBSOLETE * +// OBSOLETE * Example: +// OBSOLETE * +// OBSOLETE * Host: Reply: +// OBSOLETE * $m0,10#2a +$00010203040506070809101112131415#42 +// OBSOLETE * +// OBSOLETE ****************************************************************************/ +// OBSOLETE +// OBSOLETE #include <string.h> +// OBSOLETE #include <signal.h> +// OBSOLETE +// OBSOLETE /************************************************************************ +// OBSOLETE * +// OBSOLETE * external low-level support routines +// OBSOLETE */ +// OBSOLETE +// OBSOLETE extern void putDebugChar(); /* write a single character */ +// OBSOLETE extern int getDebugChar(); /* read and return a single char */ +// OBSOLETE +// OBSOLETE /************************************************************************/ +// OBSOLETE /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ +// OBSOLETE /* at least NUMREGBYTES*2 are needed for register packets */ +// OBSOLETE #define BUFMAX 2048 +// OBSOLETE +// OBSOLETE static int initialized = 0; /* !0 means we've been initialized */ +// OBSOLETE static int remote_debug = 0; /* turn on verbose debugging */ +// OBSOLETE +// OBSOLETE extern void breakinst(); +// OBSOLETE void _cprint(); +// OBSOLETE static void hw_breakpoint(); +// OBSOLETE static void set_mem_fault_trap(); +// OBSOLETE static void get_in_break_mode(); +// OBSOLETE static unsigned char *mem2hex(); +// OBSOLETE +// OBSOLETE static const char hexchars[]="0123456789abcdef"; +// OBSOLETE +// OBSOLETE #define NUMREGS 121 +// OBSOLETE +// OBSOLETE static unsigned long saved_stack_pointer; +// OBSOLETE +// OBSOLETE /* Number of bytes of registers. */ +// OBSOLETE #define NUMREGBYTES (NUMREGS * 4) +// OBSOLETE enum regnames { G0, G1, G2, G3, G4, G5, G6, G7, +// OBSOLETE O0, O1, O2, O3, O4, O5, SP, O7, +// OBSOLETE L0, L1, L2, L3, L4, L5, L6, L7, +// OBSOLETE I0, I1, I2, I3, I4, I5, FP, I7, +// OBSOLETE +// OBSOLETE F0, F1, F2, F3, F4, F5, F6, F7, +// OBSOLETE F8, F9, F10, F11, F12, F13, F14, F15, +// OBSOLETE F16, F17, F18, F19, F20, F21, F22, F23, +// OBSOLETE F24, F25, F26, F27, F28, F29, F30, F31, +// OBSOLETE +// OBSOLETE Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR, +// OBSOLETE CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR, UNUSED1, +// OBSOLETE +// OBSOLETE ASR1, ASR15, ASR17, ASR18, ASR19, ASR20, ASR21, ASR22, +// OBSOLETE /* the following not actually implemented */ +// OBSOLETE AWR0, AWR1, AWR2, AWR3, AWR4, AWR5, AWR6, AWR7, +// OBSOLETE AWR8, AWR9, AWR10, AWR11, AWR12, AWR13, AWR14, AWR15, +// OBSOLETE AWR16, AWR17, AWR18, AWR19, AWR20, AWR21, AWR22, AWR23, +// OBSOLETE AWR24, AWR25, AWR26, AWR27, AWR28, AWR29, AWR30, AWR31, +// OBSOLETE APSR +// OBSOLETE }; +// OBSOLETE +// OBSOLETE /*************************** ASSEMBLY CODE MACROS *************************/ +// OBSOLETE /* */ +// OBSOLETE +// OBSOLETE extern void trap_low(); +// OBSOLETE +// OBSOLETE asm(" +// OBSOLETE .reserve trapstack, 1000 * 4, \"bss\", 8 +// OBSOLETE +// OBSOLETE .data +// OBSOLETE .align 4 +// OBSOLETE +// OBSOLETE in_trap_handler: +// OBSOLETE .word 0 +// OBSOLETE +// OBSOLETE .text +// OBSOLETE .align 4 +// OBSOLETE +// OBSOLETE ! This function is called when any SPARC trap (except window overflow or +// OBSOLETE ! underflow) occurs. It makes sure that the invalid register window is still +// OBSOLETE ! available before jumping into C code. It will also restore the world if you +// OBSOLETE ! return from handle_exception. +// OBSOLETE ! +// OBSOLETE ! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly. +// OBSOLETE +// OBSOLETE .globl _trap_low +// OBSOLETE _trap_low: +// OBSOLETE mov %psr, %l0 +// OBSOLETE mov %wim, %l3 +// OBSOLETE +// OBSOLETE srl %l3, %l0, %l4 ! wim >> cwp +// OBSOLETE and %l4, 0xff, %l4 ! Mask off windows 28, 29 +// OBSOLETE cmp %l4, 1 +// OBSOLETE bne window_fine ! Branch if not in the invalid window +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! Handle window overflow +// OBSOLETE +// OBSOLETE mov %g1, %l4 ! Save g1, we use it to hold the wim +// OBSOLETE srl %l3, 1, %g1 ! Rotate wim right +// OBSOLETE and %g1, 0xff, %g1 ! Mask off windows 28, 29 +// OBSOLETE tst %g1 +// OBSOLETE bg good_wim ! Branch if new wim is non-zero +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! At this point, we need to bring a 1 into the high order bit of the wim. +// OBSOLETE ! Since we don't want to make any assumptions about the number of register +// OBSOLETE ! windows, we figure it out dynamically so as to setup the wim correctly. +// OBSOLETE +// OBSOLETE ! The normal way doesn't work on the sparclet as register windows +// OBSOLETE ! 28 and 29 are special purpose windows. +// OBSOLETE !not %g1 ! Fill g1 with ones +// OBSOLETE !mov %g1, %wim ! Fill the wim with ones +// OBSOLETE !nop +// OBSOLETE !nop +// OBSOLETE !nop +// OBSOLETE !mov %wim, %g1 ! Read back the wim +// OBSOLETE !inc %g1 ! Now g1 has 1 just to left of wim +// OBSOLETE !srl %g1, 1, %g1 ! Now put 1 at top of wim +// OBSOLETE +// OBSOLETE mov 0x80, %g1 ! Hack for sparclet +// OBSOLETE +// OBSOLETE ! This doesn't work on the sparclet. +// OBSOLETE !mov %g0, %wim ! Clear wim so that subsequent save +// OBSOLETE ! won't trap +// OBSOLETE andn %l3, 0xff, %l5 ! Clear wim but not windows 28, 29 +// OBSOLETE mov %l5, %wim +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE +// OBSOLETE good_wim: +// OBSOLETE save %g0, %g0, %g0 ! Slip into next window +// OBSOLETE mov %g1, %wim ! Install the new wim +// OBSOLETE +// OBSOLETE std %l0, [%sp + 0 * 4] ! save L & I registers +// OBSOLETE std %l2, [%sp + 2 * 4] +// OBSOLETE std %l4, [%sp + 4 * 4] +// OBSOLETE std %l6, [%sp + 6 * 4] +// OBSOLETE +// OBSOLETE std %i0, [%sp + 8 * 4] +// OBSOLETE std %i2, [%sp + 10 * 4] +// OBSOLETE std %i4, [%sp + 12 * 4] +// OBSOLETE std %i6, [%sp + 14 * 4] +// OBSOLETE +// OBSOLETE restore ! Go back to trap window. +// OBSOLETE mov %l4, %g1 ! Restore %g1 +// OBSOLETE +// OBSOLETE window_fine: +// OBSOLETE sethi %hi(in_trap_handler), %l4 +// OBSOLETE ld [%lo(in_trap_handler) + %l4], %l5 +// OBSOLETE tst %l5 +// OBSOLETE bg recursive_trap +// OBSOLETE inc %l5 +// OBSOLETE +// OBSOLETE set trapstack+1000*4, %sp ! Switch to trap stack +// OBSOLETE +// OBSOLETE recursive_trap: +// OBSOLETE st %l5, [%lo(in_trap_handler) + %l4] +// OBSOLETE sub %sp,(16+1+6+1+88)*4,%sp ! Make room for input & locals +// OBSOLETE ! + hidden arg + arg spill +// OBSOLETE ! + doubleword alignment +// OBSOLETE ! + registers[121] +// OBSOLETE +// OBSOLETE std %g0, [%sp + (24 + 0) * 4] ! registers[Gx] +// OBSOLETE std %g2, [%sp + (24 + 2) * 4] +// OBSOLETE std %g4, [%sp + (24 + 4) * 4] +// OBSOLETE std %g6, [%sp + (24 + 6) * 4] +// OBSOLETE +// OBSOLETE std %i0, [%sp + (24 + 8) * 4] ! registers[Ox] +// OBSOLETE std %i2, [%sp + (24 + 10) * 4] +// OBSOLETE std %i4, [%sp + (24 + 12) * 4] +// OBSOLETE std %i6, [%sp + (24 + 14) * 4] +// OBSOLETE +// OBSOLETE ! FP regs (sparclet doesn't have fpu) +// OBSOLETE +// OBSOLETE mov %y, %l4 +// OBSOLETE mov %tbr, %l5 +// OBSOLETE st %l4, [%sp + (24 + 64) * 4] ! Y +// OBSOLETE st %l0, [%sp + (24 + 65) * 4] ! PSR +// OBSOLETE st %l3, [%sp + (24 + 66) * 4] ! WIM +// OBSOLETE st %l5, [%sp + (24 + 67) * 4] ! TBR +// OBSOLETE st %l1, [%sp + (24 + 68) * 4] ! PC +// OBSOLETE st %l2, [%sp + (24 + 69) * 4] ! NPC +// OBSOLETE ! CPSR and FPSR not impl +// OBSOLETE or %l0, 0xf20, %l4 +// OBSOLETE mov %l4, %psr ! Turn on traps, disable interrupts +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! Save coprocessor state. +// OBSOLETE ! See SK/demo/hdlc_demo/ldc_swap_context.S. +// OBSOLETE +// OBSOLETE mov %psr, %l0 +// OBSOLETE sethi %hi(0x2000), %l5 ! EC bit in PSR +// OBSOLETE or %l5, %l0, %l5 +// OBSOLETE mov %l5, %psr ! enable coprocessor +// OBSOLETE nop ! 3 nops after write to %psr (needed?) +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE crdcxt %ccsr, %l1 ! capture CCSR +// OBSOLETE mov 0x6, %l2 +// OBSOLETE cwrcxt %l2, %ccsr ! set CCP state machine for CCFR +// OBSOLETE crdcxt %ccfr, %l2 ! capture CCOR +// OBSOLETE cwrcxt %l2, %ccfr ! tickle CCFR +// OBSOLETE crdcxt %ccfr, %l3 ! capture CCOBR +// OBSOLETE cwrcxt %l3, %ccfr ! tickle CCFR +// OBSOLETE crdcxt %ccfr, %l4 ! capture CCIBR +// OBSOLETE cwrcxt %l4, %ccfr ! tickle CCFR +// OBSOLETE crdcxt %ccfr, %l5 ! capture CCIR +// OBSOLETE cwrcxt %l5, %ccfr ! tickle CCFR +// OBSOLETE crdcxt %ccpr, %l6 ! capture CCPR +// OBSOLETE crdcxt %cccrcr, %l7 ! capture CCCRCR +// OBSOLETE st %l1, [%sp + (24 + 72) * 4] ! save CCSR +// OBSOLETE st %l2, [%sp + (24 + 75) * 4] ! save CCOR +// OBSOLETE st %l3, [%sp + (24 + 76) * 4] ! save CCOBR +// OBSOLETE st %l4, [%sp + (24 + 77) * 4] ! save CCIBR +// OBSOLETE st %l5, [%sp + (24 + 78) * 4] ! save CCIR +// OBSOLETE st %l6, [%sp + (24 + 73) * 4] ! save CCPR +// OBSOLETE st %l7, [%sp + (24 + 74) * 4] ! save CCCRCR +// OBSOLETE mov %l0, %psr ! restore original PSR +// OBSOLETE nop ! 3 nops after write to %psr (needed?) +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! End of saving coprocessor state. +// OBSOLETE ! Save asr regs +// OBSOLETE +// OBSOLETE ! Part of this is silly -- we should not display ASR15 or ASR19 at all. +// OBSOLETE +// OBSOLETE sethi %hi(0x01000000), %l6 +// OBSOLETE st %l6, [%sp + (24 + 81) * 4] ! ASR15 == NOP +// OBSOLETE sethi %hi(0xdeadc0de), %l6 +// OBSOLETE or %l6, %lo(0xdeadc0de), %l6 +// OBSOLETE st %l6, [%sp + (24 + 84) * 4] ! ASR19 == DEADC0DE +// OBSOLETE +// OBSOLETE rd %asr1, %l4 +// OBSOLETE st %l4, [%sp + (24 + 80) * 4] +// OBSOLETE ! rd %asr15, %l4 ! must not read ASR15 +// OBSOLETE ! st %l4, [%sp + (24 + 81) * 4] ! (illegal instr trap) +// OBSOLETE rd %asr17, %l4 +// OBSOLETE st %l4, [%sp + (24 + 82) * 4] +// OBSOLETE rd %asr18, %l4 +// OBSOLETE st %l4, [%sp + (24 + 83) * 4] +// OBSOLETE ! rd %asr19, %l4 ! must not read asr19 +// OBSOLETE ! st %l4, [%sp + (24 + 84) * 4] ! (halts the CPU) +// OBSOLETE rd %asr20, %l4 +// OBSOLETE st %l4, [%sp + (24 + 85) * 4] +// OBSOLETE rd %asr21, %l4 +// OBSOLETE st %l4, [%sp + (24 + 86) * 4] +// OBSOLETE rd %asr22, %l4 +// OBSOLETE st %l4, [%sp + (24 + 87) * 4] +// OBSOLETE +// OBSOLETE ! End of saving asr regs +// OBSOLETE +// OBSOLETE call _handle_exception +// OBSOLETE add %sp, 24 * 4, %o0 ! Pass address of registers +// OBSOLETE +// OBSOLETE ! Reload all of the registers that aren't on the stack +// OBSOLETE +// OBSOLETE ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx] +// OBSOLETE ldd [%sp + (24 + 2) * 4], %g2 +// OBSOLETE ldd [%sp + (24 + 4) * 4], %g4 +// OBSOLETE ldd [%sp + (24 + 6) * 4], %g6 +// OBSOLETE +// OBSOLETE ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox] +// OBSOLETE ldd [%sp + (24 + 10) * 4], %i2 +// OBSOLETE ldd [%sp + (24 + 12) * 4], %i4 +// OBSOLETE ldd [%sp + (24 + 14) * 4], %i6 +// OBSOLETE +// OBSOLETE ! FP regs (sparclet doesn't have fpu) +// OBSOLETE +// OBSOLETE ! Update the coprocessor registers. +// OBSOLETE ! See SK/demo/hdlc_demo/ldc_swap_context.S. +// OBSOLETE +// OBSOLETE mov %psr, %l0 +// OBSOLETE sethi %hi(0x2000), %l5 ! EC bit in PSR +// OBSOLETE or %l5, %l0, %l5 +// OBSOLETE mov %l5, %psr ! enable coprocessor +// OBSOLETE nop ! 3 nops after write to %psr (needed?) +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE +// OBSOLETE mov 0x6, %l2 +// OBSOLETE cwrcxt %l2, %ccsr ! set CCP state machine for CCFR +// OBSOLETE +// OBSOLETE ld [%sp + (24 + 72) * 4], %l1 ! saved CCSR +// OBSOLETE ld [%sp + (24 + 75) * 4], %l2 ! saved CCOR +// OBSOLETE ld [%sp + (24 + 76) * 4], %l3 ! saved CCOBR +// OBSOLETE ld [%sp + (24 + 77) * 4], %l4 ! saved CCIBR +// OBSOLETE ld [%sp + (24 + 78) * 4], %l5 ! saved CCIR +// OBSOLETE ld [%sp + (24 + 73) * 4], %l6 ! saved CCPR +// OBSOLETE ld [%sp + (24 + 74) * 4], %l7 ! saved CCCRCR +// OBSOLETE +// OBSOLETE cwrcxt %l2, %ccfr ! restore CCOR +// OBSOLETE cwrcxt %l3, %ccfr ! restore CCOBR +// OBSOLETE cwrcxt %l4, %ccfr ! restore CCIBR +// OBSOLETE cwrcxt %l5, %ccfr ! restore CCIR +// OBSOLETE cwrcxt %l6, %ccpr ! restore CCPR +// OBSOLETE cwrcxt %l7, %cccrcr ! restore CCCRCR +// OBSOLETE cwrcxt %l1, %ccsr ! restore CCSR +// OBSOLETE +// OBSOLETE mov %l0, %psr ! restore PSR +// OBSOLETE nop ! 3 nops after write to %psr (needed?) +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! End of coprocessor handling stuff. +// OBSOLETE ! Update asr regs +// OBSOLETE +// OBSOLETE ld [%sp + (24 + 80) * 4], %l4 +// OBSOLETE wr %l4, %asr1 +// OBSOLETE ! ld [%sp + (24 + 81) * 4], %l4 ! can't write asr15 +// OBSOLETE ! wr %l4, %asr15 +// OBSOLETE ld [%sp + (24 + 82) * 4], %l4 +// OBSOLETE wr %l4, %asr17 +// OBSOLETE ld [%sp + (24 + 83) * 4], %l4 +// OBSOLETE wr %l4, %asr18 +// OBSOLETE ! ld [%sp + (24 + 84) * 4], %l4 ! can't write asr19 +// OBSOLETE ! wr %l4, %asr19 +// OBSOLETE ! ld [%sp + (24 + 85) * 4], %l4 ! can't write asr20 +// OBSOLETE ! wr %l4, %asr20 +// OBSOLETE ! ld [%sp + (24 + 86) * 4], %l4 ! can't write asr21 +// OBSOLETE ! wr %l4, %asr21 +// OBSOLETE ld [%sp + (24 + 87) * 4], %l4 +// OBSOLETE wr %l4, %asr22 +// OBSOLETE +// OBSOLETE ! End of restoring asr regs +// OBSOLETE +// OBSOLETE +// OBSOLETE ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR +// OBSOLETE ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC +// OBSOLETE +// OBSOLETE restore ! Ensure that previous window is valid +// OBSOLETE save %g0, %g0, %g0 ! by causing a window_underflow trap +// OBSOLETE +// OBSOLETE mov %l0, %y +// OBSOLETE mov %l1, %psr ! Make sure that traps are disabled +// OBSOLETE ! for rett +// OBSOLETE nop ! 3 nops after write to %psr (needed?) +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE +// OBSOLETE sethi %hi(in_trap_handler), %l4 +// OBSOLETE ld [%lo(in_trap_handler) + %l4], %l5 +// OBSOLETE dec %l5 +// OBSOLETE st %l5, [%lo(in_trap_handler) + %l4] +// OBSOLETE +// OBSOLETE jmpl %l2, %g0 ! Restore old PC +// OBSOLETE rett %l3 ! Restore old nPC +// OBSOLETE "); +// OBSOLETE +// OBSOLETE /* Convert ch from a hex digit to an int */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE hex (unsigned char ch) +// OBSOLETE { +// OBSOLETE if (ch >= 'a' && ch <= 'f') +// OBSOLETE return ch-'a'+10; +// OBSOLETE if (ch >= '0' && ch <= '9') +// OBSOLETE return ch-'0'; +// OBSOLETE if (ch >= 'A' && ch <= 'F') +// OBSOLETE return ch-'A'+10; +// OBSOLETE return -1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE static char remcomInBuffer[BUFMAX]; +// OBSOLETE static char remcomOutBuffer[BUFMAX]; +// OBSOLETE +// OBSOLETE /* scan for the sequence $<data>#<checksum> */ +// OBSOLETE +// OBSOLETE unsigned char * +// OBSOLETE getpacket (void) +// OBSOLETE { +// OBSOLETE unsigned char *buffer = &remcomInBuffer[0]; +// OBSOLETE unsigned char checksum; +// OBSOLETE unsigned char xmitcsum; +// OBSOLETE int count; +// OBSOLETE char ch; +// OBSOLETE +// OBSOLETE while (1) +// OBSOLETE { +// OBSOLETE /* wait around for the start character, ignore all other characters */ +// OBSOLETE while ((ch = getDebugChar ()) != '$') +// OBSOLETE ; +// OBSOLETE +// OBSOLETE retry: +// OBSOLETE checksum = 0; +// OBSOLETE xmitcsum = -1; +// OBSOLETE count = 0; +// OBSOLETE +// OBSOLETE /* now, read until a # or end of buffer is found */ +// OBSOLETE while (count < BUFMAX) +// OBSOLETE { +// OBSOLETE ch = getDebugChar (); +// OBSOLETE if (ch == '$') +// OBSOLETE goto retry; +// OBSOLETE if (ch == '#') +// OBSOLETE break; +// OBSOLETE checksum = checksum + ch; +// OBSOLETE buffer[count] = ch; +// OBSOLETE count = count + 1; +// OBSOLETE } +// OBSOLETE buffer[count] = 0; +// OBSOLETE +// OBSOLETE if (ch == '#') +// OBSOLETE { +// OBSOLETE ch = getDebugChar (); +// OBSOLETE xmitcsum = hex (ch) << 4; +// OBSOLETE ch = getDebugChar (); +// OBSOLETE xmitcsum += hex (ch); +// OBSOLETE +// OBSOLETE if (checksum != xmitcsum) +// OBSOLETE { +// OBSOLETE putDebugChar ('-'); /* failed checksum */ +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE putDebugChar ('+'); /* successful transfer */ +// OBSOLETE +// OBSOLETE /* if a sequence char is present, reply the sequence ID */ +// OBSOLETE if (buffer[2] == ':') +// OBSOLETE { +// OBSOLETE putDebugChar (buffer[0]); +// OBSOLETE putDebugChar (buffer[1]); +// OBSOLETE +// OBSOLETE return &buffer[3]; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return &buffer[0]; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* send the packet in buffer. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE putpacket (unsigned char *buffer) +// OBSOLETE { +// OBSOLETE unsigned char checksum; +// OBSOLETE int count; +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE /* $<packet info>#<checksum>. */ +// OBSOLETE do +// OBSOLETE { +// OBSOLETE putDebugChar('$'); +// OBSOLETE checksum = 0; +// OBSOLETE count = 0; +// OBSOLETE +// OBSOLETE while (ch = buffer[count]) +// OBSOLETE { +// OBSOLETE putDebugChar(ch); +// OBSOLETE checksum += ch; +// OBSOLETE count += 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE putDebugChar('#'); +// OBSOLETE putDebugChar(hexchars[checksum >> 4]); +// OBSOLETE putDebugChar(hexchars[checksum & 0xf]); +// OBSOLETE +// OBSOLETE } +// OBSOLETE while (getDebugChar() != '+'); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Indicate to caller of mem2hex or hex2mem that there has been an +// OBSOLETE error. */ +// OBSOLETE static volatile int mem_err = 0; +// OBSOLETE +// OBSOLETE /* Convert the memory pointed to by mem into hex, placing result in buf. +// OBSOLETE * Return a pointer to the last char put in buf (null), in case of mem fault, +// OBSOLETE * return 0. +// OBSOLETE * If MAY_FAULT is non-zero, then we will handle memory faults by returning +// OBSOLETE * a 0, else treat a fault like any other fault in the stub. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static unsigned char * +// OBSOLETE mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault) +// OBSOLETE { +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE set_mem_fault_trap(may_fault); +// OBSOLETE +// OBSOLETE while (count-- > 0) +// OBSOLETE { +// OBSOLETE ch = *mem++; +// OBSOLETE if (mem_err) +// OBSOLETE return 0; +// OBSOLETE *buf++ = hexchars[ch >> 4]; +// OBSOLETE *buf++ = hexchars[ch & 0xf]; +// OBSOLETE } +// OBSOLETE +// OBSOLETE *buf = 0; +// OBSOLETE +// OBSOLETE set_mem_fault_trap(0); +// OBSOLETE +// OBSOLETE return buf; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* convert the hex array pointed to by buf into binary to be placed in mem +// OBSOLETE * return a pointer to the character AFTER the last byte written */ +// OBSOLETE +// OBSOLETE static char * +// OBSOLETE hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE unsigned char ch; +// OBSOLETE +// OBSOLETE set_mem_fault_trap(may_fault); +// OBSOLETE +// OBSOLETE for (i=0; i<count; i++) +// OBSOLETE { +// OBSOLETE ch = hex(*buf++) << 4; +// OBSOLETE ch |= hex(*buf++); +// OBSOLETE *mem++ = ch; +// OBSOLETE if (mem_err) +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE set_mem_fault_trap(0); +// OBSOLETE +// OBSOLETE return mem; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* This table contains the mapping between SPARC hardware trap types, and +// OBSOLETE signals, which are primarily what GDB understands. It also indicates +// OBSOLETE which hardware traps we need to commandeer when initializing the stub. */ +// OBSOLETE +// OBSOLETE static struct hard_trap_info +// OBSOLETE { +// OBSOLETE unsigned char tt; /* Trap type code for SPARClite */ +// OBSOLETE unsigned char signo; /* Signal that we map this trap into */ +// OBSOLETE } hard_trap_info[] = { +// OBSOLETE {1, SIGSEGV}, /* instruction access exception */ +// OBSOLETE {0x3b, SIGSEGV}, /* instruction access error */ +// OBSOLETE {2, SIGILL}, /* illegal instruction */ +// OBSOLETE {3, SIGILL}, /* privileged instruction */ +// OBSOLETE {4, SIGEMT}, /* fp disabled */ +// OBSOLETE {0x24, SIGEMT}, /* cp disabled */ +// OBSOLETE {7, SIGBUS}, /* mem address not aligned */ +// OBSOLETE {0x29, SIGSEGV}, /* data access exception */ +// OBSOLETE {10, SIGEMT}, /* tag overflow */ +// OBSOLETE {128+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */ +// OBSOLETE {0, 0} /* Must be last */ +// OBSOLETE }; +// OBSOLETE +// OBSOLETE /* Set up exception handlers for tracing and breakpoints */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE set_debug_traps (void) +// OBSOLETE { +// OBSOLETE struct hard_trap_info *ht; +// OBSOLETE +// OBSOLETE for (ht = hard_trap_info; ht->tt && ht->signo; ht++) +// OBSOLETE exceptionHandler(ht->tt, trap_low); +// OBSOLETE +// OBSOLETE initialized = 1; +// OBSOLETE } +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE ! Trap handler for memory errors. This just sets mem_err to be non-zero. It +// OBSOLETE ! assumes that %l1 is non-zero. This should be safe, as it is doubtful that +// OBSOLETE ! 0 would ever contain code that could mem fault. This routine will skip +// OBSOLETE ! past the faulting instruction after setting mem_err. +// OBSOLETE +// OBSOLETE .text +// OBSOLETE .align 4 +// OBSOLETE +// OBSOLETE _fltr_set_mem_err: +// OBSOLETE sethi %hi(_mem_err), %l0 +// OBSOLETE st %l1, [%l0 + %lo(_mem_err)] +// OBSOLETE jmpl %l2, %g0 +// OBSOLETE rett %l2+4 +// OBSOLETE "); +// OBSOLETE +// OBSOLETE static void +// OBSOLETE set_mem_fault_trap (int enable) +// OBSOLETE { +// OBSOLETE extern void fltr_set_mem_err(); +// OBSOLETE mem_err = 0; +// OBSOLETE +// OBSOLETE if (enable) +// OBSOLETE exceptionHandler(0x29, fltr_set_mem_err); +// OBSOLETE else +// OBSOLETE exceptionHandler(0x29, trap_low); +// OBSOLETE } +// OBSOLETE +// OBSOLETE asm (" +// OBSOLETE .text +// OBSOLETE .align 4 +// OBSOLETE +// OBSOLETE _dummy_hw_breakpoint: +// OBSOLETE jmpl %l2, %g0 +// OBSOLETE rett %l2+4 +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE "); +// OBSOLETE +// OBSOLETE static void +// OBSOLETE set_hw_breakpoint_trap (int enable) +// OBSOLETE { +// OBSOLETE extern void dummy_hw_breakpoint(); +// OBSOLETE +// OBSOLETE if (enable) +// OBSOLETE exceptionHandler(255, dummy_hw_breakpoint); +// OBSOLETE else +// OBSOLETE exceptionHandler(255, trap_low); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE get_in_break_mode (void) +// OBSOLETE { +// OBSOLETE #if 0 +// OBSOLETE int x; +// OBSOLETE mesg("get_in_break_mode, sp = "); +// OBSOLETE phex(&x); +// OBSOLETE #endif +// OBSOLETE set_hw_breakpoint_trap(1); +// OBSOLETE +// OBSOLETE asm(" +// OBSOLETE sethi %hi(0xff10), %l4 +// OBSOLETE or %l4, %lo(0xff10), %l4 +// OBSOLETE sta %g0, [%l4]0x1 +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE "); +// OBSOLETE +// OBSOLETE set_hw_breakpoint_trap(0); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Convert the SPARC hardware trap type code to a unix signal number. */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE computeSignal (int tt) +// OBSOLETE { +// OBSOLETE struct hard_trap_info *ht; +// OBSOLETE +// OBSOLETE for (ht = hard_trap_info; ht->tt && ht->signo; ht++) +// OBSOLETE if (ht->tt == tt) +// OBSOLETE return ht->signo; +// OBSOLETE +// OBSOLETE return SIGHUP; /* default for things we don't know about */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * While we find nice hex chars, build an int. +// OBSOLETE * Return number of chars processed. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static int +// OBSOLETE hexToInt(char **ptr, int *intValue) +// OBSOLETE { +// OBSOLETE int numChars = 0; +// OBSOLETE int hexValue; +// OBSOLETE +// OBSOLETE *intValue = 0; +// OBSOLETE +// OBSOLETE while (**ptr) +// OBSOLETE { +// OBSOLETE hexValue = hex(**ptr); +// OBSOLETE if (hexValue < 0) +// OBSOLETE break; +// OBSOLETE +// OBSOLETE *intValue = (*intValue << 4) | hexValue; +// OBSOLETE numChars ++; +// OBSOLETE +// OBSOLETE (*ptr)++; +// OBSOLETE } +// OBSOLETE +// OBSOLETE return (numChars); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* +// OBSOLETE * This function does all command procesing for interfacing to gdb. It +// OBSOLETE * returns 1 if you should skip the instruction at the trap address, 0 +// OBSOLETE * otherwise. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE handle_exception (unsigned long *registers) +// OBSOLETE { +// OBSOLETE int tt; /* Trap type */ +// OBSOLETE int sigval; +// OBSOLETE int addr; +// OBSOLETE int length; +// OBSOLETE char *ptr; +// OBSOLETE unsigned long *sp; +// OBSOLETE unsigned long dsr; +// OBSOLETE +// OBSOLETE /* First, we must force all of the windows to be spilled out */ +// OBSOLETE +// OBSOLETE asm(" +// OBSOLETE ! Ugh. sparclet has broken save +// OBSOLETE !save %sp, -64, %sp +// OBSOLETE save +// OBSOLETE add %fp,-64,%sp +// OBSOLETE !save %sp, -64, %sp +// OBSOLETE save +// OBSOLETE add %fp,-64,%sp +// OBSOLETE !save %sp, -64, %sp +// OBSOLETE save +// OBSOLETE add %fp,-64,%sp +// OBSOLETE !save %sp, -64, %sp +// OBSOLETE save +// OBSOLETE add %fp,-64,%sp +// OBSOLETE !save %sp, -64, %sp +// OBSOLETE save +// OBSOLETE add %fp,-64,%sp +// OBSOLETE !save %sp, -64, %sp +// OBSOLETE save +// OBSOLETE add %fp,-64,%sp +// OBSOLETE !save %sp, -64, %sp +// OBSOLETE save +// OBSOLETE add %fp,-64,%sp +// OBSOLETE !save %sp, -64, %sp +// OBSOLETE save +// OBSOLETE add %fp,-64,%sp +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE restore +// OBSOLETE "); +// OBSOLETE +// OBSOLETE if (registers[PC] == (unsigned long)breakinst) +// OBSOLETE { +// OBSOLETE registers[PC] = registers[NPC]; +// OBSOLETE registers[NPC] += 4; +// OBSOLETE } +// OBSOLETE sp = (unsigned long *)registers[SP]; +// OBSOLETE +// OBSOLETE tt = (registers[TBR] >> 4) & 0xff; +// OBSOLETE +// OBSOLETE /* reply to host that an exception has occurred */ +// OBSOLETE sigval = computeSignal(tt); +// OBSOLETE ptr = remcomOutBuffer; +// OBSOLETE +// OBSOLETE *ptr++ = 'T'; +// OBSOLETE *ptr++ = hexchars[sigval >> 4]; +// OBSOLETE *ptr++ = hexchars[sigval & 0xf]; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[PC >> 4]; +// OBSOLETE *ptr++ = hexchars[PC & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((char *)®isters[PC], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[FP >> 4]; +// OBSOLETE *ptr++ = hexchars[FP & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */ +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[SP >> 4]; +// OBSOLETE *ptr++ = hexchars[SP & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((char *)&sp, ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[NPC >> 4]; +// OBSOLETE *ptr++ = hexchars[NPC & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((char *)®isters[NPC], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = hexchars[O7 >> 4]; +// OBSOLETE *ptr++ = hexchars[O7 & 0xf]; +// OBSOLETE *ptr++ = ':'; +// OBSOLETE ptr = mem2hex((char *)®isters[O7], ptr, 4, 0); +// OBSOLETE *ptr++ = ';'; +// OBSOLETE +// OBSOLETE *ptr++ = 0; +// OBSOLETE +// OBSOLETE putpacket(remcomOutBuffer); +// OBSOLETE +// OBSOLETE while (1) +// OBSOLETE { +// OBSOLETE remcomOutBuffer[0] = 0; +// OBSOLETE +// OBSOLETE ptr = getpacket(); +// OBSOLETE switch (*ptr++) +// OBSOLETE { +// OBSOLETE case '?': +// OBSOLETE remcomOutBuffer[0] = 'S'; +// OBSOLETE remcomOutBuffer[1] = hexchars[sigval >> 4]; +// OBSOLETE remcomOutBuffer[2] = hexchars[sigval & 0xf]; +// OBSOLETE remcomOutBuffer[3] = 0; +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'd': +// OBSOLETE remote_debug = !(remote_debug); /* toggle debug flag */ +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'g': /* return the value of the CPU registers */ +// OBSOLETE { +// OBSOLETE ptr = remcomOutBuffer; +// OBSOLETE ptr = mem2hex((char *)registers, ptr, 16 * 4, 0); /* G & O regs */ +// OBSOLETE ptr = mem2hex(sp + 0, ptr, 16 * 4, 0); /* L & I regs */ +// OBSOLETE memset(ptr, '0', 32 * 8); /* Floating point */ +// OBSOLETE ptr = mem2hex((char *)®isters[Y], +// OBSOLETE ptr + 32 * 4 * 2, +// OBSOLETE 8 * 4, +// OBSOLETE 0); /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ +// OBSOLETE ptr = mem2hex((char *)®isters[CCSR], +// OBSOLETE ptr, +// OBSOLETE 8 * 4, +// OBSOLETE 0); /* CCSR, CCPR, CCCRCR, CCOR, CCOBR, CCIBR, CCIR */ +// OBSOLETE ptr = mem2hex((char *)®isters[ASR1], +// OBSOLETE ptr, +// OBSOLETE 8 * 4, +// OBSOLETE 0); /* ASR1,ASR15,ASR17,ASR18,ASR19,ASR20,ASR21,ASR22 */ +// OBSOLETE #if 0 /* not implemented */ +// OBSOLETE ptr = mem2hex((char *) ®isters[AWR0], +// OBSOLETE ptr, +// OBSOLETE 32 * 4, +// OBSOLETE 0); /* Alternate Window Registers */ +// OBSOLETE #endif +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'G': /* set value of all the CPU registers - return OK */ +// OBSOLETE case 'P': /* set value of one CPU register - return OK */ +// OBSOLETE { +// OBSOLETE unsigned long *newsp, psr; +// OBSOLETE +// OBSOLETE psr = registers[PSR]; +// OBSOLETE +// OBSOLETE if (ptr[-1] == 'P') /* do a single register */ +// OBSOLETE { +// OBSOLETE int regno; +// OBSOLETE +// OBSOLETE if (hexToInt (&ptr, ®no) +// OBSOLETE && *ptr++ == '=') +// OBSOLETE if (regno >= L0 && regno <= I7) +// OBSOLETE hex2mem (ptr, sp + regno - L0, 4, 0); +// OBSOLETE else +// OBSOLETE hex2mem (ptr, (char *)®isters[regno], 4, 0); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE strcpy (remcomOutBuffer, "E01"); +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */ +// OBSOLETE hex2mem(ptr + 16 * 4 * 2, sp + 0, 16 * 4, 0); /* L & I regs */ +// OBSOLETE hex2mem(ptr + 64 * 4 * 2, (char *)®isters[Y], +// OBSOLETE 8 * 4, 0); /* Y,PSR,WIM,TBR,PC,NPC,FPSR,CPSR */ +// OBSOLETE hex2mem(ptr + 72 * 4 * 2, (char *)®isters[CCSR], +// OBSOLETE 8 * 4, 0); /* CCSR,CCPR,CCCRCR,CCOR,CCOBR,CCIBR,CCIR */ +// OBSOLETE hex2mem(ptr + 80 * 4 * 2, (char *)®isters[ASR1], +// OBSOLETE 8 * 4, 0); /* ASR1 ... ASR22 */ +// OBSOLETE #if 0 /* not implemented */ +// OBSOLETE hex2mem(ptr + 88 * 4 * 2, (char *)®isters[AWR0], +// OBSOLETE 8 * 4, 0); /* Alternate Window Registers */ +// OBSOLETE #endif +// OBSOLETE } +// OBSOLETE /* See if the stack pointer has moved. If so, then copy the saved +// OBSOLETE locals and ins to the new location. This keeps the window +// OBSOLETE overflow and underflow routines happy. */ +// OBSOLETE +// OBSOLETE newsp = (unsigned long *)registers[SP]; +// OBSOLETE if (sp != newsp) +// OBSOLETE sp = memcpy(newsp, sp, 16 * 4); +// OBSOLETE +// OBSOLETE /* Don't allow CWP to be modified. */ +// OBSOLETE +// OBSOLETE if (psr != registers[PSR]) +// OBSOLETE registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f); +// OBSOLETE +// OBSOLETE strcpy(remcomOutBuffer,"OK"); +// OBSOLETE } +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ +// OBSOLETE /* Try to read %x,%x. */ +// OBSOLETE +// OBSOLETE if (hexToInt(&ptr, &addr) +// OBSOLETE && *ptr++ == ',' +// OBSOLETE && hexToInt(&ptr, &length)) +// OBSOLETE { +// OBSOLETE if (mem2hex((char *)addr, remcomOutBuffer, length, 1)) +// OBSOLETE break; +// OBSOLETE +// OBSOLETE strcpy (remcomOutBuffer, "E03"); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE strcpy(remcomOutBuffer,"E01"); +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ +// OBSOLETE /* Try to read '%x,%x:'. */ +// OBSOLETE +// OBSOLETE if (hexToInt(&ptr, &addr) +// OBSOLETE && *ptr++ == ',' +// OBSOLETE && hexToInt(&ptr, &length) +// OBSOLETE && *ptr++ == ':') +// OBSOLETE { +// OBSOLETE if (hex2mem(ptr, (char *)addr, length, 1)) +// OBSOLETE strcpy(remcomOutBuffer, "OK"); +// OBSOLETE else +// OBSOLETE strcpy(remcomOutBuffer, "E03"); +// OBSOLETE } +// OBSOLETE else +// OBSOLETE strcpy(remcomOutBuffer, "E02"); +// OBSOLETE break; +// OBSOLETE +// OBSOLETE case 'c': /* cAA..AA Continue at address AA..AA(optional) */ +// OBSOLETE /* try to read optional parameter, pc unchanged if no parm */ +// OBSOLETE +// OBSOLETE if (hexToInt(&ptr, &addr)) +// OBSOLETE { +// OBSOLETE registers[PC] = addr; +// OBSOLETE registers[NPC] = addr + 4; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Need to flush the instruction cache here, as we may have deposited a +// OBSOLETE breakpoint, and the icache probably has no way of knowing that a data ref to +// OBSOLETE some location may have changed something that is in the instruction cache. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE flush_i_cache(); +// OBSOLETE return; +// OBSOLETE +// OBSOLETE /* kill the program */ +// OBSOLETE case 'k' : /* do nothing */ +// OBSOLETE break; +// OBSOLETE #if 0 +// OBSOLETE case 't': /* Test feature */ +// OBSOLETE asm (" std %f30,[%sp]"); +// OBSOLETE break; +// OBSOLETE #endif +// OBSOLETE case 'r': /* Reset */ +// OBSOLETE asm ("call 0 +// OBSOLETE nop "); +// OBSOLETE break; +// OBSOLETE } /* switch */ +// OBSOLETE +// OBSOLETE /* reply to the request */ +// OBSOLETE putpacket(remcomOutBuffer); +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* This function will generate a breakpoint exception. It is used at the +// OBSOLETE beginning of a program to sync up with a debugger and can be used +// OBSOLETE otherwise as a quick means to stop program execution and "break" into +// OBSOLETE the debugger. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE breakpoint (void) +// OBSOLETE { +// OBSOLETE if (!initialized) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE asm(" .globl _breakinst +// OBSOLETE +// OBSOLETE _breakinst: ta 1 +// OBSOLETE "); +// OBSOLETE } +// OBSOLETE +// OBSOLETE static void +// OBSOLETE hw_breakpoint (void) +// OBSOLETE { +// OBSOLETE asm(" +// OBSOLETE ta 127 +// OBSOLETE "); +// OBSOLETE } +// OBSOLETE +// OBSOLETE #if 0 /* experimental and never finished, left here for reference */ +// OBSOLETE static void +// OBSOLETE splet_temp(void) +// OBSOLETE { +// OBSOLETE asm(" sub %sp,(16+1+6+1+121)*4,%sp ! Make room for input & locals +// OBSOLETE ! + hidden arg + arg spill +// OBSOLETE ! + doubleword alignment +// OBSOLETE ! + registers[121] +// OBSOLETE +// OBSOLETE ! Leave a trail of breadcrumbs! (save register save area for debugging) +// OBSOLETE mov %sp, %l0 +// OBSOLETE add %l0, 24*4, %l0 +// OBSOLETE sethi %hi(_debug_registers), %l1 +// OBSOLETE st %l0, [%lo(_debug_registers) + %l1] +// OBSOLETE +// OBSOLETE ! Save the Alternate Register Set: (not implemented yet) +// OBSOLETE ! To save the Alternate Register set, we must: +// OBSOLETE ! 1) Save the current SP in some global location. +// OBSOLETE ! 2) Swap the register sets. +// OBSOLETE ! 3) Save the Alternate SP in the Y register +// OBSOLETE ! 4) Fetch the SP that we saved in step 1. +// OBSOLETE ! 5) Use that to save the rest of the regs (not forgetting ASP in Y) +// OBSOLETE ! 6) Restore the Alternate SP from Y +// OBSOLETE ! 7) Swap the registers back. +// OBSOLETE +// OBSOLETE ! 1) Copy the current stack pointer to global _SAVED_STACK_POINTER: +// OBSOLETE sethi %hi(_saved_stack_pointer), %l0 +// OBSOLETE st %sp, [%lo(_saved_stack_pointer) + %l0] +// OBSOLETE +// OBSOLETE ! 2) Swap the register sets: +// OBSOLETE mov %psr, %l1 +// OBSOLETE sethi %hi(0x10000), %l2 +// OBSOLETE xor %l1, %l2, %l1 +// OBSOLETE mov %l1, %psr +// OBSOLETE nop ! 3 nops after write to %psr (needed?) +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE +// OBSOLETE ! 3) Save Alternate L0 in Y +// OBSOLETE wr %l0, 0, %y +// OBSOLETE +// OBSOLETE ! 4) Load former SP into alternate SP, using L0 +// OBSOLETE sethi %hi(_saved_stack_pointer), %l0 +// OBSOLETE or %lo(_saved_stack_pointer), %l0, %l0 +// OBSOLETE swap [%l0], %sp +// OBSOLETE +// OBSOLETE ! 4.5) Restore alternate L0 +// OBSOLETE rd %y, %l0 +// OBSOLETE +// OBSOLETE ! 5) Save the Alternate Window Registers +// OBSOLETE st %r0, [%sp + (24 + 88) * 4] ! AWR0 +// OBSOLETE st %r1, [%sp + (24 + 89) * 4] ! AWR1 +// OBSOLETE st %r2, [%sp + (24 + 90) * 4] ! AWR2 +// OBSOLETE st %r3, [%sp + (24 + 91) * 4] ! AWR3 +// OBSOLETE st %r4, [%sp + (24 + 92) * 4] ! AWR4 +// OBSOLETE st %r5, [%sp + (24 + 93) * 4] ! AWR5 +// OBSOLETE st %r6, [%sp + (24 + 94) * 4] ! AWR6 +// OBSOLETE st %r7, [%sp + (24 + 95) * 4] ! AWR7 +// OBSOLETE st %r8, [%sp + (24 + 96) * 4] ! AWR8 +// OBSOLETE st %r9, [%sp + (24 + 97) * 4] ! AWR9 +// OBSOLETE st %r10, [%sp + (24 + 98) * 4] ! AWR10 +// OBSOLETE st %r11, [%sp + (24 + 99) * 4] ! AWR11 +// OBSOLETE st %r12, [%sp + (24 + 100) * 4] ! AWR12 +// OBSOLETE st %r13, [%sp + (24 + 101) * 4] ! AWR13 +// OBSOLETE ! st %r14, [%sp + (24 + 102) * 4] ! AWR14 (SP) +// OBSOLETE st %r15, [%sp + (24 + 103) * 4] ! AWR15 +// OBSOLETE st %r16, [%sp + (24 + 104) * 4] ! AWR16 +// OBSOLETE st %r17, [%sp + (24 + 105) * 4] ! AWR17 +// OBSOLETE st %r18, [%sp + (24 + 106) * 4] ! AWR18 +// OBSOLETE st %r19, [%sp + (24 + 107) * 4] ! AWR19 +// OBSOLETE st %r20, [%sp + (24 + 108) * 4] ! AWR20 +// OBSOLETE st %r21, [%sp + (24 + 109) * 4] ! AWR21 +// OBSOLETE st %r22, [%sp + (24 + 110) * 4] ! AWR22 +// OBSOLETE st %r23, [%sp + (24 + 111) * 4] ! AWR23 +// OBSOLETE st %r24, [%sp + (24 + 112) * 4] ! AWR24 +// OBSOLETE st %r25, [%sp + (24 + 113) * 4] ! AWR25 +// OBSOLETE st %r26, [%sp + (24 + 114) * 4] ! AWR26 +// OBSOLETE st %r27, [%sp + (24 + 115) * 4] ! AWR27 +// OBSOLETE st %r28, [%sp + (24 + 116) * 4] ! AWR28 +// OBSOLETE st %r29, [%sp + (24 + 117) * 4] ! AWR29 +// OBSOLETE st %r30, [%sp + (24 + 118) * 4] ! AWR30 +// OBSOLETE st %r31, [%sp + (24 + 119) * 4] ! AWR21 +// OBSOLETE +// OBSOLETE ! Get the Alternate PSR (I hope...) +// OBSOLETE +// OBSOLETE rd %psr, %l2 +// OBSOLETE st %l2, [%sp + (24 + 120) * 4] ! APSR +// OBSOLETE +// OBSOLETE ! Don't forget the alternate stack pointer +// OBSOLETE +// OBSOLETE rd %y, %l3 +// OBSOLETE st %l3, [%sp + (24 + 102) * 4] ! AWR14 (SP) +// OBSOLETE +// OBSOLETE ! 6) Restore the Alternate SP (saved in Y) +// OBSOLETE +// OBSOLETE rd %y, %o6 +// OBSOLETE +// OBSOLETE +// OBSOLETE ! 7) Swap the registers back: +// OBSOLETE +// OBSOLETE mov %psr, %l1 +// OBSOLETE sethi %hi(0x10000), %l2 +// OBSOLETE xor %l1, %l2, %l1 +// OBSOLETE mov %l1, %psr +// OBSOLETE nop ! 3 nops after write to %psr (needed?) +// OBSOLETE nop +// OBSOLETE nop +// OBSOLETE "); +// OBSOLETE } +// OBSOLETE +// OBSOLETE #endif |