Index: gdb/gdbserver/linux-mips-low.c |
diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c |
index 8baf1b0ce6c1bb18e5653e4aae29717cbfd9f1a6..8e37298d118ddef4765590116a047d4b1bea8b8d 100644 |
--- a/gdb/gdbserver/linux-mips-low.c |
+++ b/gdb/gdbserver/linux-mips-low.c |
@@ -27,8 +27,17 @@ |
/* Defined in auto-generated file mips-linux.c. */ |
void init_registers_mips_linux (void); |
+/* Defined in auto-generated file mips-dsp-linux.c. */ |
+void init_registers_mips_dsp_linux (void); |
/* Defined in auto-generated file mips64-linux.c. */ |
void init_registers_mips64_linux (void); |
+/* Defined in auto-generated file mips64-dsp-linux.c. */ |
+void init_registers_mips64_dsp_linux (void); |
+ |
+#ifdef __mips64 |
+#define init_registers_mips_linux init_registers_mips64_linux |
+#define init_registers_mips_dsp_linux init_registers_mips64_dsp_linux |
+#endif |
#ifndef PTRACE_GET_THREAD_AREA |
#define PTRACE_GET_THREAD_AREA 25 |
@@ -39,9 +48,15 @@ void init_registers_mips64_linux (void); |
#endif |
#define mips_num_regs 73 |
+#define mips_dsp_num_regs 80 |
#include <asm/ptrace.h> |
+#ifndef DSP_BASE |
+#define DSP_BASE 71 |
+#define DSP_CONTROL 77 |
+#endif |
+ |
union mips_register |
{ |
unsigned char buf[8]; |
@@ -53,27 +68,84 @@ union mips_register |
/* Return the ptrace ``address'' of register REGNO. */ |
-static int mips_regmap[] = { |
- -1, 1, 2, 3, 4, 5, 6, 7, |
- 8, 9, 10, 11, 12, 13, 14, 15, |
- 16, 17, 18, 19, 20, 21, 22, 23, |
- 24, 25, 26, 27, 28, 29, 30, 31, |
+#define mips_base_regs \ |
+ -1, 1, 2, 3, 4, 5, 6, 7, \ |
+ 8, 9, 10, 11, 12, 13, 14, 15, \ |
+ 16, 17, 18, 19, 20, 21, 22, 23, \ |
+ 24, 25, 26, 27, 28, 29, 30, 31, \ |
+ \ |
+ -1, MMLO, MMHI, BADVADDR, CAUSE, PC, \ |
+ \ |
+ FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, \ |
+ FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, \ |
+ FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11, \ |
+ FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, \ |
+ FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, \ |
+ FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, \ |
+ FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, \ |
+ FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, \ |
+ FPC_CSR, FPC_EIR |
+ |
+#define mips_dsp_regs \ |
+ DSP_BASE, DSP_BASE + 1, DSP_BASE + 2, DSP_BASE + 3, \ |
+ DSP_BASE + 4, DSP_BASE + 5, \ |
+ DSP_CONTROL |
+ |
+static int mips_regmap[mips_num_regs] = { |
+ mips_base_regs, |
+ 0 |
+}; |
- -1, MMLO, MMHI, BADVADDR, CAUSE, PC, |
+static int mips_dsp_regmap[mips_dsp_num_regs] = { |
+ mips_base_regs, |
+ mips_dsp_regs, |
+ 0 |
+}; |
- FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, |
- FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, |
- FPR_BASE + 8, FPR_BASE + 8, FPR_BASE + 10, FPR_BASE + 11, |
- FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, |
- FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, |
- FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, |
- FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, |
- FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, |
- FPC_CSR, FPC_EIR, |
+/* DSP registers are not in any regset and can only be accessed |
+ individually. */ |
- 0 |
+static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = { |
+ 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80 |
}; |
+/* Try peeking at an arbitrarily chosen DSP register and pick the available |
+ user register set accordingly. */ |
+ |
+static void |
+mips_arch_setup (void) |
+{ |
+ static void (*init_registers) (void); |
+ |
+ gdb_assert (current_inferior); |
+ |
+ if (init_registers == NULL) |
+ { |
+ int pid = lwpid_of (get_thread_lwp (current_inferior)); |
+ |
+ ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0); |
+ switch (errno) |
+ { |
+ case 0: |
+ the_low_target.num_regs = mips_dsp_num_regs; |
+ the_low_target.regmap = mips_dsp_regmap; |
+ the_low_target.regset_bitmap = mips_dsp_regset_bitmap; |
+ init_registers = init_registers_mips_dsp_linux; |
+ break; |
+ case EIO: |
+ the_low_target.num_regs = mips_num_regs; |
+ the_low_target.regmap = mips_regmap; |
+ the_low_target.regset_bitmap = NULL; |
+ init_registers = init_registers_mips_linux; |
+ break; |
+ default: |
+ perror_with_name ("ptrace"); |
+ break; |
+ } |
+ } |
+ init_registers (); |
+} |
+ |
/* From mips-linux-nat.c. */ |
/* Pseudo registers can not be read. ptrace does not provide a way to |
@@ -84,7 +156,7 @@ static int mips_regmap[] = { |
static int |
mips_cannot_fetch_register (int regno) |
{ |
- if (mips_regmap[regno] == -1) |
+ if (the_low_target.regmap[regno] == -1) |
return 1; |
if (find_regno ("r0") == regno) |
@@ -96,7 +168,7 @@ mips_cannot_fetch_register (int regno) |
static int |
mips_cannot_store_register (int regno) |
{ |
- if (mips_regmap[regno] == -1) |
+ if (the_low_target.regmap[regno] == -1) |
return 1; |
if (find_regno ("r0") == regno) |
@@ -352,15 +424,13 @@ struct regset_info target_regsets[] = { |
}; |
struct linux_target_ops the_low_target = { |
-#ifdef __mips64 |
- init_registers_mips64_linux, |
-#else |
- init_registers_mips_linux, |
-#endif |
- mips_num_regs, |
- mips_regmap, |
+ mips_arch_setup, |
+ -1, |
+ NULL, |
+ NULL, |
mips_cannot_fetch_register, |
mips_cannot_store_register, |
+ NULL, /* fetch_register */ |
mips_get_pc, |
mips_set_pc, |
(const unsigned char *) &mips_breakpoint, |