mips: Remove the GDB stub

bsps/mips/shared/gdbstub/ holds a GDB stub of 2001 in five files.  No
build item names any of them, so no BSP compiles the stub and
mips_gdb_stub_install() has no caller.

The stub could not link in any case.  It installed its handler with
rtems_interrupt_catch(), a simple vectored directive which the tree
does not have.  It calls rtems_gdb_stub_get_current_thread() and two
more functions which gdb_if.h declares and no source defines.  It
declares mips_register_t for __mips 1 and __mips 3 alone, so the
preprocessor raises an error for the malta and the csb350 BSP.  Its
README names the MongooseV BSP, which the tree dropped.

cpu_asm.S carries the support of the stub.  mips_break() is the
breakpoint trampoline and the exception return steps over the break of
it.  Nothing else calls either one.  A commented-out block of the
R3000 return logic states that the stub does that work instead.  Five
comments name the stub.

Remove the directory and that support.

A back end of cpukit/libdebugger/ will serve the MIPS port.  The
library carries one for aarch64, arm, i386, microblaze and powerpc
today.

Update #5752.

Assisted-by: Claude:claude-opus-5 claude-code
Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
This commit is contained in:
Sebastian Huber
2026-09-21 20:02:55 -05:00
committed by Kinsey Moore
parent 710d341453
commit 382be2ca57
7 changed files with 6 additions and 2454 deletions
-151
View File
@@ -1,151 +0,0 @@
GDB stub
========
Debugged this stub against the MongooseV bsp. Relies on putting break
instructions on breakpoints and step targets- normal stuff, and does not
employ hardware breakpoint support at this time. As written, a single
breakpoint in a loop will not be reasserted unless the user steps or has
a 2nd one, since breakpoints are only reset when the gdb stub is
re-entered. A useful enhancement would be to fix the break instruction
management so the stub could invisibly put a 2nd break after the 1st
"official" one so it can silently reset breakpoints. Shouldn't be too
hard, mostly a matter of working it out.
This was tested only against an R3000 MIPS. It should work OK on a
R4000. Needs to be tested at some point.
This stub supports threads as implemented by gdb 5 and doesn't have any
bugs I'm aware of.
Greg Menke
3/5/2002
The contents of this directory are based upon the "r46kstub.tar.gz" package
released to the net by
C. M. Heard
VVNET, Inc. phone: +1 408 247 9376
4040 Moorpark Ave. Suite 206 fax: +1 408 244 3651
San Jose, CA 95117 USA e-mail: heard@vvnet.com
This package was released in the September 1996 time frame for use
with gdb 4.16 and an IDT R4600 Orion. The stub was modified to support
R3000 class CPUs and to work within the mips-rtems exeception processing
framework.
The file memlimits.h could end up being target board dependent. If
this is the case, copy it to your BSP directory and modify as necessary.
Original README
---------------
The r46kstub directory and its compressed archive (r46kstub.tar.gz) contain
the 9/29/96 source code snapshot for a ROM-resident gdb-4.16 debug agent
(aka stub) for the IDT R4600 Orion processor. It is based on the stub for
the Hitachi SH processor written by Ben Lee and Steve Chamberlain and
supplied with the gdb-4.16 distribution; that stub in turn was "originally
based on an m68k software stub written by Glenn Engel at HP, but has changed
quite a bit". The modifications for the R4600 were contributed by C. M.
Heard of VVNET, Inc. and were based in part on the Algorithmics R4000 version
of Phil Bunce's PMON program.
The distribution consists of the following files:
```
-rw-r--r-- 1 1178 Sep 29 16:34 ChangeLog
-rw-r--r-- 1 748 Jul 26 01:18 Makefile
-rw-r--r-- 1 6652 Sep 29 16:34 README
-rw-r--r-- 1 1829 May 21 02:02 gdb_if.h
-rw-r--r-- 1 3745 Sep 29 14:03 ioaddr.h
-rw-r--r-- 1 2906 Sep 29 14:39 limits.h
-rw-r--r-- 1 6552 May 23 00:17 mips_opcode.h
-rw-r--r-- 1 14017 May 21 02:04 r4600.h
-rw-r--r-- 1 23874 Jul 21 20:31 r46kstub.c
-rw-r--r-- 1 1064 Jul 3 12:35 r46kstub.ld
-rw-r--r-- 1 13299 Sep 29 16:24 stubinit.S
```
With the exception of mips_opcode.h, which is a slightly modified version
of a header file contributed by Ralph Campbell to 4.4 BSD and is therefore
copyrighted by the UC Regents, all of the source files have been dedicated
by their authors to the public domain. Use them as you wish, but do so
at your own risk! The authors accept _no_ responsibility for any errors.
The debug agent contained herein is at this writing in active use at VVNET
supporting initial hardware debug and board bring-up of an OC-12 ATM probe
board. It uses polled I/O on a 16C450 UART. We had originally intended to
add support for interrupts to allow gdb to break in on a running program,
but we have found that this is not really necessary since the reset button
will accomplish the same purpose (thanks to the MIPS feature of saving the
program counter in the ErrorEPC register when a reset exception occurs).
Be aware that this stub handles ALL interrupts and exceptions except for
reset (or NMI) in the same way -- by passing control to the debug command
loop. It of course uses the ROM exception vectors to do so. In order to
support code that actally needs to use interrupts we use use a more elaborate
stub that is linked with the downloaded program. It hooks the RAM exception
vectors and clears the BEV status bit to gain control. The ROM-based stub
is still used in this case for initial program loading.
In order to port this stub to a different platform you will at a minimum
need to customize the macros in limits.h (which define the limits of readable,
writeable, and steppable address space) and the I/O addresses in ioaddr.h
(which define the 16C450 MMIO addresses). If you use something other than
a 16C450 UART you will probably also need to modify the portions of stubinit.S
which deal with the serial port. I've tried to be careful to respect all the
architecturally-defined hazards as described in Appendix F of Kane and
Heinrich, MIPS RISC Architecture, in order to minimize the work in porting
to 4000-series processors other than the R4600, but no guarantees are offered.
Support is presently restricted to big-endian addressing, and I've not even
considered what changes would be needed for little-endian support.
When this stub is built with gcc-2.7.2 and binutils-2.6 you will see a few
warning messages from the single-step support routine where a cast is used
to sign-extend a pointer (the next instruction address) into a long long
(the PC image). Those warnings are expected; I've checked the generated
code and it is doing what I had intended. But you should not see any other
warnings or errors. Here is a log of the build:
```shell
mips64orion-idt-elf-gcc -g -Wa,-ahld -Wall -membedded-data \
-O3 -c r46kstub.c >r46kstub.L
r46kstub.c: In function `doSStep':
r46kstub.c:537: warning: cast to pointer from integer of different size
r46kstub.c:539: warning: cast to pointer from integer of different size
r46kstub.c:547: warning: cast to pointer from integer of different size
r46kstub.c:561: warning: cast to pointer from integer of different size
r46kstub.c:563: warning: cast to pointer from integer of different size
r46kstub.c:572: warning: cast to pointer from integer of different size
r46kstub.c:574: warning: cast to pointer from integer of different size
r46kstub.c:582: warning: cast to pointer from integer of different size
r46kstub.c:589: warning: cast to pointer from integer of different size
r46kstub.c:591: warning: cast to pointer from integer of different size
r46kstub.c:597: warning: cast to pointer from integer of different size
r46kstub.c:599: warning: cast to pointer from integer of different size
r46kstub.c:605: warning: cast to pointer from integer of different size
r46kstub.c:607: warning: cast to pointer from integer of different size
r46kstub.c:613: warning: cast to pointer from integer of different size
r46kstub.c:615: warning: cast to pointer from integer of different size
r46kstub.c:624: warning: cast to pointer from integer of different size
r46kstub.c:628: warning: cast to pointer from integer of different size
r46kstub.c:635: warning: cast to pointer from integer of different size
r46kstub.c:637: warning: cast to pointer from integer of different size
mips64orion-idt-elf-gcc -g -Wa,-ahld -Wall -membedded-data \
-O3 -c stubinit.S >stubinit.L
mips64orion-idt-elf-ld -t -s -T r46kstub.ld -Map r46kstub.map -o r46kstub.out
mips64orion-idt-elf-ld: mode elf32bmip
stubinit.o
r46kstub.o
mips64orion-idt-elf-objcopy -S -R .bss -R .data -R .reginfo \
-O srec r46kstub.out r46kstub.hex
```
Limitations: stubinit.S deliberately forces the PC (which is a 64-bit
register) to contain a legitimate sign-extended 32-bit value. This was
done to cope with a bug in gdb-4.16, which does _not_ properly sign-extend
the initial PC when it loads a program. This means that you cannot use
the "set" command to load an unmapped sixty-four bit virtual address into
the PC, as you can for all other registers.
Please send bug reports, comments, or suggestions for improvement to:
-194
View File
@@ -1,194 +0,0 @@
/**
* @file
* @ingroup mips_gdb
* @brief Definition of the interface between stub and gdb
*/
/*
* gdb_if.h - definition of the interface between the stub and gdb
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* The following software is offered for use in the public domain.
* There is no warranty with regard to this software or its performance
* and the user must accept the software "AS IS" with all faults.
*
* THE CONTRIBUTORS DISCLAIM 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.
*/
/**
* @defgroup mips_gdb GDB Interface
* @ingroup RTEMSBSPsMIPSShared
* @brief GDB Interface
* @{
*/
#ifndef _GDB_IF_H
#define _GDB_IF_H
/** @brief Max number of threads in qM response */
#define QM_MAX_THREADS (20)
struct rtems_gdb_stub_thread_info {
char display[256];
char name[256];
char more_display[256];
};
/**
* @name Prototypes
* @{
*/
int parse_zbreak(const char *in, int *type, unsigned char **addr, int *len);
char* mem2hstr(char *buf, const unsigned char *mem, int count);
int hstr2mem(unsigned char *mem, const char *buf, int count);
void set_mem_err(void);
unsigned char get_byte(const unsigned char *ptr);
void set_byte(unsigned char *ptr, int val);
char* thread2vhstr(char *buf, int thread);
char* thread2fhstr(char *buf, int thread);
const char* fhstr2thread(const char *buf, int *thread);
const char* vhstr2thread(const char *buf, int *thread);
char* int2fhstr(char *buf, int val);
char* int2vhstr(char *buf, int vali);
const char* fhstr2int(const char *buf, int *ival);
const char* vhstr2int(const char *buf, int *ival);
int hstr2byte(const char *buf, int *bval);
int hstr2nibble(const char *buf, int *nibble);
Thread_Control *rtems_gdb_index_to_stub_id(int);
int rtems_gdb_stub_thread_support_ok(void);
int rtems_gdb_stub_get_current_thread(void);
int rtems_gdb_stub_get_next_thread(int);
int rtems_gdb_stub_get_offsets(
unsigned char **text_addr,
unsigned char **data_addr,
unsigned char **bss_addr
);
int rtems_gdb_stub_get_thread_regs(
int thread,
unsigned int *registers
);
int rtems_gdb_stub_set_thread_regs(
int thread,
unsigned int *registers
);
void rtems_gdb_process_query(
char *inbuffer,
char *outbuffer,
int do_threads,
int thread
);
/** @} */
/**
* @name MIPS registers
* @brief Numbered in the order in which gdb expects to see them.
* @{
*/
#define ZERO 0
#define AT 1
#define V0 2
#define V1 3
#define A0 4
#define A1 5
#define A2 6
#define A3 7
#define T0 8
#define T1 9
#define T2 10
#define T3 11
#define T4 12
#define T5 13
#define T6 14
#define T7 15
#define S0 16
#define S1 17
#define S2 18
#define S3 19
#define S4 20
#define S5 21
#define S6 22
#define S7 23
#define T8 24
#define T9 25
#define K0 26
#define K1 27
#define GP 28
#define SP 29
#define S8 30
#define RA 31
#define SR 32
#define LO 33
#define HI 34
#define BAD_VA 35
#define CAUSE 36
#define PC 37
#define F0 38
#define F1 39
#define F2 40
#define F3 41
#define F4 42
#define F5 43
#define F6 44
#define F7 45
#define F8 46
#define F9 47
#define F10 48
#define F11 49
#define F12 50
#define F13 51
#define F14 52
#define F15 53
#define F16 54
#define F17 55
#define F18 56
#define F19 57
#define F20 58
#define F21 59
#define F22 60
#define F23 61
#define F24 62
#define F25 63
#define F26 64
#define F27 65
#define F28 66
#define F29 67
#define F30 68
#define F31 69
#define FCSR 70
#define FIRR 71
#define NUM_REGS 72
/** @} */
void mips_gdb_stub_install(int enableThreads) ;
#define MEMOPT_READABLE 1
#define MEMOPT_WRITEABLE 2
#ifndef NUM_MEMSEGS
#define NUM_MEMSEGS 10
#endif
int gdbstub_add_memsegment(unsigned,unsigned,int);
/** @} */
#endif /* _GDB_IF_H */
-100
View File
@@ -1,100 +0,0 @@
/**
* @file
* @ingroup mips_limits
* @brief Definition of machine and system dependent address limits.
*/
/*
* limits.h - definition of machine & system dependent address limits
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* The following software is offered for use in the public domain.
* There is no warranty with regard to this software or its performance
* and the user must accept the software "AS IS" with all faults.
*
* THE CONTRIBUTORS DISCLAIM 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.
*/
#ifndef _MEMLIMITS_H_
#define _MEMLIMITS_H_
/*
* The macros in this file are specific to a given implementation.
* The general rules for their construction are as follows:
*
* 1.) is_readable(addr,length) should be true if and only if the
* region starting at the given virtual address can be read
* _without_ causing an exception or other fatal error. Note
* that the stub will use the strictest alignment satisfied
* by _both_ addr and length (e.g., if both are divisible by
* 8 then the region will be read in double-word chunks).
*
* 2.) is_writeable(addr,length) should be true if and only if the
* region starting at the given virtual address can be written
* _without_ causing an exception or other fatal error. Note
* that the stub will use the strictest alignment satisfied
* by _both_ addr and length (e.g., if both are divisible by
* 8 then the region will be written in double-word chunks).
*
* 3.) is-steppable(ptr) whould be true if and only if ptr is the
* address of a writeable region of memory which may contain
* an executable instruction. At a minimum this requires that
* ptr be word-aligned (divisible by 4) and not point to EPROM
* or memory-mapped I/O.
*
* Note: in order to satisfy constraints related to cacheability
* of certain memory subsystems it may be necessary for regions
* of kseg0 and kseg1 which map to the same physical addresses
* to have different readability and/or writeability attributes.
*/
/**
* @defgroup mips_limits Address Limits
* @ingroup RTEMSBSPsMIPSShared
* @brief Address Limits
*/
/*
#define K0_LIMIT_FOR_READ (K0BASE+0x18000000)
#define K1_LIMIT_FOR_READ (K1BASE+K1SIZE)
#define is_readable(addr,length) \
(((K0BASE <= addr) && ((addr + length) <= K0_LIMIT_FOR_READ)) \
|| ((K1BASE <= addr) && ((addr + length) <= K1_LIMIT_FOR_READ)))
#define K0_LIMIT_FOR_WRITE (K0BASE+0x08000000)
#define K1_LIMIT_FOR_WRITE (K1BASE+0x1e000000)
#define is_writeable(addr,length) \
(((K0BASE <= addr) && ((addr + length) <= K0_LIMIT_FOR_WRITE)) \
|| ((K1BASE <= addr) && ((addr + length) <= K1_LIMIT_FOR_WRITE)))
#define K0_LIMIT_FOR_STEP (K0BASE+0x08000000)
#define K1_LIMIT_FOR_STEP (K1BASE+0x08000000)
#define is_steppable(ptr) \
((((int)ptr & 0x3) == 0) \
&& (((K0BASE <= (int)ptr) && ((int)ptr < K0_LIMIT_FOR_STEP)) \
|| ((K1BASE <= (int)ptr) && ((int)ptr < K1_LIMIT_FOR_STEP))))
struct memseg
{
unsigned begin, end, opts;
};
#define MEMOPT_READABLE 1
#define MEMOPT_WRITEABLE 2
#define NUM_MEMSEGS 10
int add_memsegment(unsigned,unsigned,int);
int is_readable(unsigned,unsigned);
int is_writeable(unsigned,unsigned);
int is_steppable(unsigned);
*/
#endif /* _MEMLIMITS_H_ */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+6 -83
View File
@@ -115,7 +115,6 @@
/* #define INSTRUMENT_EXECUTING_THREAD */
/* Ifdefs prevent the duplication of code for MIPS ISA Level 3 ( R4xxx )
* and MIPS ISA Level 1 (R3xxx).
*/
@@ -471,8 +470,7 @@ FRAME(_CPU_Context_switch,sp,0,ra)
/*
** this code grabs the userspace EPC if we're dispatching from
** an interrupt frame or supplies the address of the dispatch
** routines if not. This is entirely for the gdbstub's benefit so
** it can know where each task is running.
** routines if not, so the context records where each task runs.
**
** Its value is only set when calling threadDispatch from
** the interrupt handler and is cleared immediately when this
@@ -716,8 +714,6 @@ _ISR_Handler_Exception:
* bad is going on and we can continue to run normally.
* But we want to save the entire CPU context so exception
* handlers can look at it and change it.
*
* NOTE: This is the path the debugger stub will take.
*/
/* already got t0 = cause in the interrupt test above */
@@ -778,67 +774,8 @@ _ISR_Handler_Exception:
** this is not done, we might get stuck in an infinite loop because
** we'll return to the instruction where the exception occurred and
** it could throw again.
**
** It is expected the only code using the exception processing is
** either the gdb stub or some user code which is either going to
** panic or do something useful. Regardless, it is up to each
** exception routine to properly adjust EPC, so the code below
** may be helpful for doing just that.
*/
/* *********************************************************************
** this code follows the R3000's exception return logic, but is not
** needed because the gdb stub does it for us. It might be useful
** for something else at some point...
**
* compute the address of the instruction we'll return to *
LDREG t1, R_CAUSE*R_SZ(sp)
LDREG t0, R_EPC*R_SZ(sp)
* first see if the exception happened in the delay slot *
li t3,CAUSE_BD
AND t4,t1,t3
beqz t4,excnodelay
NOP
* it did, now see if the branch occurred or not *
li t3,CAUSE_BT
AND t4,t1,t3
beqz t4,excnobranch
NOP
* branch was taken, we resume at the branch target *
LDREG t0, R_TAR*R_SZ(sp)
j excreturn
NOP
excnobranch:
ADDU t0,R_SZ
excnodelay:
ADDU t0,R_SZ
excreturn:
STREG t0, R_EPC*R_SZ(sp)
NOP
********************************************************************* */
/* if we're returning into mips_break, move to the next instruction */
LDREG t0,R_EPC*R_SZ(sp)
la t1,mips_break
xor t2,t0,t1
bnez t2,3f
addu t0,R_SZ
STREG t0,R_EPC*R_SZ(sp)
NOP
3:
#if ( CPU_HARDWARE_FP == TRUE )
mfc0 t0,C0_SR /* FPU is enabled, restore state */
@@ -871,11 +808,11 @@ excreturn:
/*
** Jump all the way out. If theres a pending interrupt, just
** let it be serviced later. Since we're probably using the
** gdb stub, we've already disrupted the ISR service timing
** anyhow. We oughtn't mix exception and interrupt processing
** in the same exception call in case the exception stuff
** might interfere with the dispatching & timer ticks.
** let it be serviced later. An exception handler has already
** disrupted the ISR service timing anyhow. We oughtn't mix
** exception and interrupt processing in the same exception call
** in case the exception stuff might interfere with the
** dispatching & timer ticks.
*/
j _ISR_Handler_exit
NOP
@@ -975,7 +912,6 @@ _ISR_Handler_1:
NOP
#ifdef INSTRUMENT_EXECUTING_THREAD
lw t0,THREAD_EXECUTING
NOP
@@ -1062,10 +998,6 @@ _ISR_Handler_1:
#endif
#ifdef INSTRUMENT_EXECUTING_THREAD
lw t0,THREAD_EXECUTING
NOP
@@ -1143,12 +1075,3 @@ _ISR_Handler_exit:
ENDFRAME(_ISR_Handler)
FRAME(mips_break,sp,0,ra)
.set noreorder
break 0x0 /* this statement must be first in this function, assumed so by mips-stub.c */
NOP
j ra
NOP
.set reorder
ENDFRAME(mips_break)
@@ -744,7 +744,6 @@ void _CPU_Context_Initialize(
/* end of Context handler macros */
extern void mips_break( int error );
#define CPU_USE_GENERIC_BITFIELD_CODE TRUE