From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0F5DC433ED for ; Mon, 5 Apr 2021 14:52:15 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EA08C613B1 for ; Mon, 5 Apr 2021 14:52:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EA08C613B1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38546 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lTQaL-0001SG-Lc for qemu-devel@archiver.kernel.org; Mon, 05 Apr 2021 10:52:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42254) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lTQHF-0001Kh-KZ for qemu-devel@nongnu.org; Mon, 05 Apr 2021 10:32:29 -0400 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]:51948) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lTQH7-0001ig-ET for qemu-devel@nongnu.org; Mon, 05 Apr 2021 10:32:29 -0400 Received: by mail-wm1-x32d.google.com with SMTP id p19so5817579wmq.1 for ; Mon, 05 Apr 2021 07:32:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BY2DlGfthi/5EpjNo0Gz8ouWxFRGsyZJp6AAsyCinj8=; b=u4xleXawVJ8K1Lu+aplES/Lu85MNx1rd9J+34odlp/x4QFLY57gPxpCO2zv8telliJ f0kFpEO7c0unPkYffukvcKWPCFEKctF/sOsLuX5QC2PthllLIsHIdnQOyiOUFnQSxUdp blXr/jFYyIHV1T1Repo9Rsf+mJu2SXE8Rp+3ouwnCnuEvv1IV73G01UhgiIZFfeR5gDr crpBIELt+BhehshZDD1wOqmEkize1zor/AN5d1NxqMbBEk+yOa7EyEdpP3j1Hebrq4fK yNM+WJV7iWbTWc2F/K64xIEg4pxFAXM1Gcs9eP2ouLxmkB0c6tdVkW6hNYtJIlsV37W+ a4FQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BY2DlGfthi/5EpjNo0Gz8ouWxFRGsyZJp6AAsyCinj8=; b=M8N+uZjyJLX1cP/id6Y1H/V7fWpb27fds2DUVjv9Ewu0OqyEqH50d4FjI+SBsg4Gq6 CN9MLb7YBvRrfA482kmoJNijty2WWtoeAvcTYWaFSMTa3T6VsTn+QpMIiyizve5vwgos HxavUMS+JWepmawMJcTuRRdWs9AidfbIxhp9XZ5cbQN8gW/RlWT6DbsmPG4LFi2qpBq0 K7ISoQm6Qv8Pwc9aJmAPz+DIana7nTOp+FS3DmpjWVWknOuS2XJqrZpBKcfN99JDVom2 nr0H9BqCNMiLHTbl471ZwNZHvnJ1NNiUPZHQsU2J5hIg5eRoP7120+7gYPaOFVYIZhE/ d5Ww== X-Gm-Message-State: AOAM531of6Tz1Hr4oJKiAhL17q8XIBgAYGaVav7nfOmpU2Q2uNPVy4F4 Az+4iysPdMYVmJ0vFOGXs9Za/F7KK++6PA== X-Google-Smtp-Source: ABdhPJzI5JJOOYRo3G6nJ3mWnVjpZQD7H8yfXQqvMMyZEmqVmcD0PYDIcd2Osyxf1wommlWSbF+p3w== X-Received: by 2002:a1c:6241:: with SMTP id w62mr25481929wmb.79.1617633140064; Mon, 05 Apr 2021 07:32:20 -0700 (PDT) Received: from cmiranda-laptop.localdomain (bl15-158-218.dsl.telepac.pt. [188.80.158.218]) by smtp.gmail.com with ESMTPSA id k3sm8231552wrc.67.2021.04.05.07.32.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Apr 2021 07:32:19 -0700 (PDT) From: cupertinomiranda@gmail.com To: qemu-devel@nongnu.org Subject: [PATCH 12/27] arc: Add gdbstub and XML for debugging support Date: Mon, 5 Apr 2021 15:31:23 +0100 Message-Id: <20210405143138.17016-13-cupertinomiranda@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210405143138.17016-1-cupertinomiranda@gmail.com> References: <20210405143138.17016-1-cupertinomiranda@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2a00:1450:4864:20::32d; envelope-from=cupertinomiranda@gmail.com; helo=mail-wm1-x32d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: shahab@synopsys.com, linux-snps-arc@lists.infradead.org, claziss@synopsys.com, cmiranda@synopsys.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Shahab Vahedi Register layout for the target and the mechanisms to read and set them. Signed-off-by: Shahab Vahedi --- gdb-xml/arc-v2-aux.xml | 32 +++ gdb-xml/arc-v2-core.xml | 45 +++++ gdb-xml/arc-v2-other.xml | 235 ++++++++++++++++++++++ target/arc/gdbstub.c | 421 +++++++++++++++++++++++++++++++++++++++ target/arc/gdbstub.h | 157 +++++++++++++++ 5 files changed, 890 insertions(+) create mode 100644 gdb-xml/arc-v2-aux.xml create mode 100644 gdb-xml/arc-v2-core.xml create mode 100644 gdb-xml/arc-v2-other.xml create mode 100644 target/arc/gdbstub.c create mode 100644 target/arc/gdbstub.h diff --git a/gdb-xml/arc-v2-aux.xml b/gdb-xml/arc-v2-aux.xml new file mode 100644 index 0000000000..e18168ad05 --- /dev/null +++ b/gdb-xml/arc-v2-aux.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/arc-v2-core.xml b/gdb-xml/arc-v2-core.xml new file mode 100644 index 0000000000..c925a6994c --- /dev/null +++ b/gdb-xml/arc-v2-core.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/arc-v2-other.xml b/gdb-xml/arc-v2-other.xml new file mode 100644 index 0000000000..9824f518cc --- /dev/null +++ b/gdb-xml/arc-v2-other.xml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/target/arc/gdbstub.c b/target/arc/gdbstub.c new file mode 100644 index 0000000000..a09cdb3f45 --- /dev/null +++ b/target/arc/gdbstub.c @@ -0,0 +1,421 @@ +/* + * QEMU ARC CPU + * + * Copyright (c) 2020 Synppsys Inc. + * + * 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 "irq.h" +#include "gdbstub.h" +#include "exec/helper-proto.h" + +/* gets the register address for a particular processor */ +#define REG_ADDR(reg, processor_type) \ + arc_aux_reg_address_for((reg), (processor_type)) + +#define GDB_GET_REG gdb_get_reg32 + +int arc_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) +{ + ARCCPU *cpu = ARC_CPU(cs); + CPUARCState *env = &cpu->env; + target_ulong 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_REG(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; + target_ulong 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) +{ + ARCCPU *cpu = env_archcpu(env); + target_ulong regval = 0; + + switch (regnum) { + case GDB_AUX_MIN_REG_PC: + regval = env->pc & ((target_ulong) 0xfffffffffffffffe); + break; + case GDB_AUX_MIN_REG_LPS: + regval = helper_lr(env, REG_ADDR(AUX_ID_lp_start, cpu->family)); + break; + case GDB_AUX_MIN_REG_LPE: + regval = helper_lr(env, REG_ADDR(AUX_ID_lp_end, cpu->family)); + 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_REG(mem_buf, regval); +} + + +static int +arc_aux_minimal_gdb_set_reg(CPUARCState *env, uint8_t *mem_buf, int regnum) +{ + ARCCPU *cpu = env_archcpu(env); + target_ulong regval = ldl_p(mem_buf); + switch (regnum) { + case GDB_AUX_MIN_REG_PC: + env->pc = regval & ((target_ulong) 0xfffffffffffffffe); + break; + case GDB_AUX_MIN_REG_LPS: + helper_sr(env, regval, REG_ADDR(AUX_ID_lp_start, cpu->family)); + break; + case GDB_AUX_MIN_REG_LPE: + helper_sr(env, regval, REG_ADDR(AUX_ID_lp_end, cpu->family)); + 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) +{ + ARCCPU *cpu = env_archcpu(env); + target_ulong regval = 0; + switch (regnum) { + case GDB_AUX_OTHER_REG_TIMER_BUILD: + regval = helper_lr(env, REG_ADDR(AUX_ID_timer_build, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_BUILD: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_build, cpu->family)); + break; + case GDB_AUX_OTHER_REG_MPY_BUILD: + regval = helper_lr(env, REG_ADDR(AUX_ID_mpy_build, cpu->family)); + break; + case GDB_AUX_OTHER_REG_VECBASE_BUILD: + regval = cpu->vecbase_build; + break; + case GDB_AUX_OTHER_REG_ISA_CONFIG: + regval = cpu->isa_config; + break; + case GDB_AUX_OTHER_REG_TIMER_CNT0: + regval = helper_lr(env, REG_ADDR(AUX_ID_count0, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_CTRL0: + regval = helper_lr(env, REG_ADDR(AUX_ID_control0, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_LIM0: + regval = helper_lr(env, REG_ADDR(AUX_ID_limit0, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_CNT1: + regval = helper_lr(env, REG_ADDR(AUX_ID_count1, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_CTRL1: + regval = helper_lr(env, REG_ADDR(AUX_ID_control1, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_LIM1: + regval = helper_lr(env, REG_ADDR(AUX_ID_limit1, cpu->family)); + break; + case GDB_AUX_OTHER_REG_PID: + regval = helper_lr(env, REG_ADDR(AUX_ID_pid, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TLBPD0: + regval = helper_lr(env, REG_ADDR(AUX_ID_tlbpd0, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TLBPD1: + regval = helper_lr(env, REG_ADDR(AUX_ID_tlbpd1, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TLB_INDEX: + regval = helper_lr(env, REG_ADDR(AUX_ID_tlbindex, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TLB_CMD: + regval = helper_lr(env, REG_ADDR(AUX_ID_tlbcommand, cpu->family)); + break; + /* MPU */ + case GDB_AUX_OTHER_REG_MPU_BUILD: + regval = helper_lr(env, REG_ADDR(AUX_ID_mpu_build, cpu->family)); + break; + case GDB_AUX_OTHER_REG_MPU_EN: + regval = helper_lr(env, REG_ADDR(AUX_ID_mpuen, cpu->family)); + break; + case GDB_AUX_OTHER_REG_MPU_ECR: + regval = helper_lr(env, REG_ADDR(AUX_ID_mpuic, cpu->family)); + 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, cpu->family)); + 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, cpu->family)); + break; + } + /* exceptions */ + case GDB_AUX_OTHER_REG_ERSTATUS: + regval = helper_lr(env, REG_ADDR(AUX_ID_erstatus, cpu->family)); + break; + case GDB_AUX_OTHER_REG_ERBTA: + regval = helper_lr(env, REG_ADDR(AUX_ID_erbta, cpu->family)); + break; + case GDB_AUX_OTHER_REG_ECR: + regval = helper_lr(env, REG_ADDR(AUX_ID_ecr, cpu->family)); + break; + case GDB_AUX_OTHER_REG_ERET: + regval = helper_lr(env, REG_ADDR(AUX_ID_eret, cpu->family)); + break; + case GDB_AUX_OTHER_REG_EFA: + regval = helper_lr(env, REG_ADDR(AUX_ID_efa, cpu->family)); + break; + /* interrupt */ + case GDB_AUX_OTHER_REG_ICAUSE: + regval = helper_lr(env, REG_ADDR(AUX_ID_icause, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_CTRL: + regval = helper_lr(env, REG_ADDR(AUX_ID_aux_irq_ctrl, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_ACT: + regval = helper_lr(env, REG_ADDR(AUX_ID_aux_irq_act, cpu->family)); + 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, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_SELECT: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_select, cpu->family)); + 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, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_STATUS: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_status, cpu->family)); + 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, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_PRIO: + regval = helper_lr(env, REG_ADDR(AUX_ID_irq_priority, cpu->family)); + break; + case GDB_AUX_OTHER_REG_BTA: + regval = helper_lr(env, REG_ADDR(AUX_ID_bta, cpu->family)); + break; + default: + assert(!"Unsupported other auxiliary register is being read."); + } + return GDB_GET_REG(mem_buf, regval); +} + + +static int +arc_aux_other_gdb_set_reg(CPUARCState *env, uint8_t *mem_buf, int regnum) +{ + ARCCPU *cpu = env_archcpu(env); + target_ulong 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, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_CTRL0: + helper_sr(env, regval, REG_ADDR(AUX_ID_control0, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_LIM0: + helper_sr(env, regval, REG_ADDR(AUX_ID_limit0, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_CNT1: + helper_sr(env, regval, REG_ADDR(AUX_ID_count1, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_CTRL1: + helper_sr(env, regval, REG_ADDR(AUX_ID_control1, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TIMER_LIM1: + helper_sr(env, regval, REG_ADDR(AUX_ID_limit1, cpu->family)); + break; + case GDB_AUX_OTHER_REG_PID: + helper_sr(env, regval, REG_ADDR(AUX_ID_pid, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TLBPD0: + helper_sr(env, regval, REG_ADDR(AUX_ID_tlbpd0, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TLBPD1: + helper_sr(env, regval, REG_ADDR(AUX_ID_tlbpd1, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TLB_INDEX: + helper_sr(env, regval, REG_ADDR(AUX_ID_tlbindex, cpu->family)); + break; + case GDB_AUX_OTHER_REG_TLB_CMD: + helper_sr(env, regval, REG_ADDR(AUX_ID_tlbcommand, cpu->family)); + break; + /* MPU */ + case GDB_AUX_OTHER_REG_MPU_EN: + helper_sr(env, regval, REG_ADDR(AUX_ID_mpuen, cpu->family)); + 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, cpu->family)); + 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, cpu->family)); + break; + } + /* exceptions */ + case GDB_AUX_OTHER_REG_ERSTATUS: + helper_sr(env, regval, REG_ADDR(AUX_ID_erstatus, cpu->family)); + break; + case GDB_AUX_OTHER_REG_ERBTA: + helper_sr(env, regval, REG_ADDR(AUX_ID_erbta, cpu->family)); + break; + case GDB_AUX_OTHER_REG_ECR: + helper_sr(env, regval, REG_ADDR(AUX_ID_ecr, cpu->family)); + break; + case GDB_AUX_OTHER_REG_ERET: + helper_sr(env, regval, REG_ADDR(AUX_ID_eret, cpu->family)); + break; + case GDB_AUX_OTHER_REG_EFA: + helper_sr(env, regval, REG_ADDR(AUX_ID_efa, cpu->family)); + break; + /* interrupt */ + case GDB_AUX_OTHER_REG_IRQ_CTRL: + helper_sr(env, regval, REG_ADDR(AUX_ID_aux_irq_ctrl, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_ACT: + helper_sr(env, regval, REG_ADDR(AUX_ID_aux_irq_act, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_HINT: + helper_sr(env, regval, REG_ADDR(AUX_ID_aux_irq_hint, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_SELECT: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_select, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_ENABLE: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_enable, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_TRIGGER: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_trigger, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_PULSE: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_pulse_cancel, cpu->family)); + break; + case GDB_AUX_OTHER_REG_IRQ_PRIO: + helper_sr(env, regval, REG_ADDR(AUX_ID_irq_priority, cpu->family)); + break; + case GDB_AUX_OTHER_REG_BTA: + helper_sr(env, regval, REG_ADDR(AUX_ID_bta, cpu->family)); + break; + default: + assert(!"Unsupported other auxiliary register is being written."); + } + return 4; +} + +#define GDB_TARGET_MINIMAL_XML "arc-v2-aux.xml" +#define GDB_TARGET_AUX_XML "arc-v2-other.xml" + +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 */ + GDB_TARGET_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, + GDB_TARGET_AUX_XML, + 0); +} + +/*-*-indent-tabs-mode:nil;tab-width:4;indent-line-function:'insert-tab'-*-*/ +/* vim: set ts=4 sw=4 et: */ diff --git a/target/arc/gdbstub.h b/target/arc/gdbstub.h new file mode 100644 index 0000000000..2ced52ee57 --- /dev/null +++ b/target/arc/gdbstub.h @@ -0,0 +1,157 @@ +/* + * QEMU ARC CPU + * + * Copyright (c) 2020 Synopsys Inc. + * Contributed by Cupertino Miranda + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 ARC_GDBSTUB_H +#define ARC_GDBSTUB_H + +#define GDB_TARGET_STRING "arc:ARCv2" + +enum gdb_regs { + GDB_REG_0 = 0, + GDB_REG_1, + GDB_REG_2, + GDB_REG_3, + GDB_REG_4, + GDB_REG_5, + GDB_REG_6, + GDB_REG_7, + GDB_REG_8, + GDB_REG_9, + GDB_REG_10, + GDB_REG_11, + GDB_REG_12, + GDB_REG_13, + GDB_REG_14, + GDB_REG_15, + GDB_REG_16, + GDB_REG_17, + GDB_REG_18, + GDB_REG_19, + GDB_REG_20, + GDB_REG_21, + GDB_REG_22, + GDB_REG_23, + GDB_REG_24, + GDB_REG_25, + GDB_REG_26, /* GP */ + GDB_REG_27, /* FP */ + GDB_REG_28, /* SP */ + GDB_REG_29, /* ILINK */ + GDB_REG_30, /* R30 */ + GDB_REG_31, /* BLINK */ + GDB_REG_58, /* little_endian? ACCL : ACCH */ + GDB_REG_59, /* little_endian? ACCH : ACCL */ + GDB_REG_60, /* LP */ + GDB_REG_63, /* Immediate */ + GDB_REG_LAST +}; + +enum gdb_aux_min_regs { + GDB_AUX_MIN_REG_PC = 0, /* program counter */ + GDB_AUX_MIN_REG_LPS, /* loop body start */ + GDB_AUX_MIN_REG_LPE, /* loop body end */ + GDB_AUX_MIN_REG_STATUS, /* status flag */ + GDB_AUX_MIN_REG_LAST +}; + +enum gdb_aux_other_regs { + /* builds */ + GDB_AUX_OTHER_REG_TIMER_BUILD = 0, /* timer build */ + GDB_AUX_OTHER_REG_IRQ_BUILD, /* irq build */ + GDB_AUX_OTHER_REG_MPY_BUILD, /* multiply configuration */ + GDB_AUX_OTHER_REG_VECBASE_BUILD, /* vector base address config */ + GDB_AUX_OTHER_REG_ISA_CONFIG, /* isa config */ + /* timers */ + GDB_AUX_OTHER_REG_TIMER_CNT0, /* timer 0 counter */ + GDB_AUX_OTHER_REG_TIMER_CTRL0, /* timer 0 control */ + GDB_AUX_OTHER_REG_TIMER_LIM0, /* timer 0 limit */ + GDB_AUX_OTHER_REG_TIMER_CNT1, /* timer 1 counter */ + GDB_AUX_OTHER_REG_TIMER_CTRL1, /* timer 1 control */ + GDB_AUX_OTHER_REG_TIMER_LIM1, /* timer 1 limit */ + /* mpu */ + GDB_AUX_OTHER_REG_MPU_BUILD, /* MPU build */ + GDB_AUX_OTHER_REG_MPU_EN, /* MPU enable */ + GDB_AUX_OTHER_REG_MPU_ECR, /* MPU exception cause */ + GDB_AUX_OTHER_REG_MPU_BASE0, /* MPU base 0 */ + GDB_AUX_OTHER_REG_MPU_BASE1, /* MPU base 1 */ + GDB_AUX_OTHER_REG_MPU_BASE2, /* MPU base 2 */ + GDB_AUX_OTHER_REG_MPU_BASE3, /* MPU base 3 */ + GDB_AUX_OTHER_REG_MPU_BASE4, /* MPU base 4 */ + GDB_AUX_OTHER_REG_MPU_BASE5, /* MPU base 5 */ + GDB_AUX_OTHER_REG_MPU_BASE6, /* MPU base 6 */ + GDB_AUX_OTHER_REG_MPU_BASE7, /* MPU base 7 */ + GDB_AUX_OTHER_REG_MPU_BASE8, /* MPU base 8 */ + GDB_AUX_OTHER_REG_MPU_BASE9, /* MPU base 9 */ + GDB_AUX_OTHER_REG_MPU_BASE10, /* MPU base 10 */ + GDB_AUX_OTHER_REG_MPU_BASE11, /* MPU base 11 */ + GDB_AUX_OTHER_REG_MPU_BASE12, /* MPU base 12 */ + GDB_AUX_OTHER_REG_MPU_BASE13, /* MPU base 13 */ + GDB_AUX_OTHER_REG_MPU_BASE14, /* MPU base 14 */ + GDB_AUX_OTHER_REG_MPU_BASE15, /* MPU base 15 */ + GDB_AUX_OTHER_REG_MPU_PERM0, /* MPU permission 0 */ + GDB_AUX_OTHER_REG_MPU_PERM1, /* MPU permission 1 */ + GDB_AUX_OTHER_REG_MPU_PERM2, /* MPU permission 2 */ + GDB_AUX_OTHER_REG_MPU_PERM3, /* MPU permission 3 */ + GDB_AUX_OTHER_REG_MPU_PERM4, /* MPU permission 4 */ + GDB_AUX_OTHER_REG_MPU_PERM5, /* MPU permission 5 */ + GDB_AUX_OTHER_REG_MPU_PERM6, /* MPU permission 6 */ + GDB_AUX_OTHER_REG_MPU_PERM7, /* MPU permission 7 */ + GDB_AUX_OTHER_REG_MPU_PERM8, /* MPU permission 8 */ + GDB_AUX_OTHER_REG_MPU_PERM9, /* MPU permission 9 */ + GDB_AUX_OTHER_REG_MPU_PERM10, /* MPU permission 10 */ + GDB_AUX_OTHER_REG_MPU_PERM11, /* MPU permission 11 */ + GDB_AUX_OTHER_REG_MPU_PERM12, /* MPU permission 12 */ + GDB_AUX_OTHER_REG_MPU_PERM13, /* MPU permission 13 */ + GDB_AUX_OTHER_REG_MPU_PERM14, /* MPU permission 14 */ + GDB_AUX_OTHER_REG_MPU_PERM15, /* MPU permission 15 */ + /* excpetions */ + GDB_AUX_OTHER_REG_ERSTATUS, /* exception return status */ + GDB_AUX_OTHER_REG_ERBTA, /* exception return BTA */ + GDB_AUX_OTHER_REG_ECR, /* exception cause register */ + GDB_AUX_OTHER_REG_ERET, /* exception return address */ + GDB_AUX_OTHER_REG_EFA, /* exception fault address */ + /* irq */ + GDB_AUX_OTHER_REG_ICAUSE, /* interrupt cause */ + GDB_AUX_OTHER_REG_IRQ_CTRL, /* context saving control */ + GDB_AUX_OTHER_REG_IRQ_ACT, /* active */ + GDB_AUX_OTHER_REG_IRQ_PRIO_PEND, /* priority pending */ + GDB_AUX_OTHER_REG_IRQ_HINT, /* hint */ + GDB_AUX_OTHER_REG_IRQ_SELECT, /* select */ + GDB_AUX_OTHER_REG_IRQ_ENABLE, /* enable */ + GDB_AUX_OTHER_REG_IRQ_TRIGGER, /* trigger */ + GDB_AUX_OTHER_REG_IRQ_STATUS, /* status */ + GDB_AUX_OTHER_REG_IRQ_PULSE, /* pulse cancel */ + GDB_AUX_OTHER_REG_IRQ_PENDING, /* pending */ + GDB_AUX_OTHER_REG_IRQ_PRIO, /* priority */ + /* miscellaneous */ + GDB_AUX_OTHER_REG_BTA, /* branch target address */ + /* mmu */ + GDB_AUX_OTHER_REG_PID, /* process identity */ + GDB_AUX_OTHER_REG_TLBPD0, /* page descriptor 0 */ + GDB_AUX_OTHER_REG_TLBPD1, /* page descriptor 1 */ + GDB_AUX_OTHER_REG_TLB_INDEX, /* tlb index */ + GDB_AUX_OTHER_REG_TLB_CMD, /* tlb command */ + + GDB_AUX_OTHER_REG_LAST +}; + +/* add auxiliary registers to set of supported registers for GDB */ +void arc_cpu_register_gdb_regs_for_features(ARCCPU *cpu); + +#endif /* ARC_GDBSTUB_H */ -- 2.20.1