From nobody Mon Feb 9 11:22:58 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516095707083403.4386590815245; Tue, 16 Jan 2018 01:41:47 -0800 (PST) Received: from localhost ([::1]:51802 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ebNkO-0003U7-Qq for importer@patchew.org; Tue, 16 Jan 2018 04:41:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58792) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ebNjP-00034U-27 for qemu-devel@nongnu.org; Tue, 16 Jan 2018 04:40:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ebNjK-0007Qy-3H for qemu-devel@nongnu.org; Tue, 16 Jan 2018 04:40:35 -0500 Received: from smtp1.lauterbach.com ([62.154.241.196]:39021) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ebNjJ-0007EI-JU for qemu-devel@nongnu.org; Tue, 16 Jan 2018 04:40:30 -0500 Received: (qmail 30050 invoked by uid 484); 16 Jan 2018 09:40:11 -0000 Received: from unknown (HELO [192.168.187.23]) (Authenticated_SSL:abouassida@[41.224.44.126]) (envelope-sender ) by smtp1.lauterbach.com (qmail-ldap-1.03) with ECDHE-RSA-AES256-GCM-SHA384 encrypted SMTP for ; 16 Jan 2018 09:40:10 -0000 X-Qmail-Scanner-Diagnostics: from 41.224.44.126 by smtp1.lauterbach.com (envelope-from , uid 484) with qmail-scanner-2.11 (mhr: 1.0. clamdscan: 0.99/21437. spamassassin: 3.4.0. Clear:RC:1(41.224.44.126):. Processed in 0.311926 secs); 16 Jan 2018 09:40:11 -0000 From: Abdallah Bouassida To: qemu-arm@nongnu.org Message-ID: Date: Tue, 16 Jan 2018 10:40:10 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2 MIME-Version: 1.0 Content-Language: en-US X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 62.154.241.196 Content-Type: text/plain; charset="utf-8"; format="flowed" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.21 Subject: [Qemu-devel] [PATCH RFC] target-arm:Add a dynamic XML-description of the cp-registers to GDB X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Khaled Jmal , QEMU Developers , Peter Maydell Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 [PATCH RFC] target-arm:Add a dynamic XML-description of the cp-registers=20 to GDB This patch offers to GDB the ability to read/write all the coprocessor registers for ARM and ARM64 by generating dynamically an XML-description for these registers. - gdbstub.c : =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 *Extend the get_feature_xml() to han= dle the dynamic XML=20 generation for =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 architectures that supp= ort this=20 (gdb_coprocessor_dynnamic_xml =3D=3D true) =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 *Extend the gdb_write_register() and= gdb_read_register() to=20 handle the =C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 write and the read of th= ese registers. - include/qom/cpu.h: =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 *Add a new structure "XMLDynamicDesc= ription". =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *Declare the new variables and = function pointers. - target/arm/cpu.c: =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *Initialize the new variables a= nd function pointers for ARM. - target/arm/cpu.h: =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 *Declare the new read, write and XML= dynamic generation functions. =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 *Declare the write_raw_cp_reg() as I= have changed it to non static. - target/arm/gdbstub.c: =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 *Define the new functions for ARM: =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 arm_generate_xml(= ): is called for each register of the=20 hashtable cp_regs =C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2= =A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 to generate the right XML "= " line for it. =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 arm_get_feature_x= ml_dynamically(): generate the XML=20 dynamically. =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 arm_cpu_gdb_read_= cpregister(): To read the coprocessor=20 registers. =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 arm_cpu_gdb_write= _cpregister(): To write the coprocessor=20 registers. This patch is tagged as [RFC] because I need help to review the=20 following points: *I only take the registers that (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) So, am I covering all the Coprocessor registers with that? *For the ARM64, should I differentiate the registers that have two views=20 (32 and 64) Maybe by adding in the XML description a "32" tag for the registers name=20 for the 32bit view and a "64" for the 64bit view. *How to properly handle the secure and the non secure views? Signed-off-by: Abdallah Bouassida --- =C2=A0gdbstub.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 | 18 +++++++++++ =C2=A0include/qom/cpu.h=C2=A0=C2=A0=C2=A0 | 19 +++++++++++ =C2=A0target/arm/cpu.c=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 5 +++ =C2=A0target/arm/cpu.h=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 6 +++- =C2=A0target/arm/gdbstub.c | 90=20 ++++++++++++++++++++++++++++++++++++++++++++++++++++ =C2=A0target/arm/helper.c=C2=A0 |=C2=A0 3 +- =C2=A06 files changed, 138 insertions(+), 3 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index f1d5148..b0124c8 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -670,10 +670,20 @@ static const char *get_feature_xml(const char *p,=20 const char **newp, =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 pstrcat(target_xml, sizeof(target_xml), r->xml); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 pstrcat(target_xml, sizeof(target_xml), "\"/>"); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (cc-= >gdb_coprocessor_dynamic_xml) { +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 pstrcat(target_xml, sizeof(target_xml), ""); +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 p= strcat(target_xml, sizeof(target_xml), ""); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return target_xml; =C2=A0=C2=A0=C2=A0=C2=A0 } +=C2=A0=C2=A0 =C2=A0if (strncmp(p, "coprocessor_dynamic.xml", len) =3D=3D 0= ) { +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 CPUState *cpu =3D first_cpu; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0return cc->get_feature_xml_dynamical= ly(cpu); +=C2=A0=C2=A0 =C2=A0} =C2=A0=C2=A0=C2=A0=C2=A0 for (i =3D 0; ; i++) { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 name =3D xml_builtin[i][0= ]; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!name || (strncmp(nam= e, p, len) =3D=3D 0 && strlen(name) =3D=3D len)) @@ -697,6 +707,10 @@ static int gdb_read_register(CPUState *cpu, uint8_t=20 *mem_buf, int reg) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 r= eturn r->get_reg(env, mem_buf, reg - r->base_reg); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0=C2=A0 } + +=C2=A0=C2=A0=C2=A0 if (reg < cpu->gdb_num_regs + cc->gdb_num_cpregs) { +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return cc->gdb_read_cpregister(= cpu, mem_buf, reg -=20 cpu->gdb_num_regs); +=C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0=C2=A0 return 0; =C2=A0} @@ -715,6 +729,10 @@ static int gdb_write_register(CPUState *cpu,=20 uint8_t *mem_buf, int reg) =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 r= eturn r->set_reg(env, mem_buf, reg - r->base_reg); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0=C2=A0 } + +=C2=A0=C2=A0=C2=A0 if (reg < cpu->gdb_num_regs + cc->gdb_num_cpregs) { +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return cc->gdb_write_cpregister= (cpu, mem_buf, reg -=20 cpu->gdb_num_regs); +=C2=A0=C2=A0=C2=A0 } =C2=A0=C2=A0=C2=A0=C2=A0 return 0; =C2=A0} diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 93bd546..f40ee59 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -76,6 +76,19 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu,=20 hwaddr addr, =C2=A0struct TranslationBlock; =C2=A0/** + * XMLDynamicDescription: + * @desc: Contains the XML descriptions. + * @num_cpregs: Number of the Coprocessor registers seen by GDB. + * @xml_cpregs_ordred_keys: Array that contains the corresponding Key of + * a given cpreg with the same order of the cpreg in the XML description. + */ +typedef struct XMLDynamicDescription { +=C2=A0=C2=A0 =C2=A0char * desc; +=C2=A0=C2=A0=C2=A0 int num_cpregs; +=C2=A0=C2=A0=C2=A0 uint32_t *xml_cpregs_ordred_keys; +} XMLDynamicDescription; + +/** =C2=A0 * CPUClass: =C2=A0 * @class_by_name: Callback to map -cpu command line model name to an =C2=A0 * instantiatable CPU type. @@ -196,6 +209,12 @@ typedef struct CPUClass { =C2=A0=C2=A0=C2=A0=C2=A0 const struct VMStateDescription *vmsd; =C2=A0=C2=A0=C2=A0=C2=A0 const char *gdb_core_xml_file; +=C2=A0=C2=A0=C2=A0 bool gdb_coprocessor_dynamic_xml; +=C2=A0=C2=A0=C2=A0 XMLDynamicDescription dyn_xml; +=C2=A0=C2=A0=C2=A0 int gdb_num_cpregs; +=C2=A0=C2=A0=C2=A0 char * (*get_feature_xml_dynamically)(CPUState *cpu); +=C2=A0=C2=A0=C2=A0 int (*gdb_read_cpregister)(CPUState *cpu, uint8_t *buf,= int reg); +=C2=A0=C2=A0=C2=A0 int (*gdb_write_cpregister)(CPUState *cpu, uint8_t *buf= , int reg); =C2=A0=C2=A0=C2=A0=C2=A0 gchar * (*gdb_arch_name)(CPUState *cpu); =C2=A0=C2=A0=C2=A0=C2=A0 void (*cpu_exec_enter)(CPUState *cpu); diff --git a/target/arm/cpu.c b/target/arm/cpu.c index cc1856c..00efae4 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1751,6 +1751,11 @@ static void arm_cpu_class_init(ObjectClass *oc,=20 void *data) =C2=A0#endif =C2=A0=C2=A0=C2=A0=C2=A0 cc->gdb_num_core_regs =3D 26; =C2=A0=C2=A0=C2=A0=C2=A0 cc->gdb_core_xml_file =3D "arm-core.xml"; +=C2=A0=C2=A0=C2=A0 cc->gdb_coprocessor_dynamic_xml=3Dtrue; +=C2=A0=C2=A0=C2=A0 cc->gdb_num_cpregs =3D 0; +=C2=A0=C2=A0=C2=A0 cc->get_feature_xml_dynamically =3D arm_get_feature_xml= _dynamically; +=C2=A0=C2=A0=C2=A0 cc->gdb_read_cpregister =3D arm_cpu_gdb_read_cpregister; +=C2=A0=C2=A0=C2=A0 cc->gdb_write_cpregister =3D arm_cpu_gdb_write_cpregist= er; =C2=A0=C2=A0=C2=A0=C2=A0 cc->gdb_arch_name =3D arm_gdb_arch_name; =C2=A0=C2=A0=C2=A0=C2=A0 cc->gdb_stop_before_watchpoint =3D true; =C2=A0=C2=A0=C2=A0=C2=A0 cc->debug_excp_handler =3D arm_debug_excp_handler; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 9631670..16f84e3 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -797,6 +797,9 @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState=20 *cpu, vaddr addr, =C2=A0int arm_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); =C2=A0int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); +char *arm_get_feature_xml_dynamically(CPUState *cpu); +int arm_cpu_gdb_read_cpregister(CPUState *cpu, uint8_t *buf, int reg); +int arm_cpu_gdb_write_cpregister(CPUState *cpu, uint8_t *buf, int reg); =C2=A0int arm_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 int cpuid, void *opaque); @@ -2005,7 +2008,8 @@ static inline bool cp_access_ok(int current_el, =C2=A0/* Raw read of a coprocessor register (as needed for migration, etc)= */ =C2=A0uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri); - +void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 uint64_t v); =C2=A0/** =C2=A0 * write_list_to_cpustate =C2=A0 * @cpu: ARMCPU diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index 04c1208..123da12 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -101,3 +101,93 @@ int arm_cpu_gdb_write_register(CPUState *cs,=20 uint8_t *mem_buf, int n) =C2=A0=C2=A0=C2=A0=C2=A0 /* Unknown register.=C2=A0 */ =C2=A0=C2=A0=C2=A0=C2=A0 return 0; =C2=A0} + +static void arm_generate_xml(gpointer key, gpointer value, gpointer cs) +{ +=C2=A0=C2=A0=C2=A0 ARMCPU *cpu =3D ARM_CPU(cs); +=C2=A0=C2=A0=C2=A0 CPUClass *cc =3D CPU_GET_CLASS(cpu); +=C2=A0=C2=A0 =C2=A0XMLDynamicDescription *dyn_xml =3D &cc->dyn_xml; +=C2=A0=C2=A0 =C2=A0ARMCPRegInfo *ri =3D value; +=C2=A0=C2=A0 =C2=A0uint32_t ri_key=3D *(uint32_t *)key; +=C2=A0=C2=A0=C2=A0 CPUARMState *env =3D &cpu->env; +=C2=A0=C2=A0 =C2=A0char **target_xml=3D(char **)&(dyn_xml->desc); +=C2=A0=C2=A0 =C2=A0char *tmp_xml=3D*target_xml; + +=C2=A0=C2=A0 =C2=A0if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (cpreg_field_is_64bit(ri)){ +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (arm_feature(e= nv, ARM_FEATURE_AARCH64)) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0*target_xml=3Dg_strconcat(*target_xml, "name, "\" bitsize=3D\"64\"/>",= NULL); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} else { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0return; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} else { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0*target_xml=3Dg_s= trconcat(*target_xml, "name, "\" bitsize=3D\"32\"/>", NULL); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0g_free(tmp_xml); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0dyn_xml->num_cpregs++; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0dyn_xml->xml_cpregs_ordred_keys=3Dg_= renew(uint32_t, \ +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0dyn_xml->xml_cpregs_ordred_keys, dyn_xml->num_cpregs); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0dyn_xml->xml_cpregs_ordred_keys[dyn_= xml->num_cpregs - 1] =3D ri_key; +=C2=A0=C2=A0 =C2=A0} +} + +char *arm_get_feature_xml_dynamically(CPUState *cs) +{ +=C2=A0=C2=A0=C2=A0 ARMCPU *cpu =3D ARM_CPU(cs); +=C2=A0=C2=A0=C2=A0 CPUClass *cc =3D CPU_GET_CLASS(cpu); + +=C2=A0=C2=A0=C2=A0 cc->dyn_xml.num_cpregs=3D0; +=C2=A0=C2=A0=C2=A0 cc->dyn_xml.desc=3Dg_strconcat("", \ +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "", \ +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 "", NULL); +=C2=A0=C2=A0 =C2=A0g_hash_table_foreach(cpu->cp_regs, arm_generate_xml, cs= ); +=C2=A0=C2=A0=C2=A0 cc->dyn_xml.desc=3Dg_strconcat( cc->dyn_xml.desc, "", NULL); +=C2=A0=C2=A0 =C2=A0cc->gdb_num_cpregs=3Dcc->dyn_xml.num_cpregs; +=C2=A0=C2=A0 =C2=A0return=C2=A0 cc->dyn_xml.desc; +} + +int arm_cpu_gdb_read_cpregister(CPUState *cs, uint8_t *mem_buf, int n) +{ +=C2=A0=C2=A0 =C2=A0ARMCPU *cpu =3D ARM_CPU(cs); +=C2=A0=C2=A0 =C2=A0CPUClass *cc =3D CPU_GET_CLASS(cpu); +=C2=A0=C2=A0=C2=A0 ARMCPRegInfo *ri; +=C2=A0=C2=A0=C2=A0 CPUARMState *env =3D &cpu->env; +=C2=A0=C2=A0=C2=A0 uint32_t key; + +=C2=A0=C2=A0 =C2=A0key =3D cc->dyn_xml.xml_cpregs_ordred_keys[n]; +=C2=A0=C2=A0 =C2=A0ri=3D(ARMCPRegInfo=20 *)get_arm_cp_reginfo(arm_env_get_cpu(env)->cp_regs, key); +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (ri) { +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if(cpreg_field_is_64bit= (ri)){ +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0retu= rn gdb_get_reg64(mem_buf,=20 (uint64_t)read_raw_cp_reg(env,ri)); +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} else { +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0retu= rn gdb_get_reg32(mem_buf,=20 (uint32_t)read_raw_cp_reg(env,ri)); +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0return 0; +} + +int arm_cpu_gdb_write_cpregister(CPUState *cs, uint8_t *mem_buf, int n) +{ +=C2=A0=C2=A0=C2=A0 ARMCPU *cpu =3D ARM_CPU(cs); +=C2=A0=C2=A0=C2=A0 CPUClass *cc =3D CPU_GET_CLASS(cpu); +=C2=A0=C2=A0=C2=A0 ARMCPRegInfo *ri; +=C2=A0=C2=A0=C2=A0 CPUARMState *env =3D &cpu->env; +=C2=A0=C2=A0=C2=A0 uint32_t tmp_buf,key; + +=C2=A0=C2=A0=C2=A0 tmp_buf =3D ldl_p(mem_buf); +=C2=A0=C2=A0=C2=A0 key =3D cc->dyn_xml.xml_cpregs_ordred_keys[n]; +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0ri=3D(ARMCPRegInfo=20 *)get_arm_cp_reginfo(arm_env_get_cpu(env)->cp_regs, key); +=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (ri) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (!(ri->type & ARM_CP_CONST)) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0write_raw_cp_reg(= env, ri, tmp_buf); +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0if (cpreg_field_i= s_64bit(ri)) { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0return 8; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} else { +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2= =A0return 4; +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 =C2=A0} +=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0=C2=A0 } +=C2=A0=C2=A0 =C2=A0} +=C2=A0=C2=A0=C2=A0 return 0; +} diff --git a/target/arm/helper.c b/target/arm/helper.c index d1395f9..fedc6bc 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -191,8 +191,7 @@ uint64_t read_raw_cp_reg(CPUARMState *env, const=20 ARMCPRegInfo *ri) =C2=A0=C2=A0=C2=A0=C2=A0 } =C2=A0} -static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, -=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 uint64_t v) +void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t v) =C2=A0{ =C2=A0=C2=A0=C2=A0=C2=A0 /* Raw write of a coprocessor register (as needed= for migration, etc). =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * Note that constant registers are treated = as write-ignored; the --=20 1.9.1