From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1404 invoked by alias); 10 Dec 2007 15:52:21 -0000 Received: (qmail 1392 invoked by uid 22791); 10 Dec 2007 15:52:17 -0000 X-Spam-Check-By: sourceware.org Received: from dmz.mips-uk.com (HELO dmz.mips-uk.com) (194.74.144.194) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 10 Dec 2007 15:52:10 +0000 Received: from internal-mx1 ([192.168.192.240] helo=ukservices1.mips.com) by dmz.mips-uk.com with esmtp (Exim 3.35 #1 (Debian)) id 1J1kvO-000706-00; Mon, 10 Dec 2007 15:52:06 +0000 Received: from perivale.mips.com ([192.168.192.200]) by ukservices1.mips.com with esmtp (Exim 3.36 #1 (Debian)) id 1J1kvD-00059L-00; Mon, 10 Dec 2007 15:51:55 +0000 Received: from macro (helo=localhost) by perivale.mips.com with local-esmtp (Exim 4.63) (envelope-from ) id 1J1kvD-0004N1-6U; Mon, 10 Dec 2007 15:51:55 +0000 Date: Mon, 10 Dec 2007 16:33:00 -0000 From: "Maciej W. Rozycki" To: gdb-patches@sourceware.org cc: Chris Dearman , "Maciej W. Rozycki" Subject: MIPS: Handle the DSP registers Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-MIPS-Technologies-UK-MailScanner: Found to be clean X-MIPS-Technologies-UK-MailScanner-From: macro@mips.com Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-12/txt/msg00151.txt.bz2 Hello, Here is code to support DSP registers as defined by the DSP ASE to the MIPS Architecture. This piece of code handles Linux and provides for adding such support to embedded targets. The ASE is optional (as are all ASEs) and therefore some steps have been taken to handle this correctly. In particular, ptrace() calls may return a failure when called on a system that does not support the ASE. In such a case the registers are marked as unavailable in the cache which has the effect of them being hardwired to zero (I have a patch in the queue that would mark them specially in the output; I will submit it later). The offsets and layout of DSP registers vary between Linux and bare-iron -- this has been taken account of (by shuffling some code around in mips_gdbarch_init(), which I believe has actually made it a little bit more readable) and it is also the reason some minimal support for these registers with the bare-iron has been included here (and which effectively amounts to the addition of more MIPS_EMBED_* enum definitions and their use in mips-tdep.c). Full support for bare-iron relies on cp0 register discovery which I plan to propose later on (once I have found a reasonable way to port the old piece of code so that it fits the XML target description model). As a small benefit on top of these changes, there is no need to provide null strings in the tables holding register names for offsets corresponding to inexistent registers anymore -- mips_register_name() now returns a null string when the entry requested holds a null pointer. Tested using the mipsisa32-sde-elf target, with the mips-sim-sde32/-EB and mips-sim-sde32/-EL boards with no regressions. Tested natively with the mips-linux-gnu host/target (with the o32 ABI) using a MIPS64 (no DSP ASE) and a MIPS32r2 (DSP-enabled) processor with no regressions in either. I have no access to the IRIX host, but I hope I have not broken anything -- the support for no-DSP there should keep working as it is. gdb/: 2007-12-10 Maciej W. Rozycki Chris Dearman * features/mips-dsp.xml: New file. * features/mips64-dsp.xml: Likewise. * features/mips-linux.xml: Include mips-dsp.xml. * features/mips64-linux.xml: Include mips64-dsp.xml. * features/mips-linux.c: Regenerate. * features/mips64-linux.c: Regenerate. * inf-ptrace.c (inf_ptrace_fetch_register): Don't bail out having attempted to read an inexistent register; mark it as inaccessible in the cache instead. (inf_ptrace_store_register): Don't bail out having attempted to write an inexistent register. * mips-linux-nat.c (super_fetch_registers): Mark static. (super_store_registers): Likewise. (mips_linux_register_addr): Handle DSP registers. (mips64_linux_register_addr): Likewise. (mips64_linux_regsets_fetch_registers): Likewise. (mips64_linux_regsets_store_registers): Likewise. * mips-linux-tdep.c (supply_gregset, mips64_supply_gregset): Remove padding as the register array does not use the layout defined for embedded targets anymore. * mips-linux-tdep.h (DSP_BASE, DSP_CONTROL): New macros. * mips-tdep.c (NUM_MIPS_PROCESSOR_REGS): Set from MIPS_LAST_EMBED_REGNUM. (mips_generic_reg_names): Remove trailing null strings. (mips_tx39_reg_names): Likewise. (mips_linux_reg_names): New array of register names for Linux targets. (mips_register_name): Check for a null pointer in mips_processor_reg_names and return an empty string. (mips_stab_reg_to_regnum): Handle DSP accumulators. (mips_dwarf_dwarf2_ecoff_reg_to_regnum): Likewise. (mips_gdbarch_init): Likewise. Initialize internal register indices for Linux. Use MIPS_LAST_EMBED_REGNUM as appropriate. * mips-tdep.h (struct mips_regnum): Add dspacc/dspctl offsets. (MIPS_EMBED_CP2_REGNUM): Offset to CP2 registers. (MIPS_EMBED_DSPACC_REGNUM): Offset to DSP accumulator registers. (MIPS_EMBED_DSPCTL_REGNUM): Offset to DSP control registers. (MIPS_LAST_EMBED_REGNUM): Update accordingly. (MIPS_EMBED_NUM_REGS): New value to make sure that an even number of registers is used. * regcache.c (regcache_invalidate): Allow for an arbitrary setting of the cache state and replace with a wrapper to call the original function renamed to... (regcache_set_valid_p): ... this. * regcache.h (regcache_set_valid_p): New prototype. gdb/testsuite/: 2007-12-10 Maciej W. Rozycki * gdb.xml/tdesc-regs.exp: Add "mips-dsp.xml" to the list of MIPS core registers. Ok to apply? Maciej 14607.diff Index: binutils-quilt/src/gdb/mips-linux-nat.c =================================================================== --- binutils-quilt.orig/src/gdb/mips-linux-nat.c 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-nat.c 2007-12-07 15:13:02.000000000 +0000 @@ -47,8 +47,8 @@ /* Saved function pointers to fetch and store a single register using PTRACE_PEEKUSER and PTRACE_POKEUSER. */ -void (*super_fetch_registers) (struct regcache *, int); -void (*super_store_registers) (struct regcache *, int); +static void (*super_fetch_registers) (struct regcache *, int); +static void (*super_store_registers) (struct regcache *, int); /* Map gdb internal register number to ptrace ``address''. These ``addresses'' are normally defined in . @@ -84,6 +84,11 @@ regaddr = FPC_CSR; else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) regaddr = store? (CORE_ADDR) -1 : FPC_EIR; + else if ((regno >= mips_regnum (gdbarch)->dspacc) + && (regno < mips_regnum (gdbarch)->dspacc + 6)) + regaddr = DSP_BASE + (regno - mips_regnum (gdbarch)->dspacc); + else if (regno == mips_regnum (gdbarch)->dspctl) + regaddr = DSP_CONTROL; else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM) regaddr = 0; else @@ -119,6 +124,11 @@ regaddr = MIPS64_FPC_CSR; else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR; + else if ((regno >= mips_regnum (gdbarch)->dspacc) + && (regno < mips_regnum (gdbarch)->dspacc + 6)) + regaddr = DSP_BASE + (regno - mips_regnum (gdbarch)->dspacc); + else if (regno == mips_regnum (gdbarch)->dspctl) + regaddr = DSP_CONTROL; else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM) regaddr = 0; else @@ -192,7 +202,8 @@ mips64_linux_regsets_fetch_registers (struct regcache *regcache, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); - int is_fp; + int is_fp, is_dsp; + int regi; int tid; if (regno >= mips_regnum (gdbarch)->fp0 @@ -205,11 +216,20 @@ else is_fp = 0; + /* DSP registers are optional and not a part of any set. */ + if ((regno >= mips_regnum (gdbarch)->dspacc) + && (regno < mips_regnum (gdbarch)->dspacc + 6)) + is_dsp = 1; + else if (regno == mips_regnum (gdbarch)->dspctl) + is_dsp = 1; + else + is_dsp = 0; + tid = ptid_get_lwp (inferior_ptid); if (tid == 0) tid = ptid_get_pid (inferior_ptid); - if (regno == -1 || !is_fp) + if (regno == -1 || (!is_fp && !is_dsp)) { mips64_elf_gregset_t regs; @@ -245,16 +265,28 @@ mips64_supply_fpregset (regcache, (const mips64_elf_fpregset_t *) &fp_regs); } + + if (is_dsp) + super_fetch_registers (regcache, regno); + else if (regno == -1) + { + for (regi = mips_regnum (gdbarch)->dspacc; + regi < mips_regnum (gdbarch)->dspacc + 6; + regi++) + super_fetch_registers (regcache, regi); + super_fetch_registers (regcache, mips_regnum (gdbarch)->dspctl); + } } /* Store REGNO (or all registers if REGNO == -1) to the target using PTRACE_SETREGS et al. */ static void -mips64_linux_regsets_store_registers (const struct regcache *regcache, int regno) +mips64_linux_regsets_store_registers (struct regcache *regcache, int regno) { struct gdbarch *gdbarch = get_regcache_arch (regcache); - int is_fp; + int is_fp, is_dsp; + int regi; int tid; if (regno >= mips_regnum (gdbarch)->fp0 @@ -267,11 +299,20 @@ else is_fp = 0; + /* DSP registers are optional and not a part of any set. */ + if ((regno >= mips_regnum (gdbarch)->dspacc) + && (regno < mips_regnum (gdbarch)->dspacc + 6)) + is_dsp = 1; + else if (regno == mips_regnum (gdbarch)->dspctl) + is_dsp = 1; + else + is_dsp = 0; + tid = ptid_get_lwp (inferior_ptid); if (tid == 0) tid = ptid_get_pid (inferior_ptid); - if (regno == -1 || !is_fp) + if (regno == -1 || (!is_fp && !is_dsp)) { mips64_elf_gregset_t regs; @@ -298,6 +339,17 @@ (PTRACE_TYPE_ARG3) &fp_regs) == -1) perror_with_name (_("Couldn't set FP registers")); } + + if (is_dsp) + super_store_registers (regcache, regno); + else if (regno == -1) + { + for (regi = mips_regnum (gdbarch)->dspacc; + regi < mips_regnum (gdbarch)->dspacc + 6; + regi++) + super_store_registers (regcache, regi); + super_store_registers (regcache, mips_regnum (gdbarch)->dspctl); + } } /* Fetch REGNO (or all registers if REGNO == -1) from the target Index: binutils-quilt/src/gdb/mips-tdep.c =================================================================== --- binutils-quilt.orig/src/gdb/mips-tdep.c 2007-12-07 15:10:04.000000000 +0000 +++ binutils-quilt/src/gdb/mips-tdep.c 2007-12-07 15:13:02.000000000 +0000 @@ -436,7 +436,7 @@ are listed in the following tables. */ enum -{ NUM_MIPS_PROCESSOR_REGS = (90 - 32) }; +{ NUM_MIPS_PROCESSOR_REGS = (MIPS_LAST_EMBED_REGNUM + 1 - 32) }; /* Generic MIPS. */ @@ -446,9 +446,7 @@ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "fsr", "fir", "" /*"fp" */ , "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", + "fsr", "fir", }; /* Names of IDT R3041 registers. */ @@ -474,7 +472,7 @@ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", "config", "cache", "debug", "depc", "epc", "" + "", "", "config", "cache", "debug", "depc", "epc", }; /* Names of IRIX registers. */ @@ -486,6 +484,17 @@ "pc", "cause", "bad", "hi", "lo", "fsr", "fir" }; +/* Names of Linux registers. */ +static const char *mips_linux_reg_names[NUM_MIPS_PROCESSOR_REGS] = { + "sr", "lo", "hi", "bad", "cause", "pc", + "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", + "fsr", "fir", "hi1", "lo1", "hi2", "lo2", "hi3", "lo3", + "dspctl", +}; + /* Return the name of the register corresponding to REGNO. */ static const char * @@ -531,7 +540,9 @@ else if (32 <= rawnum && rawnum < gdbarch_num_regs (gdbarch)) { gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS); - return tdep->mips_processor_reg_names[rawnum - 32]; + if (tdep->mips_processor_reg_names[rawnum - 32]) + return tdep->mips_processor_reg_names[rawnum - 32]; + return ""; } else internal_error (__FILE__, __LINE__, @@ -5076,6 +5087,8 @@ regnum = mips_regnum (gdbarch)->hi; else if (num == 71) regnum = mips_regnum (gdbarch)->lo; + else if (num >= 72 && num < 78) + regnum = num + mips_regnum (gdbarch)->dspacc - 72; else /* This will hopefully (eventually) provoke a warning. Should we be calling complaint() here? */ @@ -5099,6 +5112,8 @@ regnum = mips_regnum (gdbarch)->hi; else if (num == 65) regnum = mips_regnum (gdbarch)->lo; + else if (num >= 66 && num < 72) + regnum = num + mips_regnum (gdbarch)->dspacc - 66; else /* This will hopefully (eventually) provoke a warning. Should we be calling complaint() here? */ @@ -5232,10 +5247,66 @@ struct gdbarch_tdep *tdep; int elf_flags; enum mips_abi mips_abi, found_abi, wanted_abi; - int i, num_regs; + int i, num_regs, dsp_space; enum mips_fpu_type fpu_type; struct tdesc_arch_data *tdesc_data = NULL; int elf_fpu_type = 0; + const char **reg_names; + struct mips_regnum mips_regnum, *regnum; + + /* Fill in the OS dependant register numbers and names. */ + if (info.osabi == GDB_OSABI_IRIX) + { + mips_regnum.fp0 = 32; + mips_regnum.pc = 64; + mips_regnum.cause = 65; + mips_regnum.badvaddr = 66; + mips_regnum.hi = 67; + mips_regnum.lo = 68; + mips_regnum.fp_control_status = 69; + mips_regnum.fp_implementation_revision = 70; + mips_regnum.dspacc = -1; + mips_regnum.dspctl = -1; + dsp_space = 0; + num_regs = 71; + reg_names = mips_irix_reg_names; + } + else if (info.osabi == GDB_OSABI_LINUX) + { + mips_regnum.fp0 = 38; + mips_regnum.pc = 37; + mips_regnum.cause = 36; + mips_regnum.badvaddr = 35; + mips_regnum.hi = 34; + mips_regnum.lo = 33; + mips_regnum.fp_control_status = 70; + mips_regnum.fp_implementation_revision = 71; + mips_regnum.dspacc = 72; + mips_regnum.dspctl = 78; + dsp_space = 0; + num_regs = 79; + reg_names = mips_linux_reg_names; + } + else + { + mips_regnum.lo = MIPS_EMBED_LO_REGNUM; + mips_regnum.hi = MIPS_EMBED_HI_REGNUM; + mips_regnum.badvaddr = MIPS_EMBED_BADVADDR_REGNUM; + mips_regnum.cause = MIPS_EMBED_CAUSE_REGNUM; + mips_regnum.pc = MIPS_EMBED_PC_REGNUM; + mips_regnum.fp0 = MIPS_EMBED_FP0_REGNUM; + mips_regnum.fp_control_status = 70; + mips_regnum.fp_implementation_revision = 71; + mips_regnum.dspacc = MIPS_EMBED_DSPACC_REGNUM; + mips_regnum.dspctl = MIPS_EMBED_DSPCTL_REGNUM; + dsp_space = 1; + num_regs = MIPS_LAST_EMBED_REGNUM + 1; + if (info.bfd_arch_info != NULL + && info.bfd_arch_info->mach == bfd_mach_mips3900) + reg_names = mips_tx39_reg_names; + else + reg_names = mips_generic_reg_names; + } /* Check any target description for validity. */ if (tdesc_has_registers (info.target_desc)) @@ -5270,11 +5341,11 @@ valid_p &= tdesc_numbered_register (feature, tdesc_data, - MIPS_EMBED_LO_REGNUM, "lo"); + mips_regnum.lo, "lo"); valid_p &= tdesc_numbered_register (feature, tdesc_data, - MIPS_EMBED_HI_REGNUM, "hi"); + mips_regnum.hi, "hi"); valid_p &= tdesc_numbered_register (feature, tdesc_data, - MIPS_EMBED_PC_REGNUM, "pc"); + mips_regnum.pc, "pc"); if (!valid_p) { @@ -5292,12 +5363,11 @@ valid_p = 1; valid_p &= tdesc_numbered_register (feature, tdesc_data, - MIPS_EMBED_BADVADDR_REGNUM, - "badvaddr"); + mips_regnum.badvaddr, "badvaddr"); valid_p &= tdesc_numbered_register (feature, tdesc_data, MIPS_PS_REGNUM, "status"); valid_p &= tdesc_numbered_register (feature, tdesc_data, - MIPS_EMBED_CAUSE_REGNUM, "cause"); + mips_regnum.cause, "cause"); if (!valid_p) { @@ -5318,13 +5388,15 @@ valid_p = 1; for (i = 0; i < 32; i++) valid_p &= tdesc_numbered_register (feature, tdesc_data, - i + MIPS_EMBED_FP0_REGNUM, - mips_fprs[i]); + i + mips_regnum.fp0, mips_fprs[i]); valid_p &= tdesc_numbered_register (feature, tdesc_data, - MIPS_EMBED_FP0_REGNUM + 32, "fcsr"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - MIPS_EMBED_FP0_REGNUM + 33, "fir"); + mips_regnum.fp_control_status, + "fcsr"); + valid_p + &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.fp_implementation_revision, + "fir"); if (!valid_p) { @@ -5332,8 +5404,46 @@ return NULL; } + if (mips_regnum.dspacc >= 0) + { + feature = tdesc_find_feature (info.target_desc, + "org.gnu.gdb.mips.dsp"); + if (feature == NULL) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + valid_p = 1; + i = dsp_space; + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.dspacc + i++, "hi1"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.dspacc + i++, "lo1"); + i += dsp_space; + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.dspacc + i++, "hi2"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.dspacc + i++, "lo2"); + i += dsp_space; + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.dspacc + i++, "hi3"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.dspacc + i++, "lo3"); + + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.dspctl, "dspctl"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + } + /* It would be nice to detect an attempt to use a 64-bit ABI when only 32-bit registers are provided. */ + reg_names = NULL; } /* First of all, extract the elf_flags, if available. */ @@ -5572,66 +5682,19 @@ set_gdbarch_elf_make_msymbol_special (gdbarch, mips_elf_make_msymbol_special); - /* Fill in the OS dependant register numbers and names. */ - { - const char **reg_names; - struct mips_regnum *regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch, - struct mips_regnum); - if (tdesc_has_registers (info.target_desc)) - { - regnum->lo = MIPS_EMBED_LO_REGNUM; - regnum->hi = MIPS_EMBED_HI_REGNUM; - regnum->badvaddr = MIPS_EMBED_BADVADDR_REGNUM; - regnum->cause = MIPS_EMBED_CAUSE_REGNUM; - regnum->pc = MIPS_EMBED_PC_REGNUM; - regnum->fp0 = MIPS_EMBED_FP0_REGNUM; - regnum->fp_control_status = 70; - regnum->fp_implementation_revision = 71; - num_regs = MIPS_LAST_EMBED_REGNUM + 1; - reg_names = NULL; - } - else if (info.osabi == GDB_OSABI_IRIX) - { - regnum->fp0 = 32; - regnum->pc = 64; - regnum->cause = 65; - regnum->badvaddr = 66; - regnum->hi = 67; - regnum->lo = 68; - regnum->fp_control_status = 69; - regnum->fp_implementation_revision = 70; - num_regs = 71; - reg_names = mips_irix_reg_names; - } - else - { - regnum->lo = MIPS_EMBED_LO_REGNUM; - regnum->hi = MIPS_EMBED_HI_REGNUM; - regnum->badvaddr = MIPS_EMBED_BADVADDR_REGNUM; - regnum->cause = MIPS_EMBED_CAUSE_REGNUM; - regnum->pc = MIPS_EMBED_PC_REGNUM; - regnum->fp0 = MIPS_EMBED_FP0_REGNUM; - regnum->fp_control_status = 70; - regnum->fp_implementation_revision = 71; - num_regs = 90; - if (info.bfd_arch_info != NULL - && info.bfd_arch_info->mach == bfd_mach_mips3900) - reg_names = mips_tx39_reg_names; - else - reg_names = mips_generic_reg_names; - } - /* FIXME: cagney/2003-11-15: For MIPS, hasn't gdbarch_pc_regnum been - replaced by read_pc? */ - set_gdbarch_pc_regnum (gdbarch, regnum->pc + num_regs); - set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs); - set_gdbarch_fp0_regnum (gdbarch, regnum->fp0); - set_gdbarch_num_regs (gdbarch, num_regs); - set_gdbarch_num_pseudo_regs (gdbarch, num_regs); - set_gdbarch_register_name (gdbarch, mips_register_name); - set_gdbarch_virtual_frame_pointer (gdbarch, mips_virtual_frame_pointer); - tdep->mips_processor_reg_names = reg_names; - tdep->regnum = regnum; - } + regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct mips_regnum); + *regnum = mips_regnum; + /* FIXME: cagney/2003-11-15: For MIPS, hasn't gdbarch_pc_regnum been + replaced by read_pc? */ + set_gdbarch_pc_regnum (gdbarch, regnum->pc + num_regs); + set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs); + set_gdbarch_fp0_regnum (gdbarch, regnum->fp0); + set_gdbarch_num_regs (gdbarch, num_regs); + set_gdbarch_num_pseudo_regs (gdbarch, num_regs); + set_gdbarch_register_name (gdbarch, mips_register_name); + set_gdbarch_virtual_frame_pointer (gdbarch, mips_virtual_frame_pointer); + tdep->mips_processor_reg_names = reg_names; + tdep->regnum = regnum; switch (mips_abi) { Index: binutils-quilt/src/gdb/mips-tdep.h =================================================================== --- binutils-quilt.orig/src/gdb/mips-tdep.h 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/mips-tdep.h 2007-12-07 15:13:02.000000000 +0000 @@ -53,6 +53,8 @@ int cause; /* Describes last exception. */ int hi; /* Multiply/divide temp. */ int lo; /* ... */ + int dspacc; /* SmartMIPS/DSP accumulators. */ + int dspctl; /* DSP control. */ }; extern const struct mips_regnum *mips_regnum (struct gdbarch *gdbarch); @@ -75,9 +77,26 @@ MIPS_EMBED_PC_REGNUM = 37, MIPS_EMBED_FP0_REGNUM = 38, MIPS_UNUSED_REGNUM = 73, /* Never used, FIXME */ - MIPS_FIRST_EMBED_REGNUM = 74, /* First CP0 register for embedded use. */ - MIPS_PRID_REGNUM = 89, /* Processor ID. */ - MIPS_LAST_EMBED_REGNUM = 89 /* Last one. */ + MIPS_FIRST_EMBED_REGNUM = 74, /* First CP register for embedded use. */ + MIPS_EMBED_CP0_REGNUM = MIPS_FIRST_EMBED_REGNUM, + /* CP0 data registers: 8 banks of 32. */ + MIPS_PRID_REGNUM = (MIPS_EMBED_CP0_REGNUM + 15), + /* Processor ID. */ + MIPS_EMBED_CP2_REGNUM = (MIPS_EMBED_CP0_REGNUM + 8 * 32), + /* CP2 data registers: 8 banks of 32. */ + MIPS_EMBED_CP2CTL_REGNUM = (MIPS_EMBED_CP2_REGNUM + 8 * 32), + /* CP2 control registers: 32. */ + MIPS_EMBED_DSPACC_REGNUM = (MIPS_EMBED_CP2CTL_REGNUM + 32), + /* DSP/SmartMIPS registers: + ACX, Hi1, Lo1, ACX1, + Hi2, Lo2, ACX2, Hi3, Lo3, ACX3. */ + MIPS_EMBED_DSPCTL_REGNUM = (MIPS_EMBED_DSPACC_REGNUM + 10), + /* DSP DSPCTL0..1 registers. */ + MIPS_EMBED_NUM_REGS = (MIPS_EMBED_DSPCTL_REGNUM + 2), + /* Total number of actual registers. */ + MIPS_LAST_EMBED_REGNUM + = ((MIPS_EMBED_NUM_REGS + MIPS_EMBED_NUM_REGS % 2) - 1) + /* Last one, including padding to even. */ }; /* Defined in mips-tdep.c and used in remote-mips.c */ Index: binutils-quilt/src/gdb/mips-linux-tdep.c =================================================================== --- binutils-quilt.orig/src/gdb/mips-linux-tdep.c 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-tdep.c 2007-12-07 15:13:02.000000000 +0000 @@ -112,14 +112,6 @@ supply_32bit_reg (regcache, MIPS_PS_REGNUM, regp + EF_CP0_STATUS); supply_32bit_reg (regcache, mips_regnum (gdbarch)->cause, regp + EF_CP0_CAUSE); - - /* Fill inaccessible registers with zero. */ - regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf); - regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf); - for (regi = MIPS_FIRST_EMBED_REGNUM; - regi <= MIPS_LAST_EMBED_REGNUM; - regi++) - regcache_raw_supply (regcache, regi, zerobuf); } /* Pack our registers (or one register) into an elf_gregset_t. */ @@ -325,14 +317,6 @@ (const gdb_byte *) (regp + MIPS64_EF_CP0_STATUS)); supply_64bit_reg (regcache, mips_regnum (gdbarch)->cause, (const gdb_byte *) (regp + MIPS64_EF_CP0_CAUSE)); - - /* Fill inaccessible registers with zero. */ - regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf); - regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf); - for (regi = MIPS_FIRST_EMBED_REGNUM; - regi <= MIPS_LAST_EMBED_REGNUM; - regi++) - regcache_raw_supply (regcache, regi, zerobuf); } /* Pack our registers (or one register) into a 64-bit elf_gregset_t. */ Index: binutils-quilt/src/gdb/mips-linux-tdep.h =================================================================== --- binutils-quilt.orig/src/gdb/mips-linux-tdep.h 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/mips-linux-tdep.h 2007-12-07 15:13:02.000000000 +0000 @@ -36,6 +36,8 @@ #define MMLO 68 #define FPC_CSR 69 #define FPC_EIR 70 +#define DSP_BASE 71 +#define DSP_CONTROL 77 #define EF_REG0 6 #define EF_REG31 37 Index: binutils-quilt/src/gdb/inf-ptrace.c =================================================================== --- binutils-quilt.orig/src/gdb/inf-ptrace.c 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/inf-ptrace.c 2007-12-07 15:13:02.000000000 +0000 @@ -647,7 +647,12 @@ { errno = 0; buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, 0); - if (errno != 0) + if (errno == EIO) + { + regcache_set_valid_p (regcache, regnum, -1); + return; + } + else if (errno != 0) error (_("Couldn't read register %s (#%d): %s."), gdbarch_register_name (gdbarch, regnum), regnum, safe_strerror (errno)); @@ -705,7 +710,9 @@ { errno = 0; ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, buf[i]); - if (errno != 0) + if (errno == EIO) + return; + else if (errno != 0) error (_("Couldn't write register %s (#%d): %s."), gdbarch_register_name (gdbarch, regnum), regnum, safe_strerror (errno)); Index: binutils-quilt/src/gdb/features/mips-linux.xml =================================================================== --- binutils-quilt.orig/src/gdb/features/mips-linux.xml 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/features/mips-linux.xml 2007-12-07 15:13:02.000000000 +0000 @@ -11,6 +11,7 @@ + Index: binutils-quilt/src/gdb/features/mips64-dsp.xml =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ binutils-quilt/src/gdb/features/mips64-dsp.xml 2007-12-07 15:13:02.000000000 +0000 @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + Index: binutils-quilt/src/gdb/features/mips64-linux.xml =================================================================== --- binutils-quilt.orig/src/gdb/features/mips64-linux.xml 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/features/mips64-linux.xml 2007-12-07 15:13:02.000000000 +0000 @@ -11,6 +11,7 @@ + Index: binutils-quilt/src/gdb/features/mips-dsp.xml =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ binutils-quilt/src/gdb/features/mips-dsp.xml 2007-12-07 15:13:02.000000000 +0000 @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + Index: binutils-quilt/src/gdb/regcache.c =================================================================== --- binutils-quilt.orig/src/gdb/regcache.c 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/regcache.c 2007-12-07 15:13:02.000000000 +0000 @@ -398,16 +398,24 @@ return regcache->register_valid_p[regnum]; } +/* Record that REGNUM's value is cached if STATE is >0, uncached but + fetchable if STATE is 0, and uncached and unfetchable if STATE is <0. */ + void -regcache_invalidate (struct regcache *regcache, int regnum) +regcache_set_valid_p (struct regcache *regcache, int regnum, int state) { gdb_assert (regcache != NULL); gdb_assert (regnum >= 0); gdb_assert (!regcache->readonly_p); gdb_assert (regnum < regcache->descr->nr_raw_registers); - regcache->register_valid_p[regnum] = 0; + regcache->register_valid_p[regnum] = state; } +void +regcache_invalidate (struct regcache *regcache, int regnum) +{ + regcache_set_valid_p (regcache, regnum, 0); +} /* Global structure containing the current regcache. */ /* FIXME: cagney/2002-05-11: The two global arrays registers[] and Index: binutils-quilt/src/gdb/regcache.h =================================================================== --- binutils-quilt.orig/src/gdb/regcache.h 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/regcache.h 2007-12-07 15:13:02.000000000 +0000 @@ -60,6 +60,8 @@ int regcache_valid_p (const struct regcache *regcache, int regnum); +void regcache_set_valid_p (struct regcache *regcache, int regnum, int state); + void regcache_invalidate (struct regcache *regcache, int regnum); /* Transfer a cooked register [0..NUM_REGS+NUM_PSEUDO_REGS). */ Index: binutils-quilt/src/gdb/features/mips64-linux.c =================================================================== --- binutils-quilt.orig/src/gdb/features/mips64-linux.c 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/features/mips64-linux.c 2007-12-07 15:13:02.000000000 +0000 @@ -92,8 +92,17 @@ tdesc_create_reg (feature, "fcsr", 70, 1, "float", 64, "int"); tdesc_create_reg (feature, "fir", 71, 1, "float", 64, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.mips.dsp"); + tdesc_create_reg (feature, "hi1", 72, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "lo1", 73, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hi2", 74, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "lo2", 75, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "hi3", 76, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "lo3", 77, 1, NULL, 64, "int"); + tdesc_create_reg (feature, "dspctl", 78, 1, NULL, 32, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux"); - tdesc_create_reg (feature, "restart", 72, 1, "system", 64, "int"); + tdesc_create_reg (feature, "restart", 79, 1, "system", 64, "int"); tdesc_mips64_linux = result; } Index: binutils-quilt/src/gdb/features/mips-linux.c =================================================================== --- binutils-quilt.orig/src/gdb/features/mips-linux.c 2007-12-07 15:08:21.000000000 +0000 +++ binutils-quilt/src/gdb/features/mips-linux.c 2007-12-07 15:13:02.000000000 +0000 @@ -92,8 +92,17 @@ tdesc_create_reg (feature, "fcsr", 70, 1, "float", 32, "int"); tdesc_create_reg (feature, "fir", 71, 1, "float", 32, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.mips.dsp"); + tdesc_create_reg (feature, "hi1", 72, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "lo1", 73, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hi2", 74, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "lo2", 75, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "hi3", 76, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "lo3", 77, 1, NULL, 32, "int"); + tdesc_create_reg (feature, "dspctl", 78, 1, NULL, 32, "int"); + feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux"); - tdesc_create_reg (feature, "restart", 72, 1, "system", 32, "int"); + tdesc_create_reg (feature, "restart", 79, 1, "system", 32, "int"); tdesc_mips_linux = result; } Index: binutils-quilt/src/gdb/testsuite/gdb.xml/tdesc-regs.exp =================================================================== --- binutils-quilt.orig/src/gdb/testsuite/gdb.xml/tdesc-regs.exp 2007-12-07 17:01:40.000000000 +0000 +++ binutils-quilt/src/gdb/testsuite/gdb.xml/tdesc-regs.exp 2007-12-07 17:02:17.000000000 +0000 @@ -33,7 +33,7 @@ set core-regs {arm-core.xml} } "mips*-*-*" { - set core-regs {mips-cpu.xml mips-cp0.xml mips-fpu.xml} + set core-regs {mips-cpu.xml mips-cp0.xml mips-fpu.xml mips-dsp.xml} } "powerpc*-*-*" { set regdir "rs6000/"