From: Shahab Vahedi <sha...@synopsys.com> Register layout for the target and the mechanisms to read and set them.
Signed-off-by: Shahab Vahedi <sha...@synopsys.com> --- gdb-xml/arc-aux-minimal.xml | 32 +++ gdb-xml/arc-aux-other.xml | 235 ++++++++++++++++++++ gdb-xml/arc-core-v2.xml | 45 ++++ target/arc/gdbstub.c | 421 ++++++++++++++++++++++++++++++++++++ 4 files changed, 733 insertions(+) create mode 100644 gdb-xml/arc-aux-minimal.xml create mode 100644 gdb-xml/arc-aux-other.xml create mode 100644 gdb-xml/arc-core-v2.xml create mode 100644 target/arc/gdbstub.c diff --git a/gdb-xml/arc-aux-minimal.xml b/gdb-xml/arc-aux-minimal.xml new file mode 100644 index 0000000000..7809c97a8d --- /dev/null +++ b/gdb-xml/arc-aux-minimal.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2018 Free Software Foundation, Inc. + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.arc.aux-minimal"> + <flags id="status32_type" size="4"> + <field name="H" start="0" end="0"/> + <field name="E" start="1" end="4"/> + <field name="AE" start="5" end="5"/> + <field name="DE" start="6" end="6"/> + <field name="U" start="7" end="7"/> + <field name="V" start="8" end="8"/> + <field name="C" start="9" end="9"/> + <field name="N" start="10" end="10"/> + <field name="Z" start="11" end="11"/> + <field name="L" start="12" end="12"/> + <field name="DZ" start="13" end="13"/> + <field name="SC" start="14" end="14"/> + <field name="ES" start="15" end="15"/> + <field name="RB" start="16" end="18"/> + <field name="AD" start="19" end="19"/> + <field name="US" start="20" end="20"/> + <field name="IE" start="31" end="31"/> + </flags> + <reg name="pc" bitsize="32" regnum="36" type="code_ptr" group="general"/> + <reg name="lp_start" bitsize="32" regnum="37" type="code_ptr" group="general"/> + <reg name="lp_end" bitsize="32" regnum="38" type="code_ptr" group="general"/> + <reg name="status32" bitsize="32" regnum="39" type="status32_type" group="general"/> +</feature> diff --git a/gdb-xml/arc-aux-other.xml b/gdb-xml/arc-aux-other.xml new file mode 100644 index 0000000000..86b114af98 --- /dev/null +++ b/gdb-xml/arc-aux-other.xml @@ -0,0 +1,235 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2018 Free Software Foundation, Inc. + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.arc.aux-other"> + <flags id="timer_build_type" size="4"> + <field name="version" start="0" end="7"/> + <field name="t0" start="8" end="8"/> + <field name="t1" start="9" end="9"/> + <field name="rtc" start="10" end="10"/> + <field name="p0" start="16" end="19"/> + <field name="p1" start="20" end="23"/> + </flags> + <flags id="irq_build_type" size="4"> + <field name="version" start="0" end="7"/> + <field name="IRQs" start="8" end="15"/> + <field name="exts" start="16" end="23"/> + <field name="p" start="24" end="27"/> + <field name="f" start="28" end="28"/> + </flags> + <flags id="mpy_build_type" size="4"> + <field name="version32x32" start="0" end="7"/> + <field name="type" start="8" end="9"/> + <field name="cyc" start="10" end="11"/> + <field name="DSP" start="12" end="15"/> + <field name="version16x16" start="16" end="23"/> + </flags> + <flags id="vecbase_build_type" size="4"> + <field name="version" start="2" end="9"/> + <field name="addr" start="10" end="31"/> + </flags> + <flags id="isa_config_type" size="4"> + <field name="version" start="0" end="7"/> + <field name="pc_size" start="8" end="11"/> + <field name="lpc_size" start="12" end="15"/> + <field name="addr_size" start="16" end="19"/> + <field name="b" start="20" end="20"/> + <field name="a" start="21" end="21"/> + <field name="n" start="22" end="22"/> + <field name="l" start="23" end="23"/> + <field name="c" start="24" end="27"/> + <field name="d" start="28" end="31"/> + </flags> + <flags id="timer_ctrl_type" size="4"> + <field name="ie" start="0" end="0"/> + <field name="nh" start="1" end="1"/> + <field name="w" start="2" end="2"/> + <field name="ip" start="3" end="3"/> + <field name="pd" start="4" end="4"/> + </flags> + <flags id="tlbpd0_type" size="4"> + <field name="a" start="0" end="7" type="uint8"/> + <field name="g" start="8" end="8" type="bool"/> + <field name="v" start="9" end="9" type="bool"/> + <field name="sz " start="10" end="10" type="bool"/> + <field name="vpn" start="12" end="30" type="uint32"/> + <field name="s" start="31" end="31" type="bool"/> + </flags> + <flags id="tlbpd1_type" size="4"> + <field name="fc" start="0" end="0"/> + <field name="eu" start="1" end="1"/> + <field name="wu" start="2" end="2"/> + <field name="ru" start="3" end="3"/> + <field name="ek" start="4" end="4"/> + <field name="wk" start="5" end="5"/> + <field name="rk" start="6" end="6"/> + <field name="ppn" start="12" end="31"/> + </flags> + <flags id="tlbindex_type" size="4"> + <field name="index" start="0" end="12"/> + <field name="rc" start="28" end="30"/> + <field name="e" start="31" end="31"/> + </flags> + <flags id="tlbcmd_type" size="4"> + <field name="cmd" start="0" end="5"/> + </flags> + <flags id="pid_type" size="4"> + <field name="p" start="0" end="7" /> + <field name="s" start="29" end="29"/> + <field name="t" start="31" end="31"/> + </flags> + <flags id="erstatus_type" size="4"> + <field name="e" start="1" end="4" /> + <field name="ae" start="5" end="5" /> + <field name="de" start="6" end="6" /> + <field name="u" start="7" end="7" /> + <field name="v" start="8" end="8" /> + <field name="c" start="9" end="9" /> + <field name="n" start="10" end="10"/> + <field name="z" start="11" end="11"/> + <field name="l" start="12" end="12"/> + <field name="dz" start="13" end="13"/> + <field name="sc" start="14" end="14"/> + <field name="es" start="15" end="15"/> + <field name="rb" start="16" end="18"/> + <field name="ad" start="19" end="19"/> + <field name="us" start="20" end="20"/> + <field name="ie" start="31" end="31"/> + </flags> + <flags id="ecr_type" size="4"> + <field name="parameter" start="0" end="7" /> + <field name="causecode" start="8" end="15"/> + <field name="vectornumber" start="16" end="23"/> + <field name="u" start="30" end="30"/> + <field name="p" start="31" end="31"/> + </flags> + <flags id="irq_ctrl_type" size="4"> + <field name="nr" start="0" end="4"/> + <field name="b" start="9" end="9"/> + <field name="l" start="10" end="10"/> + <field name="u" start="11" end="11"/> + <field name="lp" start="13" end="13"/> + </flags> + <flags id="irq_act_type" size="4"> + <field name="active" start="0" end="15"/> + <field name="u" start="31" end="31"/> + </flags> + <flags id="irq_status_type" size="4"> + <field name="p" start="0" end="3"/> + <field name="e" start="4" end="4"/> + <field name="t" start="5" end="5"/> + <field name="ip" start="31" end="31"/> + </flags> + <flags id="mpu_build_type" size="4"> + <field name="version" start="0" end="7"/> + <field name="regions" start="8" end="15"/> + </flags> + <flags id="mpuen_type" size="4"> + <field name="ue" start="3" end="3"/> + <field name="uw" start="4" end="4"/> + <field name="ur" start="5" end="5"/> + <field name="ke" start="6" end="6"/> + <field name="kw" start="7" end="7"/> + <field name="kr" start="8" end="8"/> + <field name="en" start="30" end="30"/> + </flags> + <flags id="mpuecr_type" size="4"> + <field name="mr" start="0" end="7"/> + <field name="vt" start="8" end="9"/> + <field name="ec_code" start="16" end="31"/> + </flags> + <flags id="mpurdb_type" size="4"> + <field name="v" start="0" end="0"/> + <field name="base_addr" start="5" end="31"/> + </flags> + <flags id="mpurdp_type" size="4"> + <field name="size_lower" start="0" end="1"/> + <field name="ue" start="3" end="3"/> + <field name="uw" start="4" end="4"/> + <field name="ur" start="5" end="5"/> + <field name="ke" start="6" end="6"/> + <field name="kw" start="7" end="7"/> + <field name="kr" start="8" end="8"/> + <field name="size_upper" start="9" end="11"/> + </flags> + <!-- build registers --> + <reg name="timer_build" bitsize="32" regnum="40" type="timer_build_type" group=""/> + <reg name="irq_build" bitsize="32" regnum="41" type="irq_build_type" group=""/> + <reg name="mpy_build" bitsize="32" regnum="42" type="mpy_build_type" group=""/> + <reg name="vecbase_build" bitsize="32" regnum="43" type="vecbase_build_type" group=""/> + <reg name="isa_config" bitsize="32" regnum="44" type="isa_config_type" group=""/> + <!-- timer registers --> + <reg name="timer_count0" bitsize="32" regnum="45" group="general"/> + <reg name="timer_ctrl0" bitsize="32" regnum="46" type="timer_ctrl_type" group="general"/> + <reg name="timer_limit0" bitsize="32" regnum="47" group="general"/> + <reg name="timer_count1" bitsize="32" regnum="48" group="general"/> + <reg name="timer_ctrl1" bitsize="32" regnum="49" type="timer_ctrl_type" group="general"/> + <reg name="timer_limit1" bitsize="32" regnum="50" group="general"/> + <!-- mmu registers --> + <reg name="pid" bitsize="32" regnum="51" type="pid_type" group="general"/> + <reg name="tlbpd0" bitsize="32" regnum="52" type="tlbpd0_type" group="general"/> + <reg name="tlbpd1" bitsize="32" regnum="53" type="tlbpd1_type" group="general"/> + <reg name="tlbindex" bitsize="32" regnum="54" type="tlbindex_type" group="general"/> + <reg name="tlbcmd" bitsize="32" regnum="55" type="tlbcmd_type" group="general"/> + <!-- mpu registers --> + <reg name="mpu_build" bitsize="32" regnum="56" type="mpu_build_type" group=""/> + <reg name="mpuen" bitsize="32" regnum="57" type="mpuen_type" group=""/> + <reg name="mpuecr" bitsize="32" regnum="58" type="mpuecr_type" group=""/> + <reg name="mpurdb0" bitsize="32" regnum="59" type="mpurdb_type" group=""/> + <reg name="mpurdb1" bitsize="32" regnum="60" type="mpurdb_type" group=""/> + <reg name="mpurdb2" bitsize="32" regnum="61" type="mpurdb_type" group=""/> + <reg name="mpurdb3" bitsize="32" regnum="62" type="mpurdb_type" group=""/> + <reg name="mpurdb4" bitsize="32" regnum="63" type="mpurdb_type" group=""/> + <reg name="mpurdb5" bitsize="32" regnum="64" type="mpurdb_type" group=""/> + <reg name="mpurdb6" bitsize="32" regnum="65" type="mpurdb_type" group=""/> + <reg name="mpurdb7" bitsize="32" regnum="66" type="mpurdb_type" group=""/> + <reg name="mpurdb8" bitsize="32" regnum="67" type="mpurdb_type" group=""/> + <reg name="mpurdb9" bitsize="32" regnum="68" type="mpurdb_type" group=""/> + <reg name="mpurdb10" bitsize="32" regnum="69" type="mpurdb_type" group=""/> + <reg name="mpurdb11" bitsize="32" regnum="70" type="mpurdb_type" group=""/> + <reg name="mpurdb12" bitsize="32" regnum="71" type="mpurdb_type" group=""/> + <reg name="mpurdb13" bitsize="32" regnum="72" type="mpurdb_type" group=""/> + <reg name="mpurdb14" bitsize="32" regnum="73" type="mpurdb_type" group=""/> + <reg name="mpurdb15" bitsize="32" regnum="74" type="mpurdb_type" group=""/> + <reg name="mpurdp0" bitsize="32" regnum="75" type="mpurdp_type" group=""/> + <reg name="mpurdp1" bitsize="32" regnum="76" type="mpurdp_type" group=""/> + <reg name="mpurdp2" bitsize="32" regnum="77" type="mpurdp_type" group=""/> + <reg name="mpurdp3" bitsize="32" regnum="78" type="mpurdp_type" group=""/> + <reg name="mpurdp4" bitsize="32" regnum="79" type="mpurdp_type" group=""/> + <reg name="mpurdp5" bitsize="32" regnum="80" type="mpurdp_type" group=""/> + <reg name="mpurdp6" bitsize="32" regnum="81" type="mpurdp_type" group=""/> + <reg name="mpurdp7" bitsize="32" regnum="82" type="mpurdp_type" group=""/> + <reg name="mpurdp8" bitsize="32" regnum="83" type="mpurdp_type" group=""/> + <reg name="mpurdp9" bitsize="32" regnum="84" type="mpurdp_type" group=""/> + <reg name="mpurdp10" bitsize="32" regnum="85" type="mpurdp_type" group=""/> + <reg name="mpurdp11" bitsize="32" regnum="86" type="mpurdp_type" group=""/> + <reg name="mpurdp12" bitsize="32" regnum="87" type="mpurdp_type" group=""/> + <reg name="mpurdp13" bitsize="32" regnum="88" type="mpurdp_type" group=""/> + <reg name="mpurdp14" bitsize="32" regnum="89" type="mpurdp_type" group=""/> + <reg name="mpurdp15" bitsize="32" regnum="90" type="mpurdp_type" group=""/> + <!-- exception registers --> + <reg name="erstatus" bitsize="32" regnum="91" type="erstatus_type" group="general"/> + <reg name="erbta" bitsize="32" regnum="92" type="code_ptr" group="general"/> + <reg name="ecr" bitsize="32" regnum="93" type="ecr_type" group="general"/> + <reg name="eret" bitsize="32" regnum="94" type="code_ptr" group="general"/> + <reg name="efa" bitsize="32" regnum="95" type="uint32" group="general"/> + <!-- irq registers --> + <reg name="icause" bitsize="32" regnum="96" type="uint8" group="general"/> + <reg name="aux_irq_ctrl" bitsize="32" regnum="97" type="irq_ctrl_type" group="general"/> + <reg name="aux_irq_act" bitsize="32" regnum="98" type="irq_act_type" group="general"/> + <reg name="irq_priority_pending" bitsize="32" regnum="99" type="uint16" group="general"/> + <reg name="aux_irq_hint" bitsize="32" regnum="100" type="uint8" group="general"/> + <reg name="irq_select" bitsize="32" regnum="101" type="uint8" group="general"/> + <reg name="irq_enable" bitsize="32" regnum="102" type="bool" group="general"/> + <reg name="irq_trigger" bitsize="32" regnum="103" type="bool" group="general"/> + <reg name="irq_status" bitsize="32" regnum="104" type="irq_status_type" group="general"/> + <reg name="irq_pulse_cancel" bitsize="32" regnum="105" type="bool" group="general"/> + <reg name="irq_pending" bitsize="32" regnum="106" type="bool" group="general"/> + <reg name="irq_priority" bitsize="32" regnum="107" type="uint8" group="general"/> + <!-- miscellaneous --> + <reg name="bta" bitsize="32" regnum="108" type="code_ptr" group="general"/> +</feature> diff --git a/gdb-xml/arc-core-v2.xml b/gdb-xml/arc-core-v2.xml new file mode 100644 index 0000000000..550dae3411 --- /dev/null +++ b/gdb-xml/arc-core-v2.xml @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2018 Free Software Foundation, Inc. + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!DOCTYPE feature SYSTEM "gdb-target.dtd"> +<feature name="org.gnu.gdb.arc.core.v2"> + <reg name="r0" bitsize="32" regnum="0" group="general"/> + <reg name="r1" bitsize="32" regnum="1" group="general"/> + <reg name="r2" bitsize="32" regnum="2" group="general"/> + <reg name="r3" bitsize="32" regnum="3" group="general"/> + <reg name="r4" bitsize="32" regnum="4" group="general"/> + <reg name="r5" bitsize="32" regnum="5" group="general"/> + <reg name="r6" bitsize="32" regnum="6" group="general"/> + <reg name="r7" bitsize="32" regnum="7" group="general"/> + <reg name="r8" bitsize="32" regnum="8" group="general"/> + <reg name="r9" bitsize="32" regnum="9" group="general"/> + <reg name="r10" bitsize="32" regnum="10" group="general"/> + <reg name="r11" bitsize="32" regnum="11" group="general"/> + <reg name="r12" bitsize="32" regnum="12" group="general"/> + <reg name="r13" bitsize="32" regnum="13" group="general"/> + <reg name="r14" bitsize="32" regnum="14" group="general"/> + <reg name="r15" bitsize="32" regnum="15" group="general"/> + <reg name="r16" bitsize="32" regnum="16" group="general"/> + <reg name="r17" bitsize="32" regnum="17" group="general"/> + <reg name="r18" bitsize="32" regnum="18" group="general"/> + <reg name="r19" bitsize="32" regnum="19" group="general"/> + <reg name="r20" bitsize="32" regnum="20" group="general"/> + <reg name="r21" bitsize="32" regnum="21" group="general"/> + <reg name="r22" bitsize="32" regnum="22" group="general"/> + <reg name="r23" bitsize="32" regnum="23" group="general"/> + <reg name="r24" bitsize="32" regnum="24" group="general"/> + <reg name="r25" bitsize="32" regnum="25" group="general"/> + <reg name="gp" bitsize="32" regnum="26" type="data_ptr" group="general"/> + <reg name="fp" bitsize="32" regnum="27" type="data_ptr" group="general"/> + <reg name="sp" bitsize="32" regnum="28" type="data_ptr" group="general"/> + <reg name="ilink" bitsize="32" regnum="29" type="code_ptr" group="general"/> + <reg name="r30" bitsize="32" regnum="30" group="general"/> + <reg name="blink" bitsize="32" regnum="31" type="code_ptr" group="general"/> + <reg name="accl" bitsize="32" regnum="32" group="general"/> + <reg name="acch" bitsize="32" regnum="33" group="general"/> + <reg name="lp_count" bitsize="32" regnum="34" type="uint32" group="general"/> + <reg name="pcl" bitsize="32" regnum="35" type="code_ptr" group="general"/> +</feature> diff --git a/target/arc/gdbstub.c b/target/arc/gdbstub.c new file mode 100644 index 0000000000..574e8fdf4b --- /dev/null +++ b/target/arc/gdbstub.c @@ -0,0 +1,421 @@ + +/* + * QEMU ARC CPU + * + * Copyright (c) 2016 Michael Rolnik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * http://www.gnu.org/licenses/lgpl-2.1.html + */ + +#include "qemu/osdep.h" +#include "exec/gdbstub.h" +#include "arc-common.h" +#include "target/arc/regs.h" +#include "internals.h" +#include "irq.h" + +/* gets the register address for a particular processor */ +#define REG_ADDR(reg, processor_type) \ + arc_aux_reg_address_for((reg), (processor_type)) + +int arc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) +{ + ARCCPU *cpu = ARC_CPU(cs); + CPUARCState *env = &cpu->env; + uint32_t regval = 0; + + switch (n) { + case 0 ... 31: + regval = env->r[n]; + break; + case GDB_REG_58: + regval = env->r[58]; + break; + case GDB_REG_59: + regval = env->r[59]; + break; + case GDB_REG_60: + regval = env->r[60]; + break; + case GDB_REG_63: + regval = env->r[63]; + break; + default: + assert(!"Unsupported register is being read."); + } + + return gdb_get_reg32(mem_buf, regval); +} + +int arc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) +{ + ARCCPU *cpu = ARC_CPU(cs); + CPUARCState *env = &cpu->env; + uint32_t regval = ldl_p(mem_buf); + + switch (n) { + case 0 ... 31: + env->r[n] = regval; + break; + case GDB_REG_58: + env->r[58] = regval; + break; + case GDB_REG_59: + env->r[59] = regval; + break; + case GDB_REG_60: + env->r[60] = regval; + break; + case GDB_REG_63: + env->r[63] = regval; + break; + default: + assert(!"Unsupported register is being written."); + } + + return 4; +} + + +static int +arc_aux_minimal_gdb_get_reg(CPUARCState *env, GByteArray *mem_buf, int regnum) +{ + /* TODO: processor type must be set according to configuration */ + static const int processor = ARC_OPCODE_ARCv2HS; + uint32_t regval = 0; + + switch (regnum) { + case GDB_AUX_MIN_REG_PC: + regval = env->pc & 0xfffffffe; + break; + case GDB_AUX_MIN_REG_LPS: + regval = helper_lr(env, REG_ADDR(AUX_ID_lp_start, processor)); + break; + case GDB_AUX_MIN_REG_LPE: + regval = helper_lr(env, REG_ADDR(AUX_ID_lp_end, processor)); + break; + case GDB_AUX_MIN_REG_STATUS: + regval = pack_status32(&env->stat); + break; + default: + assert(!"Unsupported minimal auxiliary register is being read."); + } + return gdb_get_reg32(mem_buf, regval); +} + + +static int +arc_aux_minimal_gdb_set_reg(CPUARCState *env, uint8_t *mem_buf, int regnum) +{ + /* TODO: processor type must be set according to configuration */ + static const int processor = ARC_OPCODE_ARCv2HS; + uint32_t regval = ldl_p(mem_buf); + switch (regnum) { + case GDB_AUX_MIN_REG_PC: + env->pc = regval & 0xfffffffe; + break; + case GDB_AUX_MIN_REG_LPS: + helper_sr(env, regval, REG_ADDR(AUX_ID_lp_start, processor)); + break; + case GDB_AUX_MIN_REG_LPE: + helper_sr(env, regval, REG_ADDR(AUX_ID_lp_end, processor)); + break; + case GDB_AUX_MIN_REG_STATUS: + unpack_status32(&env->stat, regval); + break; + default: + assert(!"Unsupported minimal auxiliary register is being written."); + } + return 4; +} + + +static int +arc_aux_other_gdb_get_reg(CPUARCState *env, GByteArray *mem_buf, int regnum) +{ + /* TODO: processor type must be set according to configuration */ + static const int processor = ARC_OPCODE_ARCv2HS; + uint32_t regval = 0; + switch (regnum) { + case GDB_AUX_OTHER_REG_TIMER_BUILD: + regval = helper_lr(env, REG_ADDR(AUX_ID_timer_build, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_BUILD: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_build, processor)); + break; + case GDB_AUX_OTHER_REG_MPY_BUILD: + regval = helper_lr(env, REG_ADDR(AUX_ID_mpy_build, processor)); + break; + case GDB_AUX_OTHER_REG_VECBASE_BUILD: + regval = env->vecbase_build; + break; + case GDB_AUX_OTHER_REG_ISA_CONFIG: + regval = env->isa_config; + break; + case GDB_AUX_OTHER_REG_TIMER_CNT0: + regval = helper_lr(env, REG_ADDR(AUX_ID_count0, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_CTRL0: + regval = helper_lr(env, REG_ADDR(AUX_ID_control0, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_LIM0: + regval = helper_lr(env, REG_ADDR(AUX_ID_limit0, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_CNT1: + regval = helper_lr(env, REG_ADDR(AUX_ID_count1, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_CTRL1: + regval = helper_lr(env, REG_ADDR(AUX_ID_control1, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_LIM1: + regval = helper_lr(env, REG_ADDR(AUX_ID_limit1, processor)); + break; + case GDB_AUX_OTHER_REG_PID: + regval = helper_lr(env, REG_ADDR(AUX_ID_pid, processor)); + break; + case GDB_AUX_OTHER_REG_TLBPD0: + regval = helper_lr(env, REG_ADDR(AUX_ID_tlbpd0, processor)); + break; + case GDB_AUX_OTHER_REG_TLBPD1: + regval = helper_lr(env, REG_ADDR(AUX_ID_tlbpd1, processor)); + break; + case GDB_AUX_OTHER_REG_TLB_INDEX: + regval = helper_lr(env, REG_ADDR(AUX_ID_tlbindex, processor)); + break; + case GDB_AUX_OTHER_REG_TLB_CMD: + regval = helper_lr(env, REG_ADDR(AUX_ID_tlbcommand, processor)); + break; + /* MPU */ + case GDB_AUX_OTHER_REG_MPU_BUILD: + regval = helper_lr(env, REG_ADDR(AUX_ID_mpu_build, processor)); + break; + case GDB_AUX_OTHER_REG_MPU_EN: + regval = helper_lr(env, REG_ADDR(AUX_ID_mpuen, processor)); + break; + case GDB_AUX_OTHER_REG_MPU_ECR: + regval = helper_lr(env, REG_ADDR(AUX_ID_mpuic, processor)); + break; + case GDB_AUX_OTHER_REG_MPU_BASE0 ... GDB_AUX_OTHER_REG_MPU_BASE15: { + const uint8_t index = regnum - GDB_AUX_OTHER_REG_MPU_BASE0; + regval = helper_lr(env, REG_ADDR(AUX_ID_mpurdb0 + index, processor)); + break; + } + case GDB_AUX_OTHER_REG_MPU_PERM0 ... GDB_AUX_OTHER_REG_MPU_PERM15: { + const uint8_t index = regnum - GDB_AUX_OTHER_REG_MPU_PERM0; + regval = helper_lr(env, REG_ADDR(AUX_ID_mpurdp0 + index, processor)); + break; + } + /* exceptions */ + case GDB_AUX_OTHER_REG_ERSTATUS: + regval = helper_lr(env, REG_ADDR(AUX_ID_erstatus, processor)); + break; + case GDB_AUX_OTHER_REG_ERBTA: + regval = helper_lr(env, REG_ADDR(AUX_ID_erbta, processor)); + break; + case GDB_AUX_OTHER_REG_ECR: + regval = helper_lr(env, REG_ADDR(AUX_ID_ecr, processor)); + break; + case GDB_AUX_OTHER_REG_ERET: + regval = helper_lr(env, REG_ADDR(AUX_ID_eret, processor)); + break; + case GDB_AUX_OTHER_REG_EFA: + regval = helper_lr(env, REG_ADDR(AUX_ID_efa, processor)); + break; + /* interrupt */ + case GDB_AUX_OTHER_REG_ICAUSE: + regval = helper_lr(env, REG_ADDR(AUX_ID_icause, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_CTRL: + regval = helper_lr(env, REG_ADDR(AUX_ID_aux_irq_ctrl, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_ACT: + regval = helper_lr(env, REG_ADDR(AUX_ID_aux_irq_act, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_PRIO_PEND: + regval = env->irq_priority_pending; + break; + case GDB_AUX_OTHER_REG_IRQ_HINT: + regval = helper_lr(env, REG_ADDR(AUX_ID_aux_irq_hint, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_SELECT: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_select, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_ENABLE: + regval = env->irq_bank[env->irq_select & 0xff].enable; + break; + case GDB_AUX_OTHER_REG_IRQ_TRIGGER: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_trigger, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_STATUS: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_status, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_PULSE: + regval = 0; /* write only for clearing the pulse triggered interrupt */ + break; + case GDB_AUX_OTHER_REG_IRQ_PENDING: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_pending, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_PRIO: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_priority, processor)); + break; + case GDB_AUX_OTHER_REG_BTA: + regval = helper_lr(env, REG_ADDR(AUX_ID_bta, processor)); + break; + default: + assert(!"Unsupported other auxiliary register is being read."); + } + return gdb_get_reg32(mem_buf, regval); +} + + +static int +arc_aux_other_gdb_set_reg(CPUARCState *env, uint8_t *mem_buf, int regnum) +{ + /* TODO: processor type must be set according to configuration */ + static const int processor = ARC_OPCODE_ARCv2HS; + uint32_t regval = ldl_p(mem_buf); + switch (regnum) { + case GDB_AUX_OTHER_REG_TIMER_BUILD: + case GDB_AUX_OTHER_REG_IRQ_BUILD: + case GDB_AUX_OTHER_REG_MPY_BUILD: + case GDB_AUX_OTHER_REG_VECBASE_BUILD: + case GDB_AUX_OTHER_REG_ISA_CONFIG: + case GDB_AUX_OTHER_REG_MPU_BUILD: + case GDB_AUX_OTHER_REG_MPU_ECR: + case GDB_AUX_OTHER_REG_ICAUSE: + case GDB_AUX_OTHER_REG_IRQ_PRIO_PEND: + case GDB_AUX_OTHER_REG_IRQ_STATUS: + case GDB_AUX_OTHER_REG_IRQ_PENDING: + /* builds/configs/exceptions/irqs cannot be changed */ + break; + case GDB_AUX_OTHER_REG_TIMER_CNT0: + helper_sr(env, regval, REG_ADDR(AUX_ID_count0, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_CTRL0: + helper_sr(env, regval, REG_ADDR(AUX_ID_control0, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_LIM0: + helper_sr(env, regval, REG_ADDR(AUX_ID_limit0, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_CNT1: + helper_sr(env, regval, REG_ADDR(AUX_ID_count1, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_CTRL1: + helper_sr(env, regval, REG_ADDR(AUX_ID_control1, processor)); + break; + case GDB_AUX_OTHER_REG_TIMER_LIM1: + helper_sr(env, regval, REG_ADDR(AUX_ID_limit1, processor)); + break; + case GDB_AUX_OTHER_REG_PID: + helper_sr(env, regval, REG_ADDR(AUX_ID_pid, processor)); + break; + case GDB_AUX_OTHER_REG_TLBPD0: + helper_sr(env, regval, REG_ADDR(AUX_ID_tlbpd0, processor)); + break; + case GDB_AUX_OTHER_REG_TLBPD1: + helper_sr(env, regval, REG_ADDR(AUX_ID_tlbpd1, processor)); + break; + case GDB_AUX_OTHER_REG_TLB_INDEX: + helper_sr(env, regval, REG_ADDR(AUX_ID_tlbindex, processor)); + break; + case GDB_AUX_OTHER_REG_TLB_CMD: + helper_sr(env, regval, REG_ADDR(AUX_ID_tlbcommand, processor)); + break; + /* MPU */ + case GDB_AUX_OTHER_REG_MPU_EN: + helper_sr(env, regval, REG_ADDR(AUX_ID_mpuen, processor)); + break; + case GDB_AUX_OTHER_REG_MPU_BASE0 ... GDB_AUX_OTHER_REG_MPU_BASE15: { + const uint8_t index = regnum - GDB_AUX_OTHER_REG_MPU_BASE0; + helper_sr(env, regval, REG_ADDR(AUX_ID_mpurdb0 + index, processor)); + break; + } + case GDB_AUX_OTHER_REG_MPU_PERM0 ... GDB_AUX_OTHER_REG_MPU_PERM15: { + const uint8_t index = regnum - GDB_AUX_OTHER_REG_MPU_PERM0; + helper_sr(env, regval, REG_ADDR(AUX_ID_mpurdp0 + index, processor)); + break; + } + /* exceptions */ + case GDB_AUX_OTHER_REG_ERSTATUS: + helper_sr(env, regval, REG_ADDR(AUX_ID_erstatus, processor)); + break; + case GDB_AUX_OTHER_REG_ERBTA: + helper_sr(env, regval, REG_ADDR(AUX_ID_erbta, processor)); + break; + case GDB_AUX_OTHER_REG_ECR: + helper_sr(env, regval, REG_ADDR(AUX_ID_ecr, processor)); + break; + case GDB_AUX_OTHER_REG_ERET: + helper_sr(env, regval, REG_ADDR(AUX_ID_eret, processor)); + break; + case GDB_AUX_OTHER_REG_EFA: + helper_sr(env, regval, REG_ADDR(AUX_ID_efa, processor)); + break; + /* interrupt */ + case GDB_AUX_OTHER_REG_IRQ_CTRL: + helper_sr(env, regval, REG_ADDR(AUX_ID_aux_irq_ctrl, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_ACT: + helper_sr(env, regval, REG_ADDR(AUX_ID_aux_irq_act, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_HINT: + helper_sr(env, regval, REG_ADDR(AUX_ID_aux_irq_hint, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_SELECT: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_select, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_ENABLE: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_enable, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_TRIGGER: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_trigger, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_PULSE: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_pulse_cancel, processor)); + break; + case GDB_AUX_OTHER_REG_IRQ_PRIO: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_priority, processor)); + break; + case GDB_AUX_OTHER_REG_BTA: + helper_sr(env, regval, REG_ADDR(AUX_ID_bta, processor)); + break; + default: + assert(!"Unsupported other auxiliary register is being written."); + } + return 4; +} + + +void arc_cpu_register_gdb_regs_for_features(ARCCPU *cpu) +{ + CPUState *cs = CPU(cpu); + + gdb_register_coprocessor(cs, + arc_aux_minimal_gdb_get_reg, /* getter */ + arc_aux_minimal_gdb_set_reg, /* setter */ + GDB_AUX_MIN_REG_LAST, /* number of registers */ + "arc-aux-minimal.xml", /* feature file */ + 0); /* position in g packet */ + + gdb_register_coprocessor(cs, + arc_aux_other_gdb_get_reg, + arc_aux_other_gdb_set_reg, + GDB_AUX_OTHER_REG_LAST, + "arc-aux-other.xml", + 0); +} + +/*-*-indent-tabs-mode:nil;tab-width:4;indent-line-function:'insert-tab'-*-*/ +/* vim: set ts=4 sw=4 et: */ -- 2.20.1