From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13997 invoked by alias); 25 Apr 2010 15:48:24 -0000 Received: (qmail 13237 invoked by uid 22791); 25 Apr 2010 15:48:09 -0000 X-SWARE-Spam-Status: No, hits=1.2 required=5.0 tests=BAYES_50,TW_EB,TW_FP,TW_MX,TW_WT,TW_XC,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 25 Apr 2010 15:47:59 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 022A12BAC95; Sun, 25 Apr 2010 11:47:51 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id AHwZiLYeBg9d; Sun, 25 Apr 2010 11:47:50 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 366C42BAC96; Sun, 25 Apr 2010 11:47:50 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id D08DCF5896; Sun, 25 Apr 2010 11:47:49 -0400 (EDT) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Joel Brobecker Subject: [vxworks 09/14] remote-wtx-hw / register fetch/store support. Date: Sun, 25 Apr 2010 15:48:00 -0000 Message-Id: <1272210447-13895-10-git-send-email-brobecker@adacore.com> In-Reply-To: <1272210447-13895-1-git-send-email-brobecker@adacore.com> References: <1272210447-13895-1-git-send-email-brobecker@adacore.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: 2010-04/txt/msg00843.txt.bz2 This module is in charge of fetching/storing a given register. There are two issues to consider: - GDB regno to WTX regno translation; - determine which register set a given register belongs to. 2010-04-24 Joel Brobecker * remote-wtx-hw.h, remote-wtx-hw.c: New files. --- gdb/remote-wtx-hw.c | 552 +++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/remote-wtx-hw.h | 56 +++++ 2 files changed, 608 insertions(+), 0 deletions(-) create mode 100644 gdb/remote-wtx-hw.c create mode 100644 gdb/remote-wtx-hw.h diff --git a/gdb/remote-wtx-hw.c b/gdb/remote-wtx-hw.c new file mode 100644 index 0000000..fb87dab --- /dev/null +++ b/gdb/remote-wtx-hw.c @@ -0,0 +1,552 @@ +/* Support for the WTX protocol. + + Copyright (C) 2007 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "remote-wtx-hw.h" +#include "gdb_assert.h" +#include "regcache.h" +#include "gdbcmd.h" + +/* Registers in WTX are stored consecutively in a series of memory blocks, + with one block per register set. The following structure details + for a given register its position in the block, and the associated + register set. A negative offset means that the register is not + accessible with WTX. + + brobecker/2007-06-25: On older versions of this code, we also used + to store the register size, but this should not be necessary. + GDB already knows the register size, and it should match the size + needed by WTX. */ + +struct wtx_hw_register +{ + UINT32 register_offset; + WTX_REG_SET_TYPE register_set; +}; + +/* i386 registers description, as seen by VxWorks. */ + +static const struct wtx_hw_register i386_register_map [] = +{ + /* Data registers. */ + {0x1c, WTX_REG_SET_IU}, /* eax */ + {0x18, WTX_REG_SET_IU}, /* ecx */ + {0x14, WTX_REG_SET_IU}, /* edx */ + {0x10, WTX_REG_SET_IU}, /* ebx */ + {0x0c, WTX_REG_SET_IU}, /* esp */ + {0x08, WTX_REG_SET_IU}, /* ebp */ + {0x04, WTX_REG_SET_IU}, /* esi */ + {0x00, WTX_REG_SET_IU}, /* edi */ + {0x24, WTX_REG_SET_IU}, /* pc */ + {0x20, WTX_REG_SET_IU}, /* eflags */ + + /* Segment registers (not accessible). */ + + {-1, WTX_REG_SET_IU}, /* cs */ + {-1, WTX_REG_SET_IU}, /* ss */ + {-1, WTX_REG_SET_IU}, /* ds */ + {-1, WTX_REG_SET_IU}, /* es */ + {-1, WTX_REG_SET_IU}, /* fs */ + {-1, WTX_REG_SET_IU}, /* gs */ + + /* Floating Point registers. */ + {0x1c, WTX_REG_SET_FPU}, /* st0 */ + {0x16, WTX_REG_SET_FPU}, /* st1 */ + {0x20, WTX_REG_SET_FPU}, /* st2 */ + {0x2a, WTX_REG_SET_FPU}, /* st3 */ + {0x34, WTX_REG_SET_FPU}, /* st4 */ + {0x3e, WTX_REG_SET_FPU}, /* st5 */ + {0x48, WTX_REG_SET_FPU}, /* st6 */ + {0x52, WTX_REG_SET_FPU}, /* st7 */ + {0x00, WTX_REG_SET_FPU}, /* fpc */ + {0x04, WTX_REG_SET_FPU}, /* fps */ + {0x08, WTX_REG_SET_FPU}, /* fpt */ + {-1, WTX_REG_SET_IU}, /* fiseg */ + {-1, WTX_REG_SET_IU}, /* fioff */ + {-1, WTX_REG_SET_IU}, /* foseg */ + {-1, WTX_REG_SET_IU}, /* fooff */ + {-1, WTX_REG_SET_IU}, /* fop */ + {-1, WTX_REG_SET_IU}, /* xmm0 */ + {-1, WTX_REG_SET_IU}, /* xmm1 */ + {-1, WTX_REG_SET_IU}, /* xmm2 */ + {-1, WTX_REG_SET_IU}, /* xmm3 */ + {-1, WTX_REG_SET_IU}, /* xmm4 */ + {-1, WTX_REG_SET_IU}, /* xmm5 */ + {-1, WTX_REG_SET_IU}, /* xmm6 */ + {-1, WTX_REG_SET_IU}, /* xmm7 */ + {-1, WTX_REG_SET_IU}, /* mxcsr */ + + /* MMX pseudo-registers (not accessible). */ + + {-1, WTX_REG_SET_IU}, /* mm0 */ + {-1, WTX_REG_SET_IU}, /* mm1 */ + {-1, WTX_REG_SET_IU}, /* mm2 */ + {-1, WTX_REG_SET_IU}, /* mm3 */ + {-1, WTX_REG_SET_IU}, /* mm4 */ + {-1, WTX_REG_SET_IU}, /* mm5 */ + {-1, WTX_REG_SET_IU}, /* mm6 */ + {-1, WTX_REG_SET_IU} /* mm7 */ +}; + + +static const struct wtx_hw_register ppc_register_map[] = +{ + /* General purpose registers. */ + + {0x00, WTX_REG_SET_IU}, /* r0 (0) */ + {0x04, WTX_REG_SET_IU}, /* r1 */ + {0x08, WTX_REG_SET_IU}, /* r2 */ + {0x0c, WTX_REG_SET_IU}, /* r3 */ + {0x10, WTX_REG_SET_IU}, /* r4 */ + {0x14, WTX_REG_SET_IU}, /* r5 */ + {0x18, WTX_REG_SET_IU}, /* r6 */ + {0x1c, WTX_REG_SET_IU}, /* r7 */ + {0x20, WTX_REG_SET_IU}, /* r8 (8) */ + {0x24, WTX_REG_SET_IU}, /* r9 */ + {0x28, WTX_REG_SET_IU}, /* r10 */ + {0x2c, WTX_REG_SET_IU}, /* r11 */ + {0x30, WTX_REG_SET_IU}, /* r12 */ + {0x34, WTX_REG_SET_IU}, /* r13 */ + {0x38, WTX_REG_SET_IU}, /* r14 */ + {0x3c, WTX_REG_SET_IU}, /* r15 (16) */ + {0x40, WTX_REG_SET_IU}, /* r16 */ + {0x44, WTX_REG_SET_IU}, /* r17 */ + {0x48, WTX_REG_SET_IU}, /* r18 */ + {0x4c, WTX_REG_SET_IU}, /* r19 */ + {0x50, WTX_REG_SET_IU}, /* r20 */ + {0x54, WTX_REG_SET_IU}, /* r21 */ + {0x58, WTX_REG_SET_IU}, /* r22 */ + {0x5c, WTX_REG_SET_IU}, /* r23 */ + {0x60, WTX_REG_SET_IU}, /* r24 (24) */ + {0x64, WTX_REG_SET_IU}, /* r25 */ + {0x68, WTX_REG_SET_IU}, /* r26 */ + {0x6c, WTX_REG_SET_IU}, /* r27 */ + {0x70, WTX_REG_SET_IU}, /* r28 */ + {0x74, WTX_REG_SET_IU}, /* r29 */ + {0x78, WTX_REG_SET_IU}, /* r30 */ + {0x7c, WTX_REG_SET_IU}, /* r31 */ + {0x00, WTX_REG_SET_FPU}, /* f0 (32) */ + {0x08, WTX_REG_SET_FPU}, /* f1 */ + {0x10, WTX_REG_SET_FPU}, /* f2 */ + {0x18, WTX_REG_SET_FPU}, /* f3 */ + {0x20, WTX_REG_SET_FPU}, /* f4 */ + {0x28, WTX_REG_SET_FPU}, /* f5 */ + {0x30, WTX_REG_SET_FPU}, /* f6 */ + {0x38, WTX_REG_SET_FPU}, /* f7 */ + {0x40, WTX_REG_SET_FPU}, /* f8 (40) */ + {0x48, WTX_REG_SET_FPU}, /* f9 */ + {0x50, WTX_REG_SET_FPU}, /* f10 */ + {0x58, WTX_REG_SET_FPU}, /* f11 */ + {0x60, WTX_REG_SET_FPU}, /* f12 */ + {0x68, WTX_REG_SET_FPU}, /* f13 */ + {0x70, WTX_REG_SET_FPU}, /* f14 */ + {0x78, WTX_REG_SET_FPU}, /* f15 */ + {0x80, WTX_REG_SET_FPU}, /* f16 (48) */ + {0x88, WTX_REG_SET_FPU}, /* f17 */ + {0x90, WTX_REG_SET_FPU}, /* f18 */ + {0x98, WTX_REG_SET_FPU}, /* f19 */ + {0xa0, WTX_REG_SET_FPU}, /* f20 */ + {0xa8, WTX_REG_SET_FPU}, /* f21 */ + {0xb0, WTX_REG_SET_FPU}, /* f22 */ + {0xb8, WTX_REG_SET_FPU}, /* f23 */ + {0xc0, WTX_REG_SET_FPU}, /* f24 (56) */ + {0xc8, WTX_REG_SET_FPU}, /* f25 */ + {0xd0, WTX_REG_SET_FPU}, /* f26 */ + {0xd8, WTX_REG_SET_FPU}, /* f27 */ + {0xe0, WTX_REG_SET_FPU}, /* f28 */ + {0xe8, WTX_REG_SET_FPU}, /* f29 */ + {0xf0, WTX_REG_SET_FPU}, /* f30 */ + {0xf8, WTX_REG_SET_FPU}, /* f31 */ + {0x8c, WTX_REG_SET_IU}, /* pc (64) */ + {0x80, WTX_REG_SET_IU}, /* ps/msr */ + + /* Special purpose registers. */ + + {0x90, WTX_REG_SET_IU}, /* cr (66) */ + {0x84, WTX_REG_SET_IU}, /* lr */ + {0x88, WTX_REG_SET_IU}, /* ctr */ + {0x94, WTX_REG_SET_IU}, /* xer */ + {0x100, WTX_REG_SET_FPU}, /* fpscr */ + + /* Unused register slots (71 - 105). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (71). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (72). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (73). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (74). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (75). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (76). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (77). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (78). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (79). */ + + {-1, WTX_REG_SET_IU}, /* Empty register slot (80). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (81). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (82). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (83). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (84). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (85). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (86). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (87). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (88). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (89). */ + + {-1, WTX_REG_SET_IU}, /* Empty register slot (90). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (91). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (92). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (93). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (94). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (95). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (96). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (97). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (98). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (99). */ + + {-1, WTX_REG_SET_IU}, /* Empty register slot (100). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (101). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (102). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (103). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (104). */ + {-1, WTX_REG_SET_IU}, /* Empty register slot (105). */ + + /* AltiVec registers. + + They are only supported starting with VxWorks 5.5 and PSC 2.1. + brobecker/2007-11-02: For now, we removed support for these registers + regardless of the VxWorks version in order to allow us to build GDB + on older versions of VxWorks. We'll investigate conditional support + later (note that these registers are part of the WTX_REG_SET_AV + register set). */ + + {-1, WTX_REG_SET_IU}, /* vr0 (106) */ + {-1, WTX_REG_SET_IU}, /* vr1 */ + {-1, WTX_REG_SET_IU}, /* vr2 */ + {-1, WTX_REG_SET_IU}, /* vr3 */ + {-1, WTX_REG_SET_IU}, /* vr4 */ + {-1, WTX_REG_SET_IU}, /* vr5 */ + {-1, WTX_REG_SET_IU}, /* vr6 */ + {-1, WTX_REG_SET_IU}, /* vr7 */ + {-1, WTX_REG_SET_IU}, /* vr8 */ + {-1, WTX_REG_SET_IU}, /* vr9 */ + {-1, WTX_REG_SET_IU}, /* vr10 */ + {-1, WTX_REG_SET_IU}, /* vr11 */ + {-1, WTX_REG_SET_IU}, /* vr12 */ + {-1, WTX_REG_SET_IU}, /* vr13 */ + {-1, WTX_REG_SET_IU}, /* vr14 */ + {-1, WTX_REG_SET_IU}, /* vr15 */ + {-1, WTX_REG_SET_IU}, /* vr16 */ + {-1, WTX_REG_SET_IU}, /* vr17 */ + {-1, WTX_REG_SET_IU}, /* vr18 */ + {-1, WTX_REG_SET_IU}, /* vr19 */ + {-1, WTX_REG_SET_IU}, /* vr20 */ + {-1, WTX_REG_SET_IU}, /* vr21 */ + {-1, WTX_REG_SET_IU}, /* vr22 */ + {-1, WTX_REG_SET_IU}, /* vr23 */ + {-1, WTX_REG_SET_IU}, /* vr24 */ + {-1, WTX_REG_SET_IU}, /* vr25 */ + {-1, WTX_REG_SET_IU}, /* vr26 */ + {-1, WTX_REG_SET_IU}, /* vr27 */ + {-1, WTX_REG_SET_IU}, /* vr28 */ + {-1, WTX_REG_SET_IU}, /* vr29 */ + {-1, WTX_REG_SET_IU}, /* vr30 */ + {-1, WTX_REG_SET_IU}, /* vr31 */ + {-1, WTX_REG_SET_IU}, /* vscr */ + {-1, WTX_REG_SET_IU}, /* vrsave */ + + /* dl registers (not accessible either). */ + {-1, WTX_REG_SET_IU}, /* dl0 */ + {-1, WTX_REG_SET_IU}, /* dl1 */ + {-1, WTX_REG_SET_IU}, /* dl2 */ + {-1, WTX_REG_SET_IU}, /* dl3 */ + {-1, WTX_REG_SET_IU}, /* dl4 */ + {-1, WTX_REG_SET_IU}, /* dl5 */ + {-1, WTX_REG_SET_IU}, /* dl6 */ + {-1, WTX_REG_SET_IU}, /* dl7 */ + {-1, WTX_REG_SET_IU}, /* dl8 */ + {-1, WTX_REG_SET_IU}, /* dl9 */ + {-1, WTX_REG_SET_IU}, /* dl10 */ + {-1, WTX_REG_SET_IU}, /* dl11 */ + {-1, WTX_REG_SET_IU}, /* dl12 */ + {-1, WTX_REG_SET_IU}, /* dl13 */ + {-1, WTX_REG_SET_IU}, /* dl14 */ + {-1, WTX_REG_SET_IU}, /* dl15 */ +}; + +/* The following variables point to the appropriate register table + depending on the target. These are updated when we connect + to the target server. */ + +static const struct wtx_hw_register *wtx_hw_register_map = NULL; +static int wtx_hw_register_map_len = 0; + +/* Whether we should complain or not if we are trying to store/fetch a + register which is not accessible. + + FIXME: guitton/2007-11-15: this should not be needed. We should always + have a warning if we are not able to store or fetch a register. However, + for some targets (e.g. x86), this generates a lot of bogus warnings. So + we disable these warnings for now. */ + +static int wtx_register_complaints = 0; + +/* Inspect the target gdbarch vector, and initialize the internal + state of this module. This include initializing elements such + as the register map, for instance. + + This function must be called before any other function is used. */ + +void +wtx_hw_initialize (void) +{ + const struct bfd_arch_info *arch_info = + gdbarch_bfd_arch_info (target_gdbarch); + + gdb_assert (arch_info != NULL); + + switch (arch_info->arch) + { + case bfd_arch_rs6000: + case bfd_arch_powerpc: + wtx_hw_register_map = ppc_register_map; + wtx_hw_register_map_len = + sizeof (ppc_register_map) / sizeof (struct wtx_hw_register); + break; + + case bfd_arch_i386: + wtx_hw_register_map = i386_register_map; + wtx_hw_register_map_len = + sizeof (i386_register_map) / sizeof (struct wtx_hw_register); + break; + + default: + error (_("This architecture is currently not supported")); + } +} + +/* Return non-zero if the given register can be fetched & stored. */ + +static int +wtx_hw_register_supported_p (int gdb_regnum) +{ + gdb_assert (wtx_hw_register_map != NULL); + gdb_assert (gdb_regnum <= wtx_hw_register_map_len); + + if (wtx_hw_register_map [gdb_regnum].register_offset == -1) + return 0; /* Offset unknown, register is not supported. */ + + return 1; +} + + +/* Fetch the value of a register given its GDB_REGNUM, and store it + inside REG_VAL. + + Register numbering in GDB do not necessarily correspond to the + numbering used by WTX. This function translates the GDB_REGNUM + into a WTX register number before calling the WTX routine. */ + +int +wtx_hw_fetch_register (struct gdbarch *gdbarch, + WTX_CONTEXT_TYPE context_type, + WTX_CONTEXT_ID_T context_id, + int gdb_regnum, + gdb_byte *reg_val) +{ + if (!wtx_hw_register_supported_p (gdb_regnum)) + { + if (wtx_register_complaints) + warning (_("Fetching register %s is not supported"), + gdbarch_register_name (gdbarch, gdb_regnum)); + return 0; + } + + return wtxapi_regs_get (context_type, context_id, + wtx_hw_register_map [gdb_regnum].register_set, + wtx_hw_register_map [gdb_regnum].register_offset, + register_size (gdbarch, gdb_regnum), + reg_val); +} + +/* Fetch the value of the given register given its GDB_REGNUM, + and store it inside REG_VAL. Instead of using WTX to read + the register value, read the register value from the memory + region where the registers have been saved for this task. + + REGS_ADDR is the base address where the GP registers have been saved. + FP_REGS_ADDR, is the base address where the FP registers have been saved. + + GP registers are always supported, and FP registers are supported + only if FP_REGS_ADDR is not zero. Other registers (Eg altivec registers) + are not supported in this mode. */ + +int +wtx_hw_fetch_register_in_memory (struct gdbarch *gdbarch, + WTX_CONTEXT_TYPE context_type, + WTX_CONTEXT_ID_T context_id, + CORE_ADDR regs_addr, + CORE_ADDR fp_regs_addr, + int gdb_regnum, + gdb_byte *reg_val) +{ + int reg_offset; + CORE_ADDR reg_addr = 0; + + if (!wtx_hw_register_supported_p (gdb_regnum)) + { + if (wtx_register_complaints) + warning (_("Fetching register %s is not supported"), + gdbarch_register_name (gdbarch, gdb_regnum)); + return 0; + } + + reg_offset = wtx_hw_register_map [gdb_regnum].register_offset; + switch (wtx_hw_register_map [gdb_regnum].register_set) + { + case WTX_REG_SET_IU: + reg_addr = regs_addr + reg_offset; + break; + case WTX_REG_SET_FPU: + if (fp_regs_addr != 0) + reg_addr = fp_regs_addr + reg_offset; + break; + } + + if (reg_addr == 0) + { + /* We couldn't determine the location where the register is stored. + Warn the user and abort. */ + if (wtx_register_complaints) + warning (_("Cannot fetch register %s in this mode"), + gdbarch_register_name (gdbarch, gdb_regnum)); + return 0; + } + + return (wtxapi_mem_read (wtxapi_pd_current_get (), reg_addr, reg_val, + register_size (gdbarch, gdb_regnum)) + != WTX_ERROR); +} + +/* Store the value from REG_VAL into the register identified by + GDB_REGNUM. + + Register numbering in GDB do not necessarily correspond to the + numbering used by WTX. This function translates the GDB_REGNUM + into a WTX register number before calling the WTX routine. */ + +int +wtx_hw_store_register (struct gdbarch *gdbarch, WTX_CONTEXT_TYPE context_type, + WTX_CONTEXT_ID_T context_id, + int gdb_regnum, + gdb_byte *reg_val) +{ + /* brobecker/2007-10-16: On powerpc targets, there seems to be a bug + in the VxWorks system that causes the storing of the msr register + to fail. Although the WTX request returns with no error, the actual + new value of the msr is often zero instead of the intended value, + later causing dramatic issues such as floating-point exceptions or + even system-wide crashes. So we simply silently ignore stores to + that register for now. */ + if (wtx_hw_register_map == ppc_register_map + && gdb_regnum == 65) + return 0; + + if (!wtx_hw_register_supported_p (gdb_regnum)) + { + if (wtx_register_complaints) + warning (_("Storing register %s is not supported"), + gdbarch_register_name (gdbarch, gdb_regnum)); + return 0; + } + + return wtxapi_regs_set (context_type, context_id, + wtx_hw_register_map [gdb_regnum].register_set, + wtx_hw_register_map [gdb_regnum].register_offset, + register_size (gdbarch, gdb_regnum), + reg_val); +} + +/* Store the value from REG_VAL into the register identified by + GDB_REGNUM. Instead of using WTX to write the register value, + we write the new value in the memory region where the register + has been saved for this task. + + REGS_ADDR is the base address where the GP registers have been saved. + FP_REGS_ADDR, is the base address where the FP registers have been saved. + + GP registers are always supported, and FP registers are supported + only if FP_REGS_ADDR is not zero. Other registers (Eg altivec registers) + are not supported in this mode. */ + +int +wtx_hw_store_register_in_memory (struct gdbarch *gdbarch, + WTX_CONTEXT_TYPE context_type, + WTX_CONTEXT_ID_T context_id, + CORE_ADDR regs_addr, + CORE_ADDR fp_regs_addr, + int gdb_regnum, + gdb_byte *reg_val) +{ + int reg_offset; + CORE_ADDR reg_addr = 0; + + if (!wtx_hw_register_supported_p (gdb_regnum)) + { + if (wtx_register_complaints) + warning (_("Storing register %s is not supported"), + gdbarch_register_name (gdbarch, gdb_regnum)); + return 0; + } + + reg_offset = wtx_hw_register_map [gdb_regnum].register_offset; + switch (wtx_hw_register_map [gdb_regnum].register_set) + { + case WTX_REG_SET_IU: + reg_addr = regs_addr + reg_offset; + break; + case WTX_REG_SET_FPU: + if (fp_regs_addr != 0) + reg_addr = fp_regs_addr + reg_offset; + break; + } + + if (reg_addr == 0) + { + /* We couldn't determine the location where the register is stored. + Warn the user and abort. */ + if (wtx_register_complaints) + warning (_("Cannot store register %s in this mode"), + gdbarch_register_name (gdbarch, gdb_regnum)); + return 0; + } + + return (wtxapi_mem_write (wtxapi_pd_current_get (), reg_val, reg_addr, + register_size (gdbarch, gdb_regnum)) + != WTX_ERROR); +} + +void +initialize_remote_wtx_hw () +{ + add_setshow_boolean_cmd ("wtx-register-complaints", no_class, + &wtx_register_complaints,"\ +Set whether to complain if a register is not accessible.", "\ +Show whether to complain if a register is not accessible.", "\ +If set, GDB complains when it cannot store/fetch a register.", + NULL, NULL, + &setlist, &showlist); +} diff --git a/gdb/remote-wtx-hw.h b/gdb/remote-wtx-hw.h new file mode 100644 index 0000000..f5c7813 --- /dev/null +++ b/gdb/remote-wtx-hw.h @@ -0,0 +1,56 @@ +/* Support for the WTX protocol. + + Copyright (C) 2007, 2010 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef REMOTE_WTX_HW_H +#define REMOTE_WTX_HW_H + +#include "defs.h" +#include "remote-wtxapi.h" + +extern void wtx_hw_initialize (void); + +extern int wtx_hw_fetch_register (struct gdbarch *gdbarch, + WTX_CONTEXT_TYPE context_type, + WTX_CONTEXT_ID_T context_id, + int gdb_regnum, + gdb_byte *reg_val); + +extern int wtx_hw_fetch_register_in_memory (struct gdbarch *gdbarch, + WTX_CONTEXT_TYPE context_type, + WTX_CONTEXT_ID_T context_id, + CORE_ADDR regs_addr, + CORE_ADDR fp_regs_addr, + int gdb_regnum, + gdb_byte *reg_val); + +extern int wtx_hw_store_register (struct gdbarch *gdbarch, + WTX_CONTEXT_TYPE context_type, + WTX_CONTEXT_ID_T context_id, + int gdb_regnum, + gdb_byte *reg_val); + +extern int wtx_hw_store_register_in_memory (struct gdbarch *gdbarch, + WTX_CONTEXT_TYPE context_type, + WTX_CONTEXT_ID_T context_id, + CORE_ADDR regs_addr, + CORE_ADDR fp_regs_addr, + int gdb_regnum, + gdb_byte *reg_val); + +#endif -- 1.6.3.3