summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/mips
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 12:06:14 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:45 +0200
commitfd67814e06a734cd0d78274d61fc04c7af79b5fc (patch)
tree2cbbf85bb5445a1c42c2c93658e3a207ac1d99ac /c/src/lib/libbsp/mips
parentbsps/v850: Move crt1.c to bsps (diff)
downloadrtems-fd67814e06a734cd0d78274d61fc04c7af79b5fc.tar.bz2
bsps: Move GDB stubs to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/mips')
-rw-r--r--c/src/lib/libbsp/mips/shared/gdbstub/README151
-rw-r--r--c/src/lib/libbsp/mips/shared/gdbstub/gdb_if.h194
-rw-r--r--c/src/lib/libbsp/mips/shared/gdbstub/memlimits.h100
-rw-r--r--c/src/lib/libbsp/mips/shared/gdbstub/mips-stub.c1589
-rw-r--r--c/src/lib/libbsp/mips/shared/gdbstub/mips_opcode.h336
5 files changed, 0 insertions, 2370 deletions
diff --git a/c/src/lib/libbsp/mips/shared/gdbstub/README b/c/src/lib/libbsp/mips/shared/gdbstub/README
deleted file mode 100644
index e61d0f0aa5..0000000000
--- a/c/src/lib/libbsp/mips/shared/gdbstub/README
+++ /dev/null
@@ -1,151 +0,0 @@
-/*****************************************************/
-
-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.
-
---joel
-8 February 2002
-
-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:
-
-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:
diff --git a/c/src/lib/libbsp/mips/shared/gdbstub/gdb_if.h b/c/src/lib/libbsp/mips/shared/gdbstub/gdb_if.h
deleted file mode 100644
index ba4f0eb757..0000000000
--- a/c/src/lib/libbsp/mips/shared/gdbstub/gdb_if.h
+++ /dev/null
@@ -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 mips_shared
- * @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 */
diff --git a/c/src/lib/libbsp/mips/shared/gdbstub/memlimits.h b/c/src/lib/libbsp/mips/shared/gdbstub/memlimits.h
deleted file mode 100644
index c60ca12111..0000000000
--- a/c/src/lib/libbsp/mips/shared/gdbstub/memlimits.h
+++ /dev/null
@@ -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 mips_shared
- * @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_ */
diff --git a/c/src/lib/libbsp/mips/shared/gdbstub/mips-stub.c b/c/src/lib/libbsp/mips/shared/gdbstub/mips-stub.c
deleted file mode 100644
index 8320eb66a9..0000000000
--- a/c/src/lib/libbsp/mips/shared/gdbstub/mips-stub.c
+++ /dev/null
@@ -1,1589 +0,0 @@
-#define GDB_STUB_ENABLE_THREAD_SUPPORT 1
-/*******************************************************************************
-
- 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.
-
-********************************************************************************
-*
-* r46kstub.c -- target debugging stub for the IDT R4600 Orion processor
-*
-* This module is based on the stub for the Hitachi SH processor written by
-* Ben Lee and Steve Chamberlain and supplied with gdb 4.16. The latter
-* in turn "is originally based on an m68k software stub written by Glenn
-* Engel at HP, but has changed quite a bit." The changes for the R4600
-* were written by C. M. Heard at VVNET. They were based in part on the
-* Algorithmics R4000 version of Phil Bunce's PMON program.
-*
-* Remote communication protocol:
-*
-* A debug packet whose contents are <data>
-* is encapsulated for transmission in the form:
-*
-* $ <data> # CSUM1 CSUM2
-*
-* <data> must be ASCII alphanumeric and cannot include characters
-* '$' or '#'. If <data> starts with two characters followed by
-* ':', then the existing stubs interpret this as a sequence number.
-*
-* CSUM1 and CSUM2 are ascii hex representation of an 8-bit
-* checksum of <data>, the most significant nibble is sent first.
-* the hex digits 0-9,a-f are used.
-*
-* Receiver responds with:
-*
-* + if CSUM is correct
-* - if CSUM is incorrect
-*
-* <data> is as follows. All values are encoded in ascii hex digits.
-*
-* Request Packet
-*
-* read registers g
-* reply XX....X Each byte of register data
-* is described by two hex digits.
-* Registers are in the internal order
-* for GDB, and the bytes in a register
-* are in the same order the machine uses.
-* or ENN for an error.
-*
-* write regs GXX..XX Each byte of register data
-* is described by two hex digits.
-* reply OK for success
-* ENN for an error
-*
-* write reg Pn...=r... Write register n... with value r....
-* reply OK for success
-* ENN for an error
-*
-* read mem mAA..AA,LLLL AA..AA is address, LLLL is length.
-* reply XX..XX XX..XX is mem contents
-* Can be fewer bytes than requested
-* if able to read only part of the data.
-* or ENN NN is errno
-*
-* write mem MAA..AA,LLLL:XX..XX
-* AA..AA is address,
-* LLLL is number of bytes,
-* XX..XX is data
-* reply OK for success
-* ENN for an error (this includes the case
-* where only part of the data was
-* written).
-*
-* cont cAA..AA AA..AA is address to resume
-* If AA..AA is omitted,
-* resume at same address.
-*
-* step sAA..AA AA..AA is address to resume
-* If AA..AA is omitted,
-* resume at same address.
-*
-* There is no immediate reply to step or cont.
-* The reply comes when the machine stops.
-* It is SAA AA is the "signal number"
-*
-* last signal ? Reply with the reason for stopping.
-* This is the same reply as is generated
-* for step or cont: SAA where AA is the
-* signal number.
-*
-* detach D Host is detaching. Reply OK and
-* end remote debugging session.
-*
-* reserved <other> On other requests, the stub should
-* ignore the request and send an empty
-* response ($#<checksum>). This way
-* we can extend the protocol and GDB
-* can tell whether the stub it is
-* talking to uses the old or the new.
-*
-* Responses can be run-length encoded to save space. A '*' means that
-* the next character is an ASCII encoding giving a repeat count which
-* stands for that many repetitions of the character preceding the '*'.
-* The encoding is n+29, yielding a printable character when n >=3
-* (which is where rle starts to win). Don't use n > 99 since gdb
-* masks each character is receives with 0x7f in order to strip off
-* the parity bit.
-*
-* As an example, "0* " means the same thing as "0000".
-*
-*******************************************************************************/
-
-
-#include <string.h>
-#include <signal.h>
-#include "mips_opcode.h"
-/* #include "memlimits.h" */
-#include <rtems.h>
-#include <rtems/bspIo.h>
-#include "gdb_if.h"
-
-/* Change it to something meaningful when debugging */
-#undef ASSERT
-#define ASSERT(x) if(!(x)) printk("ASSERT: stub: %d\n", __LINE__)
-
-/***************/
-/* Exception Codes */
-#define EXC_INT 0 /* External interrupt */
-#define EXC_MOD 1 /* TLB modification exception */
-#define EXC_TLBL 2 /* TLB miss (Load or Ifetch) */
-#define EXC_TLBS 3 /* TLB miss (Store) */
-#define EXC_ADEL 4 /* Address error (Load or Ifetch) */
-#define EXC_ADES 5 /* Address error (Store) */
-#define EXC_IBE 6 /* Bus error (Ifetch) */
-#define EXC_DBE 7 /* Bus error (data load or store) */
-#define EXC_SYS 8 /* System call */
-#define EXC_BP 9 /* Break point */
-#define EXC_RI 10 /* Reserved instruction */
-#define EXC_CPU 11 /* Coprocessor unusable */
-#define EXC_OVF 12 /* Arithmetic overflow */
-#define EXC_TRAP 13 /* Trap exception */
-#define EXC_FPE 15 /* Floating Point Exception */
-
-/* FPU Control/Status register fields */
-#define CSR_FS 0x01000000 /* Set to flush denormals to zero */
-#define CSR_C 0x00800000 /* Condition bit (set by FP compare) */
-
-#define CSR_CMASK (0x3f<<12)
-#define CSR_CE 0x00020000
-#define CSR_CV 0x00010000
-#define CSR_CZ 0x00008000
-#define CSR_CO 0x00004000
-#define CSR_CU 0x00002000
-#define CSR_CI 0x00001000
-
-#define CSR_EMASK (0x1f<<7)
-#define CSR_EV 0x00000800
-#define CSR_EZ 0x00000400
-#define CSR_EO 0x00000200
-#define CSR_EU 0x00000100
-#define CSR_EI 0x00000080
-
-#define CSR_FMASK (0x1f<<2)
-#define CSR_FV 0x00000040
-#define CSR_FZ 0x00000020
-#define CSR_FO 0x00000010
-#define CSR_FU 0x00000008
-#define CSR_FI 0x00000004
-
-#define CSR_RMODE_MASK (0x3<<0)
-#define CSR_RM 0x00000003
-#define CSR_RP 0x00000002
-#define CSR_RZ 0x00000001
-#define CSR_RN 0x00000000
-
-/***************/
-
-/*
- * Saved register information. Must be prepared by the exception
- * preprocessor before handle_exception is invoked.
- */
-#if (__mips == 3)
-typedef long long mips_register_t;
-#define R_SZ 8
-#elif (__mips == 1)
-typedef unsigned int mips_register_t;
-#define R_SZ 4
-#else
-#error "unknown MIPS ISA"
-#endif
-static mips_register_t *registers;
-
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
-static char do_threads; /* != 0 means we are supporting threads */
-#endif
-
-/*
- * The following external functions provide character input and output.
- */
-extern char getDebugChar (void);
-extern void putDebugChar (char);
-
-/*
- * Exception handler
- */
-void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame);
-
-/*
- * Prototype needed by this code and to keep it self contained.
- */
-void rtems_interrupt_catch( rtems_isr_entry, int, rtems_isr_entry *);
-
-/*
- * The following definitions are used for the gdb stub memory map
- */
-struct memseg
-{
- unsigned begin, end, opts;
-};
-
-static int is_readable(unsigned,unsigned);
-static int is_writeable(unsigned,unsigned);
-static int is_steppable(unsigned);
-
-/*
- * BUFMAX defines the maximum number of characters in the inbound & outbound
- * packet buffers. At least 4+(sizeof registers)*2 bytes will be needed for
- * register packets. Memory dump packets can profitably use even more.
- */
-#define BUFMAX 1500
-
-static char inBuffer[BUFMAX];
-static char outBuffer[BUFMAX];
-
-/* Structure to keep info on a z-breaks */
-#define BREAKNUM 32
-
-struct z0break
-{
- /* List support */
- struct z0break *next;
- struct z0break *prev;
-
- /* Location, preserved data */
-
- /* the address pointer, really, really must be a pointer to
- ** a 32 bit quantity (likely 64 on the R4k), so the full instruction is read &
- ** written. Making it a char * as on the i386 will cause
- ** the zbreaks to mess up the breakpoint instructions
- */
- unsigned char *address;
- unsigned instr;
-};
-
-static struct z0break z0break_arr[BREAKNUM];
-static struct z0break *z0break_avail = NULL;
-static struct z0break *z0break_list = NULL;
-
-
-/*
- * Convert an int to hex.
- */
-const char gdb_hexchars[] = "0123456789abcdef";
-
-#define highhex(x) gdb_hexchars [(x >> 4) & 0xf]
-#define lowhex(x) gdb_hexchars [x & 0xf]
-
-/*
- * Convert length bytes of data starting at addr into hex, placing the
- * result in buf. Return a pointer to the last (null) char in buf.
- */
-static char *
-mem2hex (void *_addr, int length, char *buf)
-{
- unsigned int addr = (unsigned int) _addr;
-
- if (((addr & 0x7) == 0) && ((length & 0x7) == 0)) /* dword aligned */
- {
- long long *source = (long long *) (addr);
- long long *limit = (long long *) (addr + length);
-
- while (source < limit)
- {
- int i;
- long long k = *source++;
-
- for (i = 15; i >= 0; i--)
- *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
- }
- }
- else if (((addr & 0x3) == 0) && ((length & 0x3) == 0)) /* word aligned */
- {
- int *source = (int *) (addr);
- int *limit = (int *) (addr + length);
-
- while (source < limit)
- {
- int i;
- int k = *source++;
-
- for (i = 7; i >= 0; i--)
- *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
- }
- }
- else if (((addr & 0x1) == 0) && ((length & 0x1) == 0)) /* halfword aligned */
- {
- short *source = (short *) (addr);
- short *limit = (short *) (addr + length);
-
- while (source < limit)
- {
- int i;
- short k = *source++;
-
- for (i = 3; i >= 0; i--)
- *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
- }
- }
- else /* byte aligned */
- {
- char *source = (char *) (addr);
- char *limit = (char *) (addr + length);
-
- while (source < limit)
- {
- int i;
- char k = *source++;
-
- for (i = 1; i >= 0; i--)
- *buf++ = gdb_hexchars [(k >> (i*4)) & 0xf];
- }
- }
-
- *buf = '\0';
- return (buf);
-}
-
-
-/*
- * Convert a hex character to an int.
- */
-static int
-hex (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);
-}
-
-/*
- * Convert a string from hex to int until a non-hex digit
- * is found. Return the number of characters processed.
- */
-static int
-hexToInt (char **ptr, int *intValue)
-{
- int numChars = 0;
- int hexValue;
-
- *intValue = 0;
-
- while (**ptr)
- {
- hexValue = hex (**ptr);
- if (hexValue >= 0)
- {
- *intValue = (*intValue << 4) | hexValue;
- numChars++;
- }
- else
- break;
-
- (*ptr)++;
- }
-
- return (numChars);
-}
-
-/*
- * Convert a string from hex to long long until a non-hex
- * digit is found. Return the number of characters processed.
- */
-static int
-hexToLongLong (char **ptr, long long *intValue)
-{
- int numChars = 0;
- int hexValue;
-
- *intValue = 0;
-
- while (**ptr)
- {
- hexValue = hex (**ptr);
- if (hexValue >= 0)
- {
- *intValue = (*intValue << 4) | hexValue;
- numChars++;
- }
- else
- break;
-
- (*ptr)++;
- }
-
- return (numChars);
-}
-
-/*
- * Convert the hex array buf into binary, placing the result at the
- * specified address. If the conversion fails at any point (i.e.,
- * if fewer bytes are written than indicated by the size parameter)
- * then return 0; otherwise return 1.
- */
-static int
-hex2mem (char *buf, void *_addr, int length)
-{
- unsigned int addr = (unsigned int) _addr;
- if (((addr & 0x7) == 0) && ((length & 0x7) == 0)) /* dword aligned */
- {
- long long *target = (long long *) (addr);
- long long *limit = (long long *) (addr + length);
-
- while (target < limit)
- {
- int i, j;
- long long k = 0;
-
- for (i = 0; i < 16; i++)
- if ((j = hex(*buf++)) < 0)
- return 0;
- else
- k = (k << 4) + j;
- *target++ = k;
- }
- }
- else if (((addr & 0x3) == 0) && ((length & 0x3) == 0)) /* word aligned */
- {
- int *target = (int *) (addr);
- int *limit = (int *) (addr + length);
-
- while (target < limit)
- {
- int i, j;
- int k = 0;
-
- for (i = 0; i < 8; i++)
- if ((j = hex(*buf++)) < 0)
- return 0;
- else
- k = (k << 4) + j;
- *target++ = k;
- }
- }
- else if (((addr & 0x1) == 0) && ((length & 0x1) == 0)) /* halfword aligned */
- {
- short *target = (short *) (addr);
- short *limit = (short *) (addr + length);
-
- while (target < limit)
- {
- int i, j;
- short k = 0;
-
- for (i = 0; i < 4; i++)
- if ((j = hex(*buf++)) < 0)
- return 0;
- else
- k = (k << 4) + j;
- *target++ = k;
- }
- }
- else /* byte aligned */
- {
- char *target = (char *) (addr);
- char *limit = (char *) (addr + length);
-
- while (target < limit)
- {
- int i, j;
- char k = 0;
-
- for (i = 0; i < 2; i++)
- if ((j = hex(*buf++)) < 0)
- return 0;
- else
- k = (k << 4) + j;
- *target++ = k;
- }
- }
-
- return 1;
-}
-
-/* Convert the binary stream in BUF to memory.
-
- Gdb will escape $, #, and the escape char (0x7d).
- COUNT is the total number of bytes to write into
- memory. */
-static unsigned char *
-bin2mem (
- char *buf,
- unsigned char *mem,
- int count
-)
-{
- int i;
-
- for (i = 0; i < count; i++) {
- /* Check for any escaped characters. Be paranoid and
- only unescape chars that should be escaped. */
- if (*buf == 0x7d) {
- switch (*(buf+1)) {
- case 0x3: /* # */
- case 0x4: /* $ */
- case 0x5d: /* escape char */
- buf++;
- *buf |= 0x20;
- break;
- default:
- /* nothing */
- break;
- }
- }
-
- *mem++ = *buf++;
- }
-
- return mem;
-}
-
-
-/*
- * Scan the input stream for a sequence for the form $<data>#<checksum>.
- */
-static void
-getpacket (char *buffer)
-{
- unsigned char checksum;
- unsigned char xmitcsum;
- int i;
- int count;
- char ch;
- do
- {
- /* wait around for the start character, ignore all other characters */
- while ((ch = getDebugChar ()) != '$');
- checksum = 0;
- xmitcsum = -1;
-
- count = 0;
-
- /* now, read until a # or end of buffer is found */
- while ( (count < BUFMAX-1) && ((ch = getDebugChar ()) != '#') )
- checksum += (buffer[count++] = ch);
-
- /* make sure that the buffer is null-terminated */
- buffer[count] = '\0';
-
- if (ch == '#')
- {
- xmitcsum = hex (getDebugChar ()) << 4;
- xmitcsum += hex (getDebugChar ());
- if (checksum != xmitcsum)
- putDebugChar ('-'); /* failed checksum */
- else
- {
- putDebugChar ('+'); /* successful transfer */
- /* if a sequence char is present, reply the sequence ID */
- if (buffer[2] == ':')
- {
- putDebugChar (buffer[0]);
- putDebugChar (buffer[1]);
- /* remove sequence chars from buffer */
- for (i = 3; i <= count; i++)
- buffer[i - 3] = buffer[i];
- }
- }
- }
- }
- while (checksum != xmitcsum);
-}
-
-/*
- * Get a positive/negative acknowledgment for a transmitted packet.
- */
-static char
-getAck (void)
-{
- char c;
-
- do
- {
- c = getDebugChar ();
- }
- while ((c != '+') && (c != '-'));
-
- return c;
-}
-
-/*
- * Send the packet in buffer and wait for a positive acknowledgement.
- */
-static void
-putpacket (char *buffer)
-{
- int checksum;
-
- /* $<packet info>#<checksum> */
- do
- {
- char *src = buffer;
- putDebugChar ('$');
- checksum = 0;
-
- while (*src != '\0')
- {
- int runlen = 0;
-
- /* Do run length encoding */
- while ((src[runlen] == src[0]) && (runlen < 99))
- runlen++;
- if (runlen > 3)
- {
- int encode;
- /* Got a useful amount */
- putDebugChar (*src);
- checksum += *src;
- putDebugChar ('*');
- checksum += '*';
- checksum += (encode = (runlen - 4) + ' ');
- putDebugChar (encode);
- src += runlen;
- }
- else
- {
- putDebugChar (*src);
- checksum += *src;
- src++;
- }
- }
-
- putDebugChar ('#');
- putDebugChar (highhex (checksum));
- putDebugChar (lowhex (checksum));
- }
- while (getAck () != '+');
-}
-
-
-/*
- * Saved instruction data for single step support
- */
-static struct
- {
- unsigned *targetAddr;
- unsigned savedInstr;
- }
-instrBuffer;
-
-/*
- * If a step breakpoint was planted restore the saved instruction.
- */
-static void
-undoSStep (void)
-{
- if (instrBuffer.targetAddr != NULL)
- {
- *instrBuffer.targetAddr = instrBuffer.savedInstr;
- instrBuffer.targetAddr = NULL;
- }
- instrBuffer.savedInstr = NOP_INSTR;
-}
-
-/*
- * If a single step is requested put a temporary breakpoint at the instruction
- * which logically follows the next one to be executed. If the next instruction
- * is a branch instruction then skip the instruction in the delay slot. NOTE:
- * ERET instructions are NOT handled, as it is impossible to single-step through
- * the exit code in an exception handler. In addition, no attempt is made to
- * do anything about BC0T and BC0F, since a condition bit for coprocessor 0
- * is not defined on the R4600. Finally, BC2T and BC2F are ignored since there
- * is no coprocessor 2 on a 4600.
- */
-static void
-doSStep (void)
-{
- InstFmt inst;
-
- instrBuffer.targetAddr = (unsigned *)(registers[PC]+4); /* set default */
-
- inst.word = *(unsigned *)registers[PC]; /* read the next instruction */
-
- switch (inst.RType.op) { /* override default if branch */
- case OP_SPECIAL:
- switch (inst.RType.func) {
- case OP_JR:
- case OP_JALR:
- instrBuffer.targetAddr =
- (unsigned *)registers[inst.RType.rs];
- break;
- };
- break;
-
- case OP_REGIMM:
- switch (inst.IType.rt) {
- case OP_BLTZ:
- case OP_BLTZL:
- case OP_BLTZAL:
- case OP_BLTZALL:
- if (registers[inst.IType.rs] < 0 )
- instrBuffer.targetAddr =
- (unsigned *)(((signed short)inst.IType.imm<<2)
- + (registers[PC]+4));
- else
- instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
- break;
- case OP_BGEZ:
- case OP_BGEZL:
- case OP_BGEZAL:
- case OP_BGEZALL:
- if (registers[inst.IType.rs] >= 0 )
- instrBuffer.targetAddr =
- (unsigned *)(((signed short)inst.IType.imm<<2)
- + (registers[PC]+4));
- else
- instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
- break;
- };
- break;
-
- case OP_J:
- case OP_JAL:
- instrBuffer.targetAddr =
- (unsigned *)((inst.JType.target<<2) + ((registers[PC]+4)&0xf0000000));
- break;
-
- case OP_BEQ:
- case OP_BEQL:
- if (registers[inst.IType.rs] == registers[inst.IType.rt])
- instrBuffer.targetAddr =
- (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
- else
- instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
- break;
- case OP_BNE:
- case OP_BNEL:
- if (registers[inst.IType.rs] != registers[inst.IType.rt])
- instrBuffer.targetAddr =
- (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
- else
- instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
- break;
- case OP_BLEZ:
- case OP_BLEZL:
- if (registers[inst.IType.rs] <= 0)
- instrBuffer.targetAddr =
- (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
- else
- instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
- break;
- case OP_BGTZ:
- case OP_BGTZL:
- if (registers[inst.IType.rs] > 0)
- instrBuffer.targetAddr =
- (unsigned *)(((signed short)inst.IType.imm<<2) + (registers[PC]+4));
- else
- instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
- break;
-
- case OP_COP1:
- if (inst.RType.rs == OP_BC)
- switch (inst.RType.rt) {
- case COPz_BCF:
- case COPz_BCFL:
- if (registers[FCSR] & CSR_C)
- instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
- else
- instrBuffer.targetAddr =
- (unsigned *)(((signed short)inst.IType.imm<<2)
- + (registers[PC]+4));
- break;
- case COPz_BCT:
- case COPz_BCTL:
- if (registers[FCSR] & CSR_C)
- instrBuffer.targetAddr =
- (unsigned *)(((signed short)inst.IType.imm<<2)
- + (registers[PC]+4));
- else
- instrBuffer.targetAddr = (unsigned*)(registers[PC]+8);
- break;
- };
- break;
- }
-
- if( is_steppable((unsigned)instrBuffer.targetAddr) && *(instrBuffer.targetAddr) != BREAK_INSTR )
- {
- instrBuffer.savedInstr = *instrBuffer.targetAddr;
- *instrBuffer.targetAddr = BREAK_INSTR;
- }
- else
- {
- instrBuffer.targetAddr = NULL;
- instrBuffer.savedInstr = NOP_INSTR;
- }
- return;
-}
-
-
-/*
- * Translate the R4600 exception code into a Unix-compatible signal.
- */
-static int
-computeSignal (void)
-{
- int exceptionCode = (registers[CAUSE] & CAUSE_EXCMASK) >> CAUSE_EXCSHIFT;
-
- switch (exceptionCode)
- {
- case EXC_INT:
- /* External interrupt */
- return SIGINT;
-
- case EXC_RI:
- /* Reserved instruction */
- case EXC_CPU:
- /* Coprocessor unusable */
- return SIGILL;
-
- case EXC_BP:
- /* Break point */
- return SIGTRAP;
-
- case EXC_OVF:
- /* Arithmetic overflow */
- case EXC_TRAP:
- /* Trap exception */
- case EXC_FPE:
- /* Floating Point Exception */
- return SIGFPE;
-
- case EXC_IBE:
- /* Bus error (Ifetch) */
- case EXC_DBE:
- /* Bus error (data load or store) */
- return SIGBUS;
-
- case EXC_MOD:
- /* TLB modification exception */
- case EXC_TLBL:
- /* TLB miss (Load or Ifetch) */
- case EXC_TLBS:
- /* TLB miss (Store) */
- case EXC_ADEL:
- /* Address error (Load or Ifetch) */
- case EXC_ADES:
- /* Address error (Store) */
- return SIGSEGV;
-
- case EXC_SYS:
- /* System call */
- return SIGSYS;
-
- default:
- return SIGTERM;
- }
-}
-
-/*
- * This support function prepares and sends the message containing the
- * basic information about this exception.
- */
-static void gdb_stub_report_exception_info(
- rtems_vector_number vector,
- CPU_Interrupt_frame *frame,
- int thread
-)
-{
- char *optr;
- int sigval;
-
- optr = outBuffer;
- *optr++ = 'T';
- sigval = computeSignal ();
- *optr++ = highhex (sigval);
- *optr++ = lowhex (sigval);
-
- *optr++ = highhex(SP); /*gdb_hexchars[SP]; */
- *optr++ = lowhex(SP);
- *optr++ = ':';
- optr = mem2hstr(optr, (unsigned char *)&frame->sp, R_SZ );
- *optr++ = ';';
-
- *optr++ = highhex(PC); /*gdb_hexchars[PC]; */
- *optr++ = lowhex(PC);
- *optr++ = ':';
- optr = mem2hstr(optr, (unsigned char *)&frame->epc, R_SZ );
- *optr++ = ';';
-
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
- if (do_threads)
- {
- *optr++ = 't';
- *optr++ = 'h';
- *optr++ = 'r';
- *optr++ = 'e';
- *optr++ = 'a';
- *optr++ = 'd';
- *optr++ = ':';
- optr = thread2vhstr(optr, thread);
- *optr++ = ';';
- }
-#endif
- *optr++ = '\0';
-}
-
-
-
-/*
- * Scratch frame used to retrieve contexts for different threads, so as
- * not to disrupt our current context on the stack
- */
-CPU_Interrupt_frame current_thread_registers;
-
-/*
- * This function handles all exceptions. It only does two things:
- * it figures out why it was activated and tells gdb, and then it
- * reacts to gdb's requests.
- */
-
-extern void clear_cache(void);
-void handle_exception (rtems_vector_number vector, CPU_Interrupt_frame *frame)
-{
- int host_has_detached = 0;
- int regno, addr, length;
- char *ptr;
- int current_thread; /* current generic thread */
- int thread; /* stopped thread: context exception happened in */
-
- long long regval;
- void *regptr;
- int binary;
-
- registers = (mips_register_t *)frame;
-
- thread = 0;
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
- if (do_threads) {
- thread = rtems_gdb_stub_get_current_thread();
- }
-#endif
- current_thread = thread;
-
- {
- /* reapply all breakpoints regardless of how we came in */
- struct z0break *z0, *zother;
-
- for (zother=z0break_list; zother!=NULL; zother=zother->next)
- {
- if( zother->instr == 0xffffffff )
- {
- /* grab the instruction */
- zother->instr = *(zother->address);
- /* and insert the breakpoint */
- *(zother->address) = BREAK_INSTR;
- }
- }
-
- /* see if we're coming from a breakpoint */
- if( *((unsigned *)frame->epc) == BREAK_INSTR )
- {
- /* see if its one of our zbreaks */
- for (z0=z0break_list; z0!=NULL; z0=z0->next)
- {
- if( (unsigned)z0->address == frame->epc)
- break;
- }
- if( z0 )
- {
- /* restore the original instruction */
- *(z0->address) = z0->instr;
- /* flag the breakpoint */
- z0->instr = 0xffffffff;
-
- /*
- now when we return, we'll execute the original code in
- the original state. This leaves our breakpoint inactive
- since the break instruction isn't there, but we'll reapply
- it the next time we come in via step or breakpoint
- */
- }
- else
- {
- /* not a zbreak, see if its our trusty stepping code */
-
- /*
- * Restore the saved instruction at
- * the single-step target address.
- */
- undoSStep();
- }
- }
- }
-
- /* reply to host that an exception has occurred with some basic info */
- gdb_stub_report_exception_info(vector, frame, thread);
- putpacket (outBuffer);
-
- while (!(host_has_detached)) {
- outBuffer[0] = '\0';
- getpacket (inBuffer);
- binary = 0;
-
- switch (inBuffer[0]) {
- case '?':
- gdb_stub_report_exception_info(vector, frame, thread);
- break;
-
- case 'd': /* toggle debug flag */
- /* can print ill-formed commands in valid packets & checksum errors */
- break;
-
- case 'D':
- /* remote system is detaching - return OK and exit from debugger */
- strcpy (outBuffer, "OK");
- host_has_detached = 1;
- break;
-
- case 'g': /* return the values of the CPU registers */
- regptr = registers;
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
- if (do_threads && current_thread != thread )
- regptr = &current_thread_registers;
-#endif
- mem2hex (regptr, NUM_REGS * (sizeof registers), outBuffer);
- break;
-
- case 'G': /* set the values of the CPU registers - return OK */
- regptr = registers;
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
- if (do_threads && current_thread != thread )
- regptr = &current_thread_registers;
-#endif
- if (hex2mem (&inBuffer[1], regptr, NUM_REGS * (sizeof registers)))
- strcpy (outBuffer, "OK");
- else
- strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */
- break;
-
- case 'P':
- /* Pn...=r... Write register n... with value r... - return OK */
- ptr = &inBuffer[1];
- if (hexToInt(&ptr, &regno) &&
- *ptr++ == '=' &&
- hexToLongLong(&ptr, &regval))
- {
- registers[regno] = regval;
- strcpy (outBuffer, "OK");
- }
- else
- strcpy (outBuffer, "E00"); /* E00 = bad "set register" command */
- break;
-
- case 'm':
- /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
- ptr = &inBuffer[1];
- if (hexToInt (&ptr, &addr)
- && *ptr++ == ','
- && hexToInt (&ptr, &length)
- && is_readable (addr, length)
- && (length < (BUFMAX - 4)/2))
- mem2hex ((void *)addr, length, outBuffer);
- else
- strcpy (outBuffer, "E01"); /* E01 = bad 'm' command */
- break;
-
- case 'X': /* XAA..AA,LLLL:<binary data>#cs */
- binary = 1;
- case 'M':
- /* MAA..AA,LLLL: Write LLLL bytes at address AA..AA - return OK */
- ptr = &inBuffer[1];
- if (hexToInt (&ptr, &addr)
- && *ptr++ == ','
- && hexToInt (&ptr, &length)
- && *ptr++ == ':'
- && is_writeable (addr, length) ) {
- if ( binary )
- hex2mem (ptr, (void *)addr, length);
- else
- bin2mem (ptr, (void *)addr, length);
- strcpy (outBuffer, "OK");
- }
- else
- strcpy (outBuffer, "E02"); /* E02 = bad 'M' command */
- break;
-
- case 'c':
- /* cAA..AA Continue at address AA..AA(optional) */
- case 's':
- /* sAA..AA Step one instruction from AA..AA(optional) */
- {
- /* try to read optional parameter, pc unchanged if no parm */
- ptr = &inBuffer[1];
- if (hexToInt (&ptr, &addr))
- registers[PC] = addr;
-
- if (inBuffer[0] == 's')
- doSStep ();
- }
- goto stubexit;
-
- case 'k': /* remove all zbreaks if any */
- dumpzbreaks:
- {
- {
- /* Unlink the entire list */
- struct z0break *z0, *znxt;
-
- while( (z0= z0break_list) )
- {
-
- /* put back the instruction */
- if( z0->instr != 0xffffffff )
- *(z0->address) = z0->instr;
-
- /* pop off the top entry */
- znxt = z0->next;
- if( znxt ) znxt->prev = NULL;
- z0break_list = znxt;
-
- /* and put it on the free list */
- z0->prev = NULL;
- z0->next = z0break_avail;
- z0break_avail = z0;
- }
- }
-
- strcpy(outBuffer, "OK");
- }
- break;
-
- case 'q': /* queries */
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
- rtems_gdb_process_query( inBuffer, outBuffer, do_threads, thread );
-#endif
- break;
-
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
- case 'T':
- {
- int testThread;
-
- if( vhstr2thread(&inBuffer[1], &testThread) == NULL )
- {
- strcpy(outBuffer, "E01");
- break;
- }
-
- if( rtems_gdb_index_to_stub_id(testThread) == NULL )
- {
- strcpy(outBuffer, "E02");
- }
- else
- {
- strcpy(outBuffer, "OK");
- }
- }
- break;
-#endif
-
- case 'H': /* set new thread */
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
- if (inBuffer[1] != 'g') {
- break;
- }
-
- if (!do_threads) {
- break;
- }
-
- {
- int tmp, ret;
-
- /* Set new generic thread */
- if (vhstr2thread(&inBuffer[2], &tmp) == NULL) {
- strcpy(outBuffer, "E01");
- break;
- }
-
- /* 0 means `thread' */
- if (tmp == 0) {
- tmp = thread;
- }
-
- if (tmp == current_thread) {
- /* No changes */
- strcpy(outBuffer, "OK");
- break;
- }
-
- /* Save current thread registers if necessary */
- if (current_thread != thread) {
- ret = rtems_gdb_stub_set_thread_regs(
- current_thread,
- (unsigned int *) (void *)&current_thread_registers);
- ASSERT(ret);
- }
-
- /* Read new registers if necessary */
- if (tmp != thread) {
- ret = rtems_gdb_stub_get_thread_regs(
- tmp, (unsigned int *) (void *)&current_thread_registers);
-
- if (!ret) {
- /* Thread does not exist */
- strcpy(outBuffer, "E02");
- break;
- }
- }
-
- current_thread = tmp;
- strcpy(outBuffer, "OK");
- }
-#endif
- break;
-
- case 'Z': /* Add breakpoint */
- {
- int ret, type, len;
- unsigned char *address;
- struct z0break *z0;
-
- ret = parse_zbreak(inBuffer, &type, &address, &len);
- if (!ret) {
- strcpy(outBuffer, "E01");
- break;
- }
-
- if (type != 0) {
- /* We support only software break points so far */
- strcpy(outBuffer, "E02");
- break;
- }
-
- if (len != R_SZ) { /* was 1 */
- strcpy(outBuffer, "E03");
- break;
- }
-
- /* Let us check whether this break point already set */
- for (z0=z0break_list; z0!=NULL; z0=z0->next) {
- if (z0->address == address) {
- break;
- }
- }
-
- if (z0 != NULL) {
- /* we already have a breakpoint for this address */
- strcpy(outBuffer, "E04");
- break;
- }
-
- /* Let us allocate new break point */
- if (z0break_avail == NULL) {
- strcpy(outBuffer, "E05");
- break;
- }
-
- /* Get entry */
- z0 = z0break_avail;
- z0break_avail = z0break_avail->next;
-
- /* Let us copy memory from address add stuff the break point in */
- /*
- *if (mem2hstr(z0->buf, address, 1) == NULL ||
- !hstr2mem(address, "cc" , 1)) {
-
- * Memory error *
- z0->next = z0break_avail;
- z0break_avail = z0;
- strcpy(outBuffer, "E05");
- break;
- }*/
-
- /* Fill it */
- z0->address = address;
-
- if( z0->address == (unsigned char *) frame->epc )
- {
- /* re-asserting the breakpoint that put us in here, so
- we'll add the breakpoint but leave the code in place
- since we'll be returning to it when the user continues */
- z0->instr = 0xffffffff;
- }
- else
- {
- /* grab the instruction */
- z0->instr = *(z0->address);
- /* and insert the break */
- *(z0->address) = BREAK_INSTR;
- }
-
- /* Add to the list */
- {
- struct z0break *znxt = z0break_list;
-
- z0->prev = NULL;
- z0->next = znxt;
-
- if( znxt ) znxt->prev = z0;
- z0break_list = z0;
- }
-
- strcpy(outBuffer, "OK");
- }
- break;
-
- case 'z': /* remove breakpoint */
- if (inBuffer[1] == 'z')
- {
- goto dumpzbreaks;
-
- /*
- * zz packet - remove all breaks *
- z0last = NULL;
-
- for (z0=z0break_list; z0!=NULL; z0=z0->next)
- {
- if(!hstr2mem(z0->address, z0->buf, R_SZ))
- {
- ret = 0;
- }
- z0last = z0;
- }
-
- * Free entries if any *
- if (z0last != NULL) {
- z0last->next = z0break_avail;
- z0break_avail = z0break_list;
- z0break_list = NULL;
- }
-
- if (ret) {
- strcpy(outBuffer, "OK");
- } else {
- strcpy(outBuffer, "E04");
- }
- break;
- */
- }
- else
- {
- int ret, type, len;
- unsigned char *address;
- struct z0break *z0;
-
- ret = parse_zbreak(inBuffer, &type, &address, &len);
- if (!ret) {
- strcpy(outBuffer, "E01");
- break;
- }
-
- if (type != 0) {
- /* We support only software break points so far */
- break;
- }
-
- if (len != R_SZ) {
- strcpy(outBuffer, "E02");
- break;
- }
-
- /* Let us check whether this break point set */
- for (z0=z0break_list; z0!=NULL; z0=z0->next) {
- if (z0->address == address) {
- break;
- }
- }
-
- if (z0 == NULL) {
- /* Unknown breakpoint */
- strcpy(outBuffer, "E03");
- break;
- }
-
- /*
- if (!hstr2mem(z0->address, z0->buf, R_SZ)) {
- strcpy(outBuffer, "E04");
- break;
- }*/
-
- if( z0->instr != 0xffffffff )
- {
- /* put the old instruction back */
- *(z0->address) = z0->instr;
- }
-
- /* Unlink entry */
- {
- struct z0break *zprv = z0->prev, *znxt = z0->next;
-
- if( zprv ) zprv->next = znxt;
- if( znxt ) znxt->prev = zprv;
-
- if( !zprv ) z0break_list = znxt;
-
- znxt = z0break_avail;
-
- z0break_avail = z0;
- z0->prev = NULL;
- z0->next = znxt;
- }
-
- strcpy(outBuffer, "OK");
- }
- break;
-
- default: /* do nothing */
- break;
- }
-
- /* reply to the request */
- putpacket (outBuffer);
- }
-
- stubexit:
-
- /*
- * The original code did this in the assembly wrapper. We should consider
- * doing it here before we return.
- *
- * On exit from the exception handler invalidate each line in the I-cache
- * and write back each dirty line in the D-cache. This needs to be done
- * before the target program is resumed in order to ensure that software
- * breakpoints and downloaded code will actually take effect. This
- * is because modifications to code in ram will affect the D-cache,
- * but not necessarily the I-cache.
- */
-
- clear_cache();
-}
-
-static int numsegs;
-static struct memseg memsegments[NUM_MEMSEGS];
-
-int gdbstub_add_memsegment( unsigned base, unsigned end, int opts )
-{
- if( numsegs == NUM_MEMSEGS ) return -1;
-
- memsegments[numsegs].begin = base;
- memsegments[numsegs].end = end;
- memsegments[numsegs].opts = opts;
-
- ++numsegs;
- return RTEMS_SUCCESSFUL;
-}
-
-static int is_readable(unsigned ptr, unsigned len)
-{
- struct memseg *ms;
- int i;
-
- if( (ptr & 0x3) ) return -1;
-
- for(i=0; i<numsegs; i++)
- {
- ms= &memsegments[i];
-
- if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_READABLE) )
- return -1;
- }
- return 0;
-}
-
-static int is_writeable(unsigned ptr, unsigned len)
-{
- struct memseg *ms;
- int i;
-
- if( (ptr & 0x3) ) return -1;
-
- for(i=0; i<numsegs; i++)
- {
- ms= &memsegments[i];
-
- if( ms->begin <= ptr && ptr+len <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )
- return -1;
- }
- return 0;
-}
-
-static int is_steppable(unsigned ptr)
-{
- struct memseg *ms;
- int i;
-
- if( (ptr & 0x3) ) return -1;
-
- for(i=0; i<numsegs; i++)
- {
- ms= &memsegments[i];
-
- if( ms->begin <= ptr && ptr <= ms->end && (ms->opts & MEMOPT_WRITEABLE) )
- return -1;
- }
- return 0;
-}
-
-static char initialized = 0; /* 0 means we are not initialized */
-
-void mips_gdb_stub_install(int enableThreads)
-{
- /*
- These are the RTEMS-defined vectors for all the MIPS exceptions
- */
- int exceptionVector[]= { MIPS_EXCEPTION_MOD, \
- MIPS_EXCEPTION_TLBL, \
- MIPS_EXCEPTION_TLBS, \
- MIPS_EXCEPTION_ADEL, \
- MIPS_EXCEPTION_ADES, \
- MIPS_EXCEPTION_IBE, \
- MIPS_EXCEPTION_DBE, \
- MIPS_EXCEPTION_SYSCALL, \
- MIPS_EXCEPTION_BREAK, \
- MIPS_EXCEPTION_RI, \
- MIPS_EXCEPTION_CPU, \
- MIPS_EXCEPTION_OVERFLOW, \
- MIPS_EXCEPTION_TRAP, \
- MIPS_EXCEPTION_VCEI, \
- MIPS_EXCEPTION_FPE, \
- MIPS_EXCEPTION_C2E, \
- MIPS_EXCEPTION_WATCH, \
- MIPS_EXCEPTION_VCED, \
- -1 };
- int i;
- rtems_isr_entry old;
-
- if (initialized)
- {
- ASSERT(0);
- return;
- }
-
- memset( memsegments,0,sizeof(struct memseg)*NUM_MEMSEGS );
- numsegs = 0;
-
-#if defined(GDB_STUB_ENABLE_THREAD_SUPPORT)
- if( enableThreads )
- do_threads = 1;
- else
- do_threads = 0;
-#endif
-
- {
- struct z0break *z0;
-
- z0break_avail = NULL;
- z0break_list = NULL;
-
- /* z0breaks list init, now we'll do it so it makes sense... */
- for (i=0; i<BREAKNUM; i++)
- {
- memset( (z0= &z0break_arr[i]), 0, sizeof(struct z0break));
-
- z0->next = z0break_avail;
- z0break_avail = z0;
- }
- }
-
- for(i=0; exceptionVector[i] > -1; i++)
- {
- rtems_interrupt_catch( (rtems_isr_entry) handle_exception, exceptionVector[i], &old );
- }
-
- initialized = 1;
-
- /* get the attention of gdb */
- /* mips_break(1); disabled so user code can choose to invoke it or not */
-}
diff --git a/c/src/lib/libbsp/mips/shared/gdbstub/mips_opcode.h b/c/src/lib/libbsp/mips/shared/gdbstub/mips_opcode.h
deleted file mode 100644
index 883b1f174b..0000000000
--- a/c/src/lib/libbsp/mips/shared/gdbstub/mips_opcode.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * @file
- * @ingroup
- * @brief Instruction formats and opcode values for MIPS
- */
-
-/*
- * Copyright (c) 1992 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)mips_opcode.h 7.1 (Berkeley) 3/19/92
- * via: mips_opcode.h,v 1.1 1994/03/10 16:15:10 (algorithmics)
- */
-
-/*
- * Define the instruction formats and opcode values for the
- * MIPS instruction set.
- */
-
-#ifndef _MIPS_OPCODE_H
-#define _MIPS_OPCODE_H
-
-/**
- * @defgroup mips_ops MIPS Opcodes
- * @ingroup mips_shared
- * @brief MIPS Instruction Formats and Opcode Values
- * @{
- */
-
-/**
- * @name Instruction formats
- * @{
- */
-
-typedef union {
- unsigned word;
-
-#ifdef MIPSEL
- struct {
- unsigned imm: 16;
- unsigned rt: 5;
- unsigned rs: 5;
- unsigned op: 6;
- } IType;
-
- struct {
- unsigned target: 26;
- unsigned op: 6;
- } JType;
-
- struct {
- unsigned func: 6;
- unsigned shamt: 5;
- unsigned rd: 5;
- unsigned rt: 5;
- unsigned rs: 5;
- unsigned op: 6;
- } RType;
-
- struct {
- unsigned func: 6;
- unsigned fd: 5;
- unsigned fs: 5;
- unsigned ft: 5;
- unsigned fmt: 4;
- unsigned : 1; /* always '1' */
- unsigned op: 6; /* always '0x11' */
- } FRType;
-#else
- struct {
- unsigned op: 6;
- unsigned rs: 5;
- unsigned rt: 5;
- unsigned imm: 16;
- } IType;
-
- struct {
- unsigned op: 6;
- unsigned target: 26;
- } JType;
-
- struct {
- unsigned op: 6;
- unsigned rs: 5;
- unsigned rt: 5;
- unsigned rd: 5;
- unsigned shamt: 5;
- unsigned func: 6;
- } RType;
-
- struct {
- unsigned op: 6; /* always '0x11' */
- unsigned : 1; /* always '1' */
- unsigned fmt: 4;
- unsigned func: 6;
- unsigned ft: 5;
- unsigned fs: 5;
- unsigned fd: 5;
- } FRType;
-#endif
-} InstFmt;
-
-/** @} */
-
-/**
- * @name 'op' field values
- * @{
- */
-
-#define OP_SPECIAL 000
-#define OP_REGIMM 001
-#define OP_J 002
-#define OP_JAL 003
-#define OP_BEQ 004
-#define OP_BNE 005
-#define OP_BLEZ 006
-#define OP_BGTZ 007
-
-#define OP_ADDI 010
-#define OP_ADDIU 011
-#define OP_SLTI 012
-#define OP_SLTIU 013
-#define OP_ANDI 014
-#define OP_ORI 015
-#define OP_XORI 016
-#define OP_LUI 017
-
-#define OP_COP0 020
-#define OP_COP1 021
-#define OP_COP2 022
-#define OP_BEQL 024
-#define OP_BNEL 025
-#define OP_BLEZL 026
-#define OP_BGTZL 027
-
-#define OP_DADDI 030
-#define OP_DADDIU 031
-#define OP_LDL 032
-#define OP_LDR 033
-
-#define OP_LB 040
-#define OP_LH 041
-#define OP_LWL 042
-#define OP_LW 043
-#define OP_LBU 044
-#define OP_LHU 045
-#define OP_LWR 046
-#define OP_LWU 047
-
-#define OP_SB 050
-#define OP_SH 051
-#define OP_SWL 052
-#define OP_SW 053
-#define OP_SDL 054
-#define OP_SDR 055
-#define OP_SWR 056
-#define OP_CACHE 057
-
-#define OP_LL 060
-#define OP_LWC1 061
-#define OP_LWC2 062
-#define OP_LLD 064
-#define OP_LDC1 065
-#define OP_LDC2 066
-#define OP_LD 067
-
-#define OP_SC 070
-#define OP_SWC1 071
-#define OP_SWC2 072
-#define OP_SCD 074
-#define OP_SDC1 075
-#define OP_SDC2 076
-#define OP_SD 077
-
-/**
- * @name 'func' field values when 'op' == OP_SPECIAL.
- * @{
- */
-
-#define OP_SLL 000
-#define OP_SRL 002
-#define OP_SRA 003
-#define OP_SLLV 004
-#define OP_SRLV 006
-#define OP_SRAV 007
-
-#define OP_JR 010
-#define OP_JALR 011
-#define OP_SYSCALL 014
-#define OP_BREAK 015
-#define OP_SYNC 017
-
-#define OP_MFHI 020
-#define OP_MTHI 021
-#define OP_MFLO 022
-#define OP_MTLO 023
-#define OP_DSLLV 024
-#define OP_DSRLV 026
-#define OP_DSRAV 027
-
-#define OP_MULT 030
-#define OP_MULTU 031
-#define OP_DIV 032
-#define OP_DIVU 033
-#define OP_DMULT 034
-#define OP_DMULTU 035
-#define OP_DDIV 036
-#define OP_DDIVU 037
-
-#define OP_ADD 040
-#define OP_ADDU 041
-#define OP_SUB 042
-#define OP_SUBU 043
-#define OP_AND 044
-#define OP_OR 045
-#define OP_XOR 046
-#define OP_NOR 047
-
-#define OP_SLT 052
-#define OP_SLTU 053
-#define OP_DADD 054
-#define OP_DADDU 055
-#define OP_DSUB 056
-#define OP_DSUBU 057
-
-#define OP_TGE 060
-#define OP_TGEU 061
-#define OP_TLT 062
-#define OP_TLTU 063
-#define OP_TEQ 064
-#define OP_TNE 066
-
-#define OP_DSLL 070
-#define OP_DSRL 072
-#define OP_DSRA 073
-#define OP_DSLL32 074
-#define OP_DSRL32 076
-#define OP_DSRA32 077
-
-/** @} */
-
-/**
- * 'func' field values when 'op' == OP_REGIMM.
- * @{
- */
-
-#define OP_BLTZ 000
-#define OP_BGEZ 001
-#define OP_BLTZL 002
-#define OP_BGEZL 003
-
-#define OP_TGEI 010
-#define OP_TGEIU 011
-#define OP_TLTI 012
-#define OP_TLTIU 013
-#define OP_TEQI 014
-#define OP_TNEI 016
-
-#define OP_BLTZAL 020
-#define OP_BGEZAL 021
-#define OP_BLTZALL 022
-#define OP_BGEZALL 023
-
-/** @} */
-
-/**
- * @name 'rs' field values when 'op' == OP_COPz.
- * @{
- */
-
-#define OP_MF 000
-#define OP_DMF 001
-#define OP_CF 002
-#define OP_MT 004
-#define OP_DMT 005
-#define OP_CT 006
-#define OP_BC 010
-
-/** @} */
-
-/**
- * @name 'rt' field values when 'op' == OP_COPz and 'rt' == OP_BC.
- * @{
- */
-
-#define COPz_BCF 0x00
-#define COPz_BCT 0x01
-#define COPz_BCFL 0x02
-#define COPz_BCTL 0x03
-
-/** @} */
-
-/**
- * @name Instructions with specal significance to debuggers.
- * @{
- */
-
-#define BREAK_INSTR 0x0000000d ///< @brief instruction code for break
-#define NOP_INSTR 0x00000000 ///< @brief instruction code for no-op
-
-/** @} */
-
-/** @} */
-
-#endif /* _MIPS_OPCODE_H */