From patchwork Mon Jan 17 13:28:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715499 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 27E94C433FE for ; Mon, 17 Jan 2022 14:52:39 +0000 (UTC) Received: from localhost ([::1]:54276 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9TN7-0003KP-Sn for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:52:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38720) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5O-0001MK-C6 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:24 -0500 Received: from [2607:f8b0:4864:20::635] (port=39446 helo=mail-pl1-x635.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000e1-Qy for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:12 -0500 Received: by mail-pl1-x635.google.com with SMTP id c6so12785632plh.6 for ; Mon, 17 Jan 2022 05:29:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=VNASKJ00wlA5t2Q/k7jW+YzfMzGznROhiBSULHbWdaE=; b=SCzwUkuknW+XEzkQ1zQDs0aITub43r8AvcPW50VFojaBGQE4hq7TXxyZaMItwNRTK0 adwDMcSJeSA4vxtVtNAbmLmezGimiKv3Bf4meER7a7Wsjj3l2ma2YVYwlcnYyBh9ofXl Uh30JqPaNWgizRKApUV24uJyEY0LGokRcQ1lxV1IAC1CPPXXtYC5AVrd6gy+yUnLnCqK teV4vschNMbIKZmzqTruEBadsdWJXpKAIL9Ocfdo5EmAqqvvxnbxNXht/r5/8fJJWe4t xm879iDekoSl3YY3f7K5yVMFYYRO/SdURQTDLeMfOwq8vD99aaSOYRUBQ/EjAN+ufrdu QFKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VNASKJ00wlA5t2Q/k7jW+YzfMzGznROhiBSULHbWdaE=; b=Wo2090R0JCX/l7zgP/6OuQgnISbRp+gcsAp2WNzGfFf1IwIX2yqjxHhBiss1ve0RGP KO4OtPlokrA+34FuVfVfxl9eIy3BRgBlF515XhLFQ3Pvh1KxtABr70nImwU0KwMJDVsf 1xRuwd8va66GelYoOGi6KNrWGhrgmnAGShnhBbzHrzqgZKXi/TNzjyAH1h6IORefLcao tfOPe+mdr+vmblAZK/neKT4qXeVLkqYjFF0GQMNIwpt2rBP2RRjrUMPKcc96voCUg0Ef e2h9yQngIN1ytxugL4AFY01BLxWgRdYLyajOgNSO/VKG98lYXziQT1rQcx83OahXbtSU DbMQ== X-Gm-Message-State: AOAM533c47KLetm95uBowftkhG/catx+lHfiPSNllSHf/jRy6I5yrtRC f+o6ds4pPtPtpE+aWuvZctXOVA== X-Google-Smtp-Source: ABdhPJz3pb82h61aj+IHXfBOJ4F39AELr/F25NjLCDG0q3990rBngRRMHQt6oGY4/TS4BF+DBOt44Q== X-Received: by 2002:a17:90b:4f84:: with SMTP id qe4mr24829671pjb.211.1642426157792; Mon, 17 Jan 2022 05:29:17 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:16 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 01/23] target/riscv: Fix trap cause for RV32 HS-mode CSR access from RV64 HS-mode Date: Mon, 17 Jan 2022 18:58:04 +0530 Message-Id: <20220117132826.426418-2-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::635 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::635; envelope-from=anup@brainfault.org; helo=mail-pl1-x635.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel We should be returning illegal instruction trap when RV64 HS-mode tries to access RV32 HS-mode CSR. Fixes: d6f20dacea51 ("target/riscv: Fix 32-bit HS mode access permissions") Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Bin Meng Reviewed-by: Frank Chang --- target/riscv/csr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index adb3d4381d..bee42b6073 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -182,7 +182,7 @@ static RISCVException hmode(CPURISCVState *env, int csrno) static RISCVException hmode32(CPURISCVState *env, int csrno) { if (riscv_cpu_mxl(env) != MXL_RV32) { - if (riscv_cpu_virt_enabled(env)) { + if (!riscv_cpu_virt_enabled(env)) { return RISCV_EXCP_ILLEGAL_INST; } else { return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; From patchwork Mon Jan 17 13:28:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715468 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 5C006C433EF for ; Mon, 17 Jan 2022 14:29:31 +0000 (UTC) Received: from localhost ([::1]:37348 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9T0k-000615-Fg for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:29:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38456) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5A-0001DT-J4 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:00 -0500 Received: from [2607:f8b0:4864:20::633] (port=45885 helo=mail-pl1-x633.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000eC-Mp for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:00 -0500 Received: by mail-pl1-x633.google.com with SMTP id g5so21183029plo.12 for ; Mon, 17 Jan 2022 05:29:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=60MzG/lacR7Hb+AFEQUePvP7QZfHssk6zKG7j6J5Jqk=; b=5H+KPnvphVughuzgvyA/fgrv09nreLkemGRc7hnz4RlJQLCQyhnAU9J1YU8Eg92KLd bxbIvBnIGylEbtgiEStBPFRkgk/kOrY8lFcDmkL2JXOZJ1hnd8Rfzk7HeqS/07p9qTzl vPkEn57OBuyRZfzEpIq6lhoMNToOKTCTzzrt6RFkG+AT3tAhtJoG5HF9OpAe5P4NizWZ pU6x0CxwKTz8W/E3kKUj1ENipnfN2VT93rMJuEWdPKunu5YNS8RZT46TQqZR4aUwJPh2 w6MBHvlRLOxL6BlSOVhhFHEnMxfcJfWLUy0TkN8azKa6Q1QGz9E8WOVZ//robZp4VuDm NxFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=60MzG/lacR7Hb+AFEQUePvP7QZfHssk6zKG7j6J5Jqk=; b=fGk7X5K4j/JdsyNuSheYZ5Hs4J7gj1Euw7EuHYTsM3Q7ZBjDxvw25bks18+PTMOkJS ly/IooERnCnSxT41pv+dXIDGncajCzo08myhuo508o8xzxof4B07VtErwEOF4SvEeiWi eidmgn4OWUCiXtu8WLszUuDxbzqGtTeWcMtD/HKpplDRO6P1BFi8eilK+BTQ5coD5Bbe 5WEUvd9IAw9zmsAvyUcmeDqJeg3tbVr4sjUO0xQpMDZZb3OQIq6e0W6nKxoc5XCFeoCy B0XpWxVxWzL/v2xNV9O7cFnlS2x7m9Flk9of/y2f1KnP/Uj/jWYc6AWpFJSOoAQd7+TE EhEw== X-Gm-Message-State: AOAM531rzhXGZXgBkdwKcnmGr5TF5lU+g875D0djys9gu5Xh0Nyr0zzB jSmHUoFIyMXZs0uwdewcRNXerw== X-Google-Smtp-Source: ABdhPJxqsUl4zr2GuzwDrtmsJi/11++T/PY43btqjHYHaGMGorFNhSnD16zV/ma9G182mtvnNMrzBw== X-Received: by 2002:a17:902:9894:b0:149:8a72:98ae with SMTP id s20-20020a170902989400b001498a7298aemr22818085plp.132.1642426162372; Mon, 17 Jan 2022 05:29:22 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:21 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 02/23] target/riscv: Implement SGEIP bit in hip and hie CSRs Date: Mon, 17 Jan 2022 18:58:05 +0530 Message-Id: <20220117132826.426418-3-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::633 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::633; envelope-from=anup@brainfault.org; helo=mail-pl1-x633.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel A hypervisor can optionally take guest external interrupts using SGEIP bit of hip and hie CSRs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu.c | 3 ++- target/riscv/cpu_bits.h | 3 +++ target/riscv/csr.c | 18 +++++++++++------- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 9bc25d3055..b26832219f 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -394,6 +394,7 @@ static void riscv_cpu_reset(DeviceState *dev) env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl); } env->mcause = 0; + env->miclaim = MIP_SGEIP; env->pc = env->resetvec; env->two_stage_lookup = false; /* mmte is supposed to have pm.current hardwired to 1 */ @@ -637,7 +638,7 @@ static void riscv_cpu_init(Object *obj) cpu_set_cpustate_pointers(cpu); #ifndef CONFIG_USER_ONLY - qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, 12); + qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, IRQ_LOCAL_MAX); #endif /* CONFIG_USER_ONLY */ } diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 5a6d49aa64..ee6d95ea91 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -537,6 +537,8 @@ typedef enum RISCVException { #define IRQ_S_EXT 9 #define IRQ_VS_EXT 10 #define IRQ_M_EXT 11 +#define IRQ_S_GEXT 12 +#define IRQ_LOCAL_MAX 16 /* mip masks */ #define MIP_USIP (1 << IRQ_U_SOFT) @@ -551,6 +553,7 @@ typedef enum RISCVException { #define MIP_SEIP (1 << IRQ_S_EXT) #define MIP_VSEIP (1 << IRQ_VS_EXT) #define MIP_MEIP (1 << IRQ_M_EXT) +#define MIP_SGEIP (1 << IRQ_S_GEXT) /* sip masks */ #define SIP_SSIP MIP_SSIP diff --git a/target/riscv/csr.c b/target/riscv/csr.c index bee42b6073..80b9b7e732 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -446,12 +446,13 @@ static RISCVException read_timeh(CPURISCVState *env, int csrno, #define M_MODE_INTERRUPTS (MIP_MSIP | MIP_MTIP | MIP_MEIP) #define S_MODE_INTERRUPTS (MIP_SSIP | MIP_STIP | MIP_SEIP) #define VS_MODE_INTERRUPTS (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP) +#define HS_MODE_INTERRUPTS (MIP_SGEIP | VS_MODE_INTERRUPTS) static const target_ulong delegable_ints = S_MODE_INTERRUPTS | VS_MODE_INTERRUPTS; static const target_ulong vs_delegable_ints = VS_MODE_INTERRUPTS; static const target_ulong all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS | - VS_MODE_INTERRUPTS; + HS_MODE_INTERRUPTS; #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \ (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \ (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \ @@ -729,7 +730,7 @@ static RISCVException write_mideleg(CPURISCVState *env, int csrno, { env->mideleg = (env->mideleg & ~delegable_ints) | (val & delegable_ints); if (riscv_has_ext(env, RVH)) { - env->mideleg |= VS_MODE_INTERRUPTS; + env->mideleg |= HS_MODE_INTERRUPTS; } return RISCV_EXCP_NONE; } @@ -745,6 +746,9 @@ static RISCVException write_mie(CPURISCVState *env, int csrno, target_ulong val) { env->mie = (env->mie & ~all_ints) | (val & all_ints); + if (!riscv_has_ext(env, RVH)) { + env->mie &= ~MIP_SGEIP; + } return RISCV_EXCP_NONE; } @@ -1080,7 +1084,7 @@ static RISCVException rmw_sip(CPURISCVState *env, int csrno, } if (ret_value) { - *ret_value &= env->mideleg; + *ret_value &= env->mideleg & S_MODE_INTERRUPTS; } return ret; } @@ -1198,7 +1202,7 @@ static RISCVException rmw_hvip(CPURISCVState *env, int csrno, write_mask & hvip_writable_mask); if (ret_value) { - *ret_value &= hvip_writable_mask; + *ret_value &= VS_MODE_INTERRUPTS; } return ret; } @@ -1211,7 +1215,7 @@ static RISCVException rmw_hip(CPURISCVState *env, int csrno, write_mask & hip_writable_mask); if (ret_value) { - *ret_value &= hip_writable_mask; + *ret_value &= HS_MODE_INTERRUPTS; } return ret; } @@ -1219,14 +1223,14 @@ static RISCVException rmw_hip(CPURISCVState *env, int csrno, static RISCVException read_hie(CPURISCVState *env, int csrno, target_ulong *val) { - *val = env->mie & VS_MODE_INTERRUPTS; + *val = env->mie & HS_MODE_INTERRUPTS; return RISCV_EXCP_NONE; } static RISCVException write_hie(CPURISCVState *env, int csrno, target_ulong val) { - target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) | (val & VS_MODE_INTERRUPTS); + target_ulong newval = (env->mie & ~HS_MODE_INTERRUPTS) | (val & HS_MODE_INTERRUPTS); return write_mie(env, CSR_MIE, newval); } From patchwork Mon Jan 17 13:28:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715456 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 84EF5C433EF for ; Mon, 17 Jan 2022 14:27:07 +0000 (UTC) Received: from localhost ([::1]:59144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9SyQ-0001o4-Gm for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:27:06 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38706) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5O-0001ME-7O for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:20 -0500 Received: from [2607:f8b0:4864:20::535] (port=36741 helo=mail-pg1-x535.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000eS-Pu for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:08 -0500 Received: by mail-pg1-x535.google.com with SMTP id e9so373826pgb.3 for ; Mon, 17 Jan 2022 05:29:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hdLIZjHkasy8bAZj2oWrfMzM3GTx/0zg7OZJH3TSOwM=; b=YsNSi/+KBn5it4uoJR4p0mf0HvrGPzXng3YFkxDr3bcAiG3ZuEkcFSav4UEA8XITZR HPftysWUrG1F8i+rv8klOf+nJjQOdnK7P6LjAYqSs7WvMRrcOC3HmCSFwAlnpqCQtUaH b9kmgFOgjwaUX6bHDsZSmqsOyP2HseACry6OewMjWq/ohbNz9BbeuUAMnMdYmwYw7UrT lZdSk6M/g0SHJUUT5RK/yhZn4kqUAKjdANWdjVL/ReoORmUxgWLeAua3Q2Cat5p/kz4N 0wd8gRJoozcRoYOEhxtComiX0YGn/y+ZoCcbwh2pErzFGsxLTLVvR6iStixYBqqRp0gJ lqMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hdLIZjHkasy8bAZj2oWrfMzM3GTx/0zg7OZJH3TSOwM=; b=poTL/80U9kLB+px0zmEDN8fSP+mN8NFxKCV5CC7tGzocJftf8UMuua2z6A2f4Fz3ni sjOfJu8XO+LJQ7fyBzNCUNaf+PlBx26yZimic4sqf7XZdcbSMdQvn/WfB1Tw05cn2NGL 3GxjttK245w4jWS+LPlh82VEShf6LKYqebCM2IUx2DNrY9qAUVTL/ndp3vZtuMd12tbw GG9gAHgzss7SKjbwuHCgQvospoZ8nh8Y5irZRUrf3eKYksLEi6rADhaiue8wUWxwMdgv fo/DwU+CftvsqOQ7r9/WNXwe+KsKoHbEOc8K0YI6UBktGJXFFnoFosi/G37GBDsZwPeg wL/w== X-Gm-Message-State: AOAM531kfOANaxbK643AiqdJQ6UzUPcde+RvgFV/4yRAeL8a/keOxOp4 9AmXHTA/dYKlXiWuUk5ofz9qmw== X-Google-Smtp-Source: ABdhPJy5IY31mBp0mLYpo0hyypQAanda5hyVcKDE+MT1eIZCI5FC096NEtYGwIhg1nEAb57I6IdfjQ== X-Received: by 2002:a62:33c7:0:b0:4bd:5aa4:1220 with SMTP id z190-20020a6233c7000000b004bd5aa41220mr21014911pfz.55.1642426166722; Mon, 17 Jan 2022 05:29:26 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:25 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 03/23] target/riscv: Implement hgeie and hgeip CSRs Date: Mon, 17 Jan 2022 18:58:06 +0530 Message-Id: <20220117132826.426418-4-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::535 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::535; envelope-from=anup@brainfault.org; helo=mail-pg1-x535.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The hgeie and hgeip CSRs are required for emulating an external interrupt controller capable of injecting virtual external interrupt to Guest/VM running at VS-level. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu.c | 61 ++++++++++++++++++++++++++++----------- target/riscv/cpu.h | 5 ++++ target/riscv/cpu_bits.h | 1 + target/riscv/cpu_helper.c | 37 ++++++++++++++++++++++-- target/riscv/csr.c | 43 ++++++++++++++++++--------- target/riscv/machine.c | 6 ++-- 6 files changed, 118 insertions(+), 35 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index b26832219f..6afb38f9b7 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -609,23 +609,49 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) static void riscv_cpu_set_irq(void *opaque, int irq, int level) { RISCVCPU *cpu = RISCV_CPU(opaque); + CPURISCVState *env = &cpu->env; - switch (irq) { - case IRQ_U_SOFT: - case IRQ_S_SOFT: - case IRQ_VS_SOFT: - case IRQ_M_SOFT: - case IRQ_U_TIMER: - case IRQ_S_TIMER: - case IRQ_VS_TIMER: - case IRQ_M_TIMER: - case IRQ_U_EXT: - case IRQ_S_EXT: - case IRQ_VS_EXT: - case IRQ_M_EXT: - riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level)); - break; - default: + if (irq < IRQ_LOCAL_MAX) { + switch (irq) { + case IRQ_U_SOFT: + case IRQ_S_SOFT: + case IRQ_VS_SOFT: + case IRQ_M_SOFT: + case IRQ_U_TIMER: + case IRQ_S_TIMER: + case IRQ_VS_TIMER: + case IRQ_M_TIMER: + case IRQ_U_EXT: + case IRQ_S_EXT: + case IRQ_VS_EXT: + case IRQ_M_EXT: + riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level)); + break; + default: + g_assert_not_reached(); + } + } else if (irq < (IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX)) { + /* Require H-extension for handling guest local interrupts */ + if (!riscv_has_ext(env, RVH)) { + g_assert_not_reached(); + } + + /* Compute bit position in HGEIP CSR */ + irq = irq - IRQ_LOCAL_MAX + 1; + if (env->geilen < irq) { + g_assert_not_reached(); + } + + /* Update HGEIP CSR */ + env->hgeip &= ~((target_ulong)1 << irq); + if (level) { + env->hgeip |= (target_ulong)1 << irq; + } + + /* Update mip.SGEIP bit */ + riscv_cpu_update_mip(cpu, MIP_SGEIP, + BOOL_TO_MASK(!!(env->hgeie & env->hgeip))); + } else { g_assert_not_reached(); } } @@ -638,7 +664,8 @@ static void riscv_cpu_init(Object *obj) cpu_set_cpustate_pointers(cpu); #ifndef CONFIG_USER_ONLY - qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, IRQ_LOCAL_MAX); + qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, + IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); #endif /* CONFIG_USER_ONLY */ } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 4d63086765..df4e7d490e 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -159,6 +159,7 @@ struct CPURISCVState { target_ulong priv; /* This contains QEMU specific information about the virt state. */ target_ulong virt; + target_ulong geilen; target_ulong resetvec; target_ulong mhartid; @@ -196,6 +197,8 @@ struct CPURISCVState { target_ulong htval; target_ulong htinst; target_ulong hgatp; + target_ulong hgeie; + target_ulong hgeip; uint64_t htimedelta; /* Upper 64-bits of 128-bit CSRs */ @@ -368,6 +371,8 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); bool riscv_cpu_fp_enabled(CPURISCVState *env); +target_ulong riscv_cpu_get_geilen(CPURISCVState *env); +void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen); bool riscv_cpu_vector_enabled(CPURISCVState *env); bool riscv_cpu_virt_enabled(CPURISCVState *env); void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable); diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index ee6d95ea91..fc9332c545 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -539,6 +539,7 @@ typedef enum RISCVException { #define IRQ_M_EXT 11 #define IRQ_S_GEXT 12 #define IRQ_LOCAL_MAX 16 +#define IRQ_LOCAL_GUEST_MAX (TARGET_LONG_BITS - 1) /* mip masks */ #define MIP_USIP (1 << IRQ_U_SOFT) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 434a83e66a..aabf0a02f9 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -158,7 +158,11 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env) target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE); target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE); - target_ulong pending = env->mip & env->mie; + target_ulong vsgemask = + (target_ulong)1 << get_field(env->hstatus, HSTATUS_VGEIN); + target_ulong vsgein = (env->hgeip & vsgemask) ? MIP_VSEIP : 0; + + target_ulong pending = (env->mip | vsgein) & env->mie; target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && mstatus_mie); @@ -278,6 +282,28 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env) } } +target_ulong riscv_cpu_get_geilen(CPURISCVState *env) +{ + if (!riscv_has_ext(env, RVH)) { + return 0; + } + + return env->geilen; +} + +void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen) +{ + if (!riscv_has_ext(env, RVH)) { + return; + } + + if (geilen > (TARGET_LONG_BITS - 1)) { + return; + } + + env->geilen = geilen; +} + bool riscv_cpu_virt_enabled(CPURISCVState *env) { if (!riscv_has_ext(env, RVH)) { @@ -321,9 +347,14 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value) { CPURISCVState *env = &cpu->env; CPUState *cs = CPU(cpu); - uint32_t old = env->mip; + uint32_t gein, vsgein = 0, old = env->mip; bool locked = false; + if (riscv_cpu_virt_enabled(env)) { + gein = get_field(env->hstatus, HSTATUS_VGEIN); + vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; + } + if (!qemu_mutex_iothread_locked()) { locked = true; qemu_mutex_lock_iothread(); @@ -331,7 +362,7 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value) env->mip = (env->mip & ~mask) | (value & mask); - if (env->mip) { + if (env->mip | vsgein) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 80b9b7e732..6d6f56af3c 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -864,7 +864,7 @@ static RISCVException rmw_mip(CPURISCVState *env, int csrno, RISCVCPU *cpu = env_archcpu(env); /* Allow software control of delegable interrupts not claimed by hardware */ target_ulong mask = write_mask & delegable_ints & ~env->miclaim; - uint32_t old_mip; + uint32_t gin, old_mip; if (mask) { old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask)); @@ -872,6 +872,11 @@ static RISCVException rmw_mip(CPURISCVState *env, int csrno, old_mip = env->mip; } + if (csrno != CSR_HVIP) { + gin = get_field(env->hstatus, HSTATUS_VGEIN); + old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0; + } + if (ret_value) { *ret_value = old_mip; } @@ -1059,7 +1064,7 @@ static RISCVException rmw_vsip(CPURISCVState *env, int csrno, target_ulong new_value, target_ulong write_mask) { /* Shift the S bits to their VS bit location in mip */ - int ret = rmw_mip(env, 0, ret_value, new_value << 1, + int ret = rmw_mip(env, csrno, ret_value, new_value << 1, (write_mask << 1) & vsip_writable_mask & env->hideleg); if (ret_value) { @@ -1079,7 +1084,7 @@ static RISCVException rmw_sip(CPURISCVState *env, int csrno, if (riscv_cpu_virt_enabled(env)) { ret = rmw_vsip(env, CSR_VSIP, ret_value, new_value, write_mask); } else { - ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value, + ret = rmw_mip(env, csrno, ret_value, new_value, write_mask & env->mideleg & sip_writable_mask); } @@ -1198,7 +1203,7 @@ static RISCVException rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask) { - int ret = rmw_mip(env, 0, ret_value, new_value, + int ret = rmw_mip(env, csrno, ret_value, new_value, write_mask & hvip_writable_mask); if (ret_value) { @@ -1211,7 +1216,7 @@ static RISCVException rmw_hip(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask) { - int ret = rmw_mip(env, 0, ret_value, new_value, + int ret = rmw_mip(env, csrno, ret_value, new_value, write_mask & hip_writable_mask); if (ret_value) { @@ -1248,15 +1253,27 @@ static RISCVException write_hcounteren(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -static RISCVException write_hgeie(CPURISCVState *env, int csrno, - target_ulong val) +static RISCVException read_hgeie(CPURISCVState *env, int csrno, + target_ulong *val) { if (val) { - qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN."); + *val = env->hgeie; } return RISCV_EXCP_NONE; } +static RISCVException write_hgeie(CPURISCVState *env, int csrno, + target_ulong val) +{ + /* Only GEILEN:1 bits implemented and BIT0 is never implemented */ + val &= ((((target_ulong)1) << env->geilen) - 1) << 1; + env->hgeie = val; + /* Update mip.SGEIP bit */ + riscv_cpu_update_mip(env_archcpu(env), MIP_SGEIP, + BOOL_TO_MASK(!!(env->hgeie & env->hgeip))); + return RISCV_EXCP_NONE; +} + static RISCVException read_htval(CPURISCVState *env, int csrno, target_ulong *val) { @@ -1284,11 +1301,11 @@ static RISCVException write_htinst(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -static RISCVException write_hgeip(CPURISCVState *env, int csrno, - target_ulong val) +static RISCVException read_hgeip(CPURISCVState *env, int csrno, + target_ulong *val) { if (val) { - qemu_log_mask(LOG_UNIMP, "No support for a non-zero GEILEN."); + *val = env->hgeip; } return RISCV_EXCP_NONE; } @@ -2074,10 +2091,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip }, [CSR_HIE] = { "hie", hmode, read_hie, write_hie }, [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren }, - [CSR_HGEIE] = { "hgeie", hmode, read_zero, write_hgeie }, + [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie }, [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval }, [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst }, - [CSR_HGEIP] = { "hgeip", hmode, read_zero, write_hgeip }, + [CSR_HGEIP] = { "hgeip", hmode, read_hgeip, NULL }, [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp }, [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta }, [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah }, diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 13b9ab375b..c11eb4639c 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -78,8 +78,8 @@ static bool hyper_needed(void *opaque) static const VMStateDescription vmstate_hyper = { .name = "cpu/hyper", - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .needed = hyper_needed, .fields = (VMStateField[]) { VMSTATE_UINTTL(env.hstatus, RISCVCPU), @@ -89,6 +89,8 @@ static const VMStateDescription vmstate_hyper = { VMSTATE_UINTTL(env.htval, RISCVCPU), VMSTATE_UINTTL(env.htinst, RISCVCPU), VMSTATE_UINTTL(env.hgatp, RISCVCPU), + VMSTATE_UINTTL(env.hgeie, RISCVCPU), + VMSTATE_UINTTL(env.hgeip, RISCVCPU), VMSTATE_UINT64(env.htimedelta, RISCVCPU), VMSTATE_UINT64(env.vsstatus, RISCVCPU), From patchwork Mon Jan 17 13:28:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715469 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 9E3A7C43217 for ; Mon, 17 Jan 2022 14:31:12 +0000 (UTC) Received: from localhost ([::1]:41740 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9T2N-0000bN-Ao for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:31:11 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38734) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5O-0001MR-DV for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:24 -0500 Received: from [2607:f8b0:4864:20::631] (port=37389 helo=mail-pl1-x631.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000ej-S1 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:09 -0500 Received: by mail-pl1-x631.google.com with SMTP id n11so19278929plf.4 for ; Mon, 17 Jan 2022 05:29:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Sq5hcxwZ8ePp8DTrOnpUye1knsdChYLvWAxxRBcI1VQ=; b=zmAb0NyDzBmIL2QJvEOpjJ07vd4uL0+HziqVz0M2wRkYmQ7x6xO2YNfu0Ds7y/GQk5 /RdLwPpt4KK469NU+FDao0DiBrh5wfkOQf4+vBXWfLQY2RDJaWUVBh00pIEOPIa9LjMb f6+m0K0EPv9qCbcXp1wL4Aoh3f1U+68aWzTSMW6qLmyn52MPQTvno7JWebeWgaR9i7v4 jMrBBlZd/FyjL/UJ2WMtEAvo/7PCo9RJ+qh5YqXjjt5XwgxlXyRsOO1uzBeYIjpgToZP srctIrSe9ej7e7doZSFVPOQRaJl3d84j0ODHextXuwSNrDBgNzvZcd72OGCuXvivbhe6 +Vyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Sq5hcxwZ8ePp8DTrOnpUye1knsdChYLvWAxxRBcI1VQ=; b=d6eXTzxVyTbGWlYGwtJGlzC7IiU+P+loZlBeaB3soQ22VbZmrkEop18g3NtC8HL+2A 7hLeK1LFRc63qjRsW3BPg8g7PIWibws68cL6WWcYtlwxIP/5ClGBkr5UN9IxhHH3v24h jxrChOMiF4O5scutakOHgWRusKo817vcHF+NGuShP5K6E4GylFk41BYVkOrROw0tGsY2 2Myt4vkF7t6YUOfDZXUyK0V0+iLq14OPwzljcTKhZ2Up3iQA0gO4OdeSSo5ESiRAZUaH RdkKDWD6d8JXax7ctwhMHG4BLLE1sWlbByajq73funh3N/AwvXmQz3TDOV4XGLWasmWx 01dA== X-Gm-Message-State: AOAM530LnO7K96Ski9Jo3vn4UP+7ezfrJ0RERBqquyIpDD9KTBvKJBxQ 9vsBYk9bkS/bhE3btdcRBcGvKg== X-Google-Smtp-Source: ABdhPJyaLaJhNikX7iKZguFGONAjbzry3XRdEwjFo2Wtq0Ff+ARtpLU17CqXb8bLPHv4aBOCFmDeAw== X-Received: by 2002:a17:90a:d154:: with SMTP id t20mr34665384pjw.43.1642426171119; Mon, 17 Jan 2022 05:29:31 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:30 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 04/23] target/riscv: Improve delivery of guest external interrupts Date: Mon, 17 Jan 2022 18:58:07 +0530 Message-Id: <20220117132826.426418-5-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::631 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::631; envelope-from=anup@brainfault.org; helo=mail-pl1-x631.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The guest external interrupts from an interrupt controller are delivered only when the Guest/VM is running (i.e. V=1). This means any guest external interrupt which is triggered while the Guest/VM is not running (i.e. V=0) will be missed on QEMU resulting in Guest with sluggish response to serial console input and other I/O events. To solve this, we check and inject interrupt after setting V=1. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu_helper.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index aabf0a02f9..01a8baea06 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -325,6 +325,19 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable) } env->virt = set_field(env->virt, VIRT_ONOFF, enable); + + if (enable) { + /* + * The guest external interrupts from an interrupt controller are + * delivered only when the Guest/VM is running (i.e. V=1). This means + * any guest external interrupt which is triggered while the Guest/VM + * is not running (i.e. V=0) will be missed on QEMU resulting in guest + * with sluggish response to serial console input and other I/O events. + * + * To solve this, we check and inject interrupt after setting V=1. + */ + riscv_cpu_update_mip(env_archcpu(env), 0, 0); + } } bool riscv_cpu_two_stage_lookup(int mmu_idx) From patchwork Mon Jan 17 13:28:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715441 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id EF730C433EF for ; Mon, 17 Jan 2022 14:07:04 +0000 (UTC) Received: from localhost ([::1]:36464 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9Sf1-000667-Ml for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:07:03 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38500) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5C-0001Gr-2z for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:02 -0500 Received: from [2607:f8b0:4864:20::52d] (port=44730 helo=mail-pg1-x52d.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000ev-Ox for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:01 -0500 Received: by mail-pg1-x52d.google.com with SMTP id h23so10886926pgk.11 for ; Mon, 17 Jan 2022 05:29:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zQ+e6HEHagLV+ugP0Jg7+hNrvuiefpptJOptkFpBlzE=; b=tShLP9kHsH9UirMtkmYzCQRf15t8aMev8X0SWxW2VfRjWrMaYLgMW+dYhN1VWzxWUy KrIe2kTXU2GDhRYPc/hXM8wL8dHz6ZldSrmYzbH16qPZHH0bJfipl1gO6Q042IH+MrdL I+E7jmGke/iiAo8i9fKf5tTEJ3IYJLiYY3dwl2Ts24gdspyXQeATfqbANLJSEkUh6F6b 81v+1O6Xb+FE/2SThPP0GJch5JlbWheHH5Rl3BBrGxpKKmfa9VWt1Yr5RgTj2G2VfFEz IgFhCLSm2JcPl1QJSyDJf/JSJrN7DXyaPvQHZ0WwAUgMM+ox0wRrrv1rE0cLDkFrfE0M PlQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zQ+e6HEHagLV+ugP0Jg7+hNrvuiefpptJOptkFpBlzE=; b=y/6bvbf/Ds8tY5e+mjnW9Wo1TYgeMSuCyVxeu7ctCo1Y7VeDa7UcZPmyzSgC3mKIos PRUNrHpLTOUk9YYHgO/lObXNXfLT25/AI1jrVF5qgkzVwT5r+Fy1PiX9a3cgpzBUfDJl wjWAQ8dTgt40nUaI+vxwq1Ne1Cmkx3yEL/ELJDKBx5HdW9dUxqaLCh1Y8BidTxO/xGxw 1XAgF6v7u2BheiDpENeuJzDoN2n+FYO00Xt9RHqlh7U5ebSZ8m8+lcAkdEbY8HsxsxjN gLXQXpcb+VVG9vjiD8sM93tJMJLY0ebQFr/dz2YdEcRJ0YHDwSnolr047+Putz9Q/30w HryA== X-Gm-Message-State: AOAM5324rzPqQJ9XTDXN5aH5G6UJAEvgxVhv7alesPriIVwJ3TcxD2oE pvvzbu6icmjeRn6FWnkCa+LZoQ== X-Google-Smtp-Source: ABdhPJz3kxKCqXGgxyd7wFwu+f5qcLjHqNsiNubycDmJ9yiITQClouJVeFIx4I48vY0bbPdxV8JnZg== X-Received: by 2002:a63:101:: with SMTP id 1mr3810041pgb.252.1642426175114; Mon, 17 Jan 2022 05:29:35 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:34 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 05/23] target/riscv: Allow setting CPU feature from machine/device emulation Date: Mon, 17 Jan 2022 18:58:08 +0530 Message-Id: <20220117132826.426418-6-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::52d (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::52d; envelope-from=anup@brainfault.org; helo=mail-pg1-x52d.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The machine or device emulation should be able to force set certain CPU features because: 1) We can have certain CPU features which are in-general optional but implemented by RISC-V CPUs on the machine. 2) We can have devices which require a certain CPU feature. For example, AIA IMSIC devices expect AIA CSRs implemented by RISC-V CPUs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Bin Meng Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu.c | 11 +++-------- target/riscv/cpu.h | 5 +++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 6afb38f9b7..76f9786836 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -133,11 +133,6 @@ static void set_vext_version(CPURISCVState *env, int vext_ver) env->vext_ver = vext_ver; } -static void set_feature(CPURISCVState *env, int feature) -{ - env->features |= (1ULL << feature); -} - static void set_resetvec(CPURISCVState *env, target_ulong resetvec) { #ifndef CONFIG_USER_ONLY @@ -459,18 +454,18 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } if (cpu->cfg.mmu) { - set_feature(env, RISCV_FEATURE_MMU); + riscv_set_feature(env, RISCV_FEATURE_MMU); } if (cpu->cfg.pmp) { - set_feature(env, RISCV_FEATURE_PMP); + riscv_set_feature(env, RISCV_FEATURE_PMP); /* * Enhanced PMP should only be available * on harts with PMP support */ if (cpu->cfg.epmp) { - set_feature(env, RISCV_FEATURE_EPMP); + riscv_set_feature(env, RISCV_FEATURE_EPMP); } } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index df4e7d490e..2c04826496 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -356,6 +356,11 @@ static inline bool riscv_feature(CPURISCVState *env, int feature) return env->features & (1ULL << feature); } +static inline void riscv_set_feature(CPURISCVState *env, int feature) +{ + env->features |= (1ULL << feature); +} + #include "cpu_user.h" extern const char * const riscv_int_regnames[]; From patchwork Mon Jan 17 13:28:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715498 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 3E1D6C433F5 for ; Mon, 17 Jan 2022 14:49:55 +0000 (UTC) Received: from localhost ([::1]:46948 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9TKU-0006i4-00 for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:49:54 -0500 Received: from eggs.gnu.org ([209.51.188.92]:40512) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9SB4-0005J1-D8 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:36:06 -0500 Received: from [2607:f8b0:4864:20::233] (port=40581 helo=mail-oi1-x233.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9SB2-00028D-H2 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:36:05 -0500 Received: by mail-oi1-x233.google.com with SMTP id bx18so5001575oib.7 for ; Mon, 17 Jan 2022 05:36:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0mYUrPuAx21gJEjUJ5875VouJqz1EtIq2aKoQE+ku+s=; b=bsVQe/pO0kukuBueydcue4yr0gcp9T7XhMB7k1ZQ+ak0vpb1zMBWo7mWEEQIW6aHoj DulaLWJsFMnBw2WThrHfS4VKki2J8qj3tCMkMxVKDA1husnCWbe5Q7wmTDj9WZf+ptT0 tPn+oIPDnO8egOM+KWH7803AmUpPja827M5ov35ZUuOE8rTmFcIm0TythD0KjmBXwukD tyV73krezj16WMefwH1rCy3iNZnMQQkl/jMOoUsd0g0ruKl8ljE+pO+wNwiT/8vKChfH RETrR1fewbkd1+nwEwO4mB5pRRi/oexXRyPcwFHFSJ1jjVf9GanJye4YRGX0VIXrFAC/ QWSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0mYUrPuAx21gJEjUJ5875VouJqz1EtIq2aKoQE+ku+s=; b=3OanwYq//lVoa4rMBv03ZsKEMc73abIdr1jOs9fcPj9+Mh6lJz+nx605W9n/BnejQX zG5Djq8NAeJ7+JmaUoXsegYpBV54wp+0kmjpdgEbgMnECgICNdQfbxp3Za8T3dC1K2Yl A/AYRsiUgUXlqHMrKLAL7NhWnshPfTUv4LIc4MpBZHSlnNegiNjxc8bvj5zZ5U/hSTfl pzr49/N25YMCkxRINh+OV1kIqIIHzCzEx7mZNhRYgCxwIcIsPwdSd4tni4j8MKm+TWKt X5V+Vsgo05CPKV66ItsrML5G5I8Z4KyWWLPxEKL0xoIqTuUruTokTNmOFaJYd97x+IU2 uWqA== X-Gm-Message-State: AOAM533itGroMQEeUPd29XpRvhpRTPS2jVOvz6iXBmV95WMMLTOjWD47 Ol1gkwj3I1YlnNLMoSnEjTYY0D3qj2c25Q== X-Google-Smtp-Source: ABdhPJx1c9pBzKSjz+X1RpyM2EXYPZPRPI68CXAZfmeGf3TwL+Oxk/Y4UkZZXXzC23NHDjs4vs6GfQ== X-Received: by 2002:a17:90a:1d0a:: with SMTP id c10mr24986643pjd.243.1642426178978; Mon, 17 Jan 2022 05:29:38 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:38 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 06/23] target/riscv: Add AIA cpu feature Date: Mon, 17 Jan 2022 18:58:09 +0530 Message-Id: <20220117132826.426418-7-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::233 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::233; envelope-from=anup@brainfault.org; helo=mail-oi1-x233.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel We define a CPU feature for AIA CSR support in RISC-V CPUs which can be set by machine/device emulation. The RISC-V CSR emulation will also check this feature for emulating AIA CSRs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Bin Meng Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 2c04826496..71a2fd1da7 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -77,7 +77,8 @@ enum { RISCV_FEATURE_MMU, RISCV_FEATURE_PMP, RISCV_FEATURE_EPMP, - RISCV_FEATURE_MISA + RISCV_FEATURE_MISA, + RISCV_FEATURE_AIA }; #define PRIV_VERSION_1_10_0 0x00011000 From patchwork Mon Jan 17 13:28:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715452 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id E82F9C433EF for ; Mon, 17 Jan 2022 14:20:41 +0000 (UTC) Received: from localhost ([::1]:42256 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9SsB-0000YU-MJ for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:20:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38714) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5O-0001MJ-BQ for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:24 -0500 Received: from [2607:f8b0:4864:20::634] (port=37393 helo=mail-pl1-x634.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000fM-Rs for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:09 -0500 Received: by mail-pl1-x634.google.com with SMTP id n11so19279450plf.4 for ; Mon, 17 Jan 2022 05:29:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PdibuOLYPC/ok8+KwgVuRDuJ6qRSf1OClhPFVl1dlU4=; b=noL++wXgRWkdbLDG4lQ2Ilc4C5zKLtt/tzsPPd6M8ReWCSgHo32PpKOxZ/indhiP8r +q+thETLBR9Lkdw7OI3RDGdKmkCcOGB1GIYpVkXSjcirLbHPaM/dUIMePj8Io9hztjlT sCXDQV+27NoYWONxz8/k8pvxAbFP986KcungU4JN7CwWcATQ5sK/0xKM7G3Xq3LbSSxj 9VWGNIKdwcztx4jzUijVyw7bH1llsPvNBOFUkhybxgnIqQ7HMXTMQ/gDqG9HAJCtDo7I UILuSVOxobPbkTAPpj8YwGVqKRIdNA5cnKZv4/tmZGZfrMpy3mzhxy9fmSMN5UB0ijNp 0UlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PdibuOLYPC/ok8+KwgVuRDuJ6qRSf1OClhPFVl1dlU4=; b=46C9DSF9raLwun8a9Q5BBYBCdN2TNHYCsImnMLXuuyageJrT0YoJCISQ5T+4n0o9ow dSdOxavJwdHZsNmA3/PtOfuMc00YElR2aO+cX1B0oIa1TVAB9KTAx40sQfpFuEg+AwGC vOUA438iPl4fTih9FiC0fCZPawmDMPjXCGCblfK+m8QTLBV6cBwxvl5x8AxKjfQ3ZVlk /umL+nw8g+bSbj28eB5l/3SEySQmDpkpDhTWucfslxABiWcAAiabQKRGfK216iXiVITG aEn66A9XxrfJVkygweaJNxkxhDE8h60z2NB2nlddELD/w2y+P3ouS9kJRRtRfzZc+Yhi pg1A== X-Gm-Message-State: AOAM531DJo3jo4V1xTRf9gvGHuzxIESqLdPhEz8O4/s+80czgY8DXST6 WgIG6zWEAS/3PHr7QyrZTRKG5g== X-Google-Smtp-Source: ABdhPJyVNW8iNFUYnGn9k9AdJkPejhoJm5+nhSx8JGKWCSDqE3+Ar87sox3F5JpuC+/Y1UKGHEEdTg== X-Received: by 2002:a17:902:b110:b0:14a:197:dfea with SMTP id q16-20020a170902b11000b0014a0197dfeamr21544662plr.142.1642426183030; Mon, 17 Jan 2022 05:29:43 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:42 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 07/23] target/riscv: Add defines for AIA CSRs Date: Mon, 17 Jan 2022 18:58:10 +0530 Message-Id: <20220117132826.426418-8-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::634 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::634; envelope-from=anup@brainfault.org; helo=mail-pl1-x634.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The RISC-V AIA specification extends RISC-V local interrupts and introduces new CSRs. This patch adds defines for the new AIA CSRs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu_bits.h | 127 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index fc9332c545..a2c47ffa79 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -168,6 +168,31 @@ #define CSR_MTVAL 0x343 #define CSR_MIP 0x344 +/* Machine-Level Window to Indirectly Accessed Registers (AIA) */ +#define CSR_MISELECT 0x350 +#define CSR_MIREG 0x351 + +/* Machine-Level Interrupts (AIA) */ +#define CSR_MTOPI 0xfb0 + +/* Machine-Level IMSIC Interface (AIA) */ +#define CSR_MSETEIPNUM 0x358 +#define CSR_MCLREIPNUM 0x359 +#define CSR_MSETEIENUM 0x35a +#define CSR_MCLREIENUM 0x35b +#define CSR_MTOPEI 0x35c + +/* Virtual Interrupts for Supervisor Level (AIA) */ +#define CSR_MVIEN 0x308 +#define CSR_MVIP 0x309 + +/* Machine-Level High-Half CSRs (AIA) */ +#define CSR_MIDELEGH 0x313 +#define CSR_MIEH 0x314 +#define CSR_MVIENH 0x318 +#define CSR_MVIPH 0x319 +#define CSR_MIPH 0x354 + /* Supervisor Trap Setup */ #define CSR_SSTATUS 0x100 #define CSR_SEDELEG 0x102 @@ -187,6 +212,24 @@ #define CSR_SPTBR 0x180 #define CSR_SATP 0x180 +/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */ +#define CSR_SISELECT 0x150 +#define CSR_SIREG 0x151 + +/* Supervisor-Level Interrupts (AIA) */ +#define CSR_STOPI 0xdb0 + +/* Supervisor-Level IMSIC Interface (AIA) */ +#define CSR_SSETEIPNUM 0x158 +#define CSR_SCLREIPNUM 0x159 +#define CSR_SSETEIENUM 0x15a +#define CSR_SCLREIENUM 0x15b +#define CSR_STOPEI 0x15c + +/* Supervisor-Level High-Half CSRs (AIA) */ +#define CSR_SIEH 0x114 +#define CSR_SIPH 0x154 + /* Hpervisor CSRs */ #define CSR_HSTATUS 0x600 #define CSR_HEDELEG 0x602 @@ -217,6 +260,35 @@ #define CSR_MTINST 0x34a #define CSR_MTVAL2 0x34b +/* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */ +#define CSR_HVIEN 0x608 +#define CSR_HVICTL 0x609 +#define CSR_HVIPRIO1 0x646 +#define CSR_HVIPRIO2 0x647 + +/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */ +#define CSR_VSISELECT 0x250 +#define CSR_VSIREG 0x251 + +/* VS-Level Interrupts (H-extension with AIA) */ +#define CSR_VSTOPI 0xeb0 + +/* VS-Level IMSIC Interface (H-extension with AIA) */ +#define CSR_VSSETEIPNUM 0x258 +#define CSR_VSCLREIPNUM 0x259 +#define CSR_VSSETEIENUM 0x25a +#define CSR_VSCLREIENUM 0x25b +#define CSR_VSTOPEI 0x25c + +/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */ +#define CSR_HIDELEGH 0x613 +#define CSR_HVIENH 0x618 +#define CSR_HVIPH 0x655 +#define CSR_HVIPRIO1H 0x656 +#define CSR_HVIPRIO2H 0x657 +#define CSR_VSIEH 0x214 +#define CSR_VSIPH 0x254 + /* Enhanced Physical Memory Protection (ePMP) */ #define CSR_MSECCFG 0x747 #define CSR_MSECCFGH 0x757 @@ -632,4 +704,59 @@ typedef enum RISCVException { #define UMTE_U_PM_INSN U_PM_INSN #define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN) +/* MISELECT, SISELECT, and VSISELECT bits (AIA) */ +#define ISELECT_IPRIO0 0x30 +#define ISELECT_IPRIO15 0x3f +#define ISELECT_IMSIC_EIDELIVERY 0x70 +#define ISELECT_IMSIC_EITHRESHOLD 0x72 +#define ISELECT_IMSIC_EIP0 0x80 +#define ISELECT_IMSIC_EIP63 0xbf +#define ISELECT_IMSIC_EIE0 0xc0 +#define ISELECT_IMSIC_EIE63 0xff +#define ISELECT_IMSIC_FIRST ISELECT_IMSIC_EIDELIVERY +#define ISELECT_IMSIC_LAST ISELECT_IMSIC_EIE63 +#define ISELECT_MASK 0x1ff + +/* Dummy [M|S|VS]ISELECT value for emulating [M|S|VS]TOPEI CSRs */ +#define ISELECT_IMSIC_TOPEI (ISELECT_MASK + 1) + +/* IMSIC bits (AIA) */ +#define IMSIC_TOPEI_IID_SHIFT 16 +#define IMSIC_TOPEI_IID_MASK 0x7ff +#define IMSIC_TOPEI_IPRIO_MASK 0x7ff +#define IMSIC_EIPx_BITS 32 +#define IMSIC_EIEx_BITS 32 + +/* MTOPI and STOPI bits (AIA) */ +#define TOPI_IID_SHIFT 16 +#define TOPI_IID_MASK 0xfff +#define TOPI_IPRIO_MASK 0xff + +/* Interrupt priority bits (AIA) */ +#define IPRIO_IRQ_BITS 8 +#define IPRIO_MMAXIPRIO 255 +#define IPRIO_DEFAULT_MMAXIPRIO 15 +#define IPRIO_DEFAULT_VS (IPRIO_DEFAULT_MMAXIPRIO - 4) +#define IPRIO_DEFAULT_SGEXT (IPRIO_DEFAULT_MMAXIPRIO - 5) +#define IPRIO_DEFAULT_S (IPRIO_DEFAULT_MMAXIPRIO - 6) +#define IPRIO_DEFAULT_M (IPRIO_DEFAULT_MMAXIPRIO - 7) +#define IPRIO_DEFAULT_U(_i) (((_i) >> 4) & 0x3) +#define IPRIO_DEFAULT_L(_i) ((_i) & 0xf) +#define IPRIO_DEFAULT_16_23(_i) \ + (IPRIO_DEFAULT_MMAXIPRIO - (IPRIO_DEFAULT_L(_i) >> 1)) +#define IPRIO_DEFAULT_24_31(_i) \ + (IPRIO_DEFAULT_MMAXIPRIO - (4 + (IPRIO_DEFAULT_L(_i) >> 1))) +#define IPRIO_DEFAULT_32_47(_i) \ + (IPRIO_DEFAULT_MMAXIPRIO - (IPRIO_DEFAULT_L(_i) >> 2)) +#define IPRIO_DEFAULT_48_63(_i) \ + (IPRIO_DEFAULT_MMAXIPRIO - (8 + (IPRIO_DEFAULT_L(_i) >> 2))) + +/* HVICTL bits (AIA) */ +#define HVICTL_VTI 0x40000000 +#define HVICTL_IID 0x0fff0000 +#define HVICTL_IPRIOM 0x00000100 +#define HVICTL_IPRIO 0x000000ff +#define HVICTL_VALID_MASK \ + (HVICTL_VTI | HVICTL_IID | HVICTL_IPRIOM | HVICTL_IPRIO) + #endif From patchwork Mon Jan 17 13:28:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715490 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 846D1C433FE for ; Mon, 17 Jan 2022 14:34:27 +0000 (UTC) Received: from localhost ([::1]:46420 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9T5W-00042A-5s for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:34:26 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38536) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5D-0001Jh-B4 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:03 -0500 Received: from [2607:f8b0:4864:20::536] (port=36745 helo=mail-pg1-x536.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000fg-PC for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:03 -0500 Received: by mail-pg1-x536.google.com with SMTP id e9so374500pgb.3 for ; Mon, 17 Jan 2022 05:29:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=et/vu/jUQE/J1fBuabFyLO2+T/t14yfVAc9Ry0i324A=; b=mXSD7tfcj6DbAeUcRl7p0MC2Jv8gCQRdFUmwg6VgogdsWYIHm+siDHVhrbx4Mdt9Qu kOnfaMiEyFATkRDBlvVt28JpAUpfuSw9VhHbmU7oarGB+uj74FRP04mgjfAM/453zB/5 BRZ12Fn/MIeYHbEwmbS0jJyC+z7Wu9M75tdimqq4/46FqFJfGmIS2JDl/vXKGAcSRreg bmykfJ014T4r3QbGZYhLtPU8xgbGMdeu67CQtYlvU+5FeB64MclBGZ3oI5OydZ8k00Up QutZy4GdAEsR4WheHu8pkdH4UoXckIEyU3EStlBnNjmioYBEUDn31iyA1PIcC3faq2kn 1Gqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=et/vu/jUQE/J1fBuabFyLO2+T/t14yfVAc9Ry0i324A=; b=t+K9lYv3fXYjik7QzPZ3rAfH4uHk6jFv6x7xFa4GaTRjP83tZpgs8svYdUFgHxlTKV 7B28VWkvMzoYVufEf2sPI+ALWwNOBinJiaPh/wpPYN3BjBBbt79wMXvvU6FXJYbIx/Qc 2hFdpjVUbeUb4AhCCH9xFIOBOBF3zvLCbJaU5IwwG2CFPKAWzaWpP0GcPzbSQArmmg3W bMP4dJSYysoDqgkPk7okOfE5h2a8HyTRcxCZ5uBZL6byrpxU7UYsdEIN/JHBlZ1Vlh/m f0bOeHWQASemNXehK03w2E6dX0S1ZWQH0hyC2ADrohoVpYdKUr+k1A0iVgSt5b31jgWE 710Q== X-Gm-Message-State: AOAM531mekblYsfQqjcrdb+jzwUMxPwf5l3gafFuRaEwTxJsWUmqLZjQ DH+O7pgOV6VylEXkYWcBtpwbQA== X-Google-Smtp-Source: ABdhPJy+O3r35E87/OIpDKCuMUDkNOWXGE3w0oIsM1Nnw95Ra0GdT2bn9DLLVfgK3QLLOc+ebkmKeQ== X-Received: by 2002:a63:90c8:: with SMTP id a191mr19579561pge.622.1642426186939; Mon, 17 Jan 2022 05:29:46 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:46 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 08/23] target/riscv: Allow AIA device emulation to set ireg rmw callback Date: Mon, 17 Jan 2022 18:58:11 +0530 Message-Id: <20220117132826.426418-9-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::536 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::536; envelope-from=anup@brainfault.org; helo=mail-pg1-x536.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The AIA device emulation (such as AIA IMSIC) should be able to set (or provide) AIA ireg read-modify-write callback for each privilege level of a RISC-V HART. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu.h | 23 +++++++++++++++++++++++ target/riscv/cpu_helper.c | 14 ++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 71a2fd1da7..cee70f8608 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -254,6 +254,22 @@ struct CPURISCVState { uint64_t (*rdtime_fn)(uint32_t); uint32_t rdtime_fn_arg; + /* machine specific AIA ireg read-modify-write callback */ +#define AIA_MAKE_IREG(__isel, __priv, __virt, __vgein, __xlen) \ + ((((__xlen) & 0xff) << 24) | \ + (((__vgein) & 0x3f) << 20) | \ + (((__virt) & 0x1) << 18) | \ + (((__priv) & 0x3) << 16) | \ + (__isel & 0xffff)) +#define AIA_IREG_ISEL(__ireg) ((__ireg) & 0xffff) +#define AIA_IREG_PRIV(__ireg) (((__ireg) >> 16) & 0x3) +#define AIA_IREG_VIRT(__ireg) (((__ireg) >> 18) & 0x1) +#define AIA_IREG_VGEIN(__ireg) (((__ireg) >> 20) & 0x3f) +#define AIA_IREG_XLEN(__ireg) (((__ireg) >> 24) & 0xff) + int (*aia_ireg_rmw_fn[4])(void *arg, target_ulong reg, + target_ulong *val, target_ulong new_val, target_ulong write_mask); + void *aia_ireg_rmw_fn_arg[4]; + /* True if in debugger mode. */ bool debugger; @@ -410,6 +426,13 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value); #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */ void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t), uint32_t arg); +void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv, + int (*rmw_fn)(void *arg, + target_ulong reg, + target_ulong *val, + target_ulong new_val, + target_ulong write_mask), + void *rmw_fn_arg); #endif void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 01a8baea06..59c8f900df 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -395,6 +395,20 @@ void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t), env->rdtime_fn_arg = arg; } +void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv, + int (*rmw_fn)(void *arg, + target_ulong reg, + target_ulong *val, + target_ulong new_val, + target_ulong write_mask), + void *rmw_fn_arg) +{ + if (priv <= PRV_M) { + env->aia_ireg_rmw_fn[priv] = rmw_fn; + env->aia_ireg_rmw_fn_arg[priv] = rmw_fn_arg; + } +} + void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) { if (newpriv > PRV_M) { From patchwork Mon Jan 17 13:28:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715492 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 7E9DAC433F5 for ; Mon, 17 Jan 2022 14:37:31 +0000 (UTC) Received: from localhost ([::1]:55146 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9T8U-0001mm-F5 for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:37:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38594) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5I-0001LD-Mq for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:12 -0500 Received: from [2607:f8b0:4864:20::1032] (port=56124 helo=mail-pj1-x1032.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000h1-PY for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:03 -0500 Received: by mail-pj1-x1032.google.com with SMTP id hv15so20538015pjb.5 for ; Mon, 17 Jan 2022 05:29:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DV+1jm6zdFl126A0iBqYeG97FScr8VTPmyJLGw4/f0M=; b=vUS1Kjj88uZLxLvgTIjhvy66u0drk0K6IQ86+WmXSgAt2FnUg+ZaAdVPmjxYvEyxUJ T6rbJBtKrzQqPJiXZa3bMH5PISLuHY6LXTJr/1b1lEA1snvTpDx0v7LaKB6oHqcuVn9d Z8Z7fbh0UYPixCOj8QnagHCL6mD4ZEdajkHqOXpEb111q0rYoHmYNzHzxlWEQEGMD6CZ 46OhdQCeTZwFq6aWGGyNnuboDPjoy5SFth0X3M1ECx7Mxk0O8yVaoKGdOUkhVHTf0La3 t895DS7gS/AUqgFI0eF2g8IFEv4aygIkKGyW0D0A4fsa2L6WA/rnNIiV/uqo2ekOojAk zPKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DV+1jm6zdFl126A0iBqYeG97FScr8VTPmyJLGw4/f0M=; b=iLtb1s2zpR/T041NWapuu+3tIXe65m4IyJF9Mvhmz5Ce7IQfBKKoPa+EiJdj7pUMmU Bb9q9FC81gx3c2C6AjmdDmonAICclW9WNIsww1nZSmGvdQHMeyeYB2/P+WgHKlop1jMa tHLjgPr6LvlYNd/BFqBxoNn3PZoWYgP3gHf3fQkbWgw+g+xeCdZD7HzHNIws9wV5Hw0V o3nPCKi2ZFv/rbTN+GQA7wxLEui85RZogeN3SJRWw1q5a8Eta+Gr1oEBcNpZ6ZFuL+h5 ulIMML/bt426ZeBtpJSp3v1Mgu8s/EmBwN5fsp/HSfW2TuIHagOtHltAzMc1n3TpbrWt /C4Q== X-Gm-Message-State: AOAM5306Ap7vClem9oGxb9+2Ex6Nab+KgN5XixVBNN9Teb70SkwvgjGf QILwXW14cNtnf/SG4Bo4xouQSQ== X-Google-Smtp-Source: ABdhPJzdi5hTN+NtPUBI7sPL0zMw5pvqHtP77Ts24tMBstnHcjyjppgQwhI8sLptbJedaxpsSDbrqg== X-Received: by 2002:a17:90a:f015:: with SMTP id bt21mr25136473pjb.3.1642426191095; Mon, 17 Jan 2022 05:29:51 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:50 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 09/23] target/riscv: Implement AIA local interrupt priorities Date: Mon, 17 Jan 2022 18:58:12 +0530 Message-Id: <20220117132826.426418-10-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::1032 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::1032; envelope-from=anup@brainfault.org; helo=mail-pj1-x1032.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The AIA spec defines programmable 8-bit priority for each local interrupt at M-level, S-level and VS-level so we extend local interrupt processing to consider AIA interrupt priorities. The AIA CSRs which help software configure local interrupt priorities will be added by subsequent patches. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis --- target/riscv/cpu.c | 19 +++ target/riscv/cpu.h | 12 ++ target/riscv/cpu_helper.c | 242 ++++++++++++++++++++++++++++++++++---- target/riscv/machine.c | 3 + 4 files changed, 255 insertions(+), 21 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 76f9786836..167d86eef7 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -370,6 +370,10 @@ void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb, static void riscv_cpu_reset(DeviceState *dev) { +#ifndef CONFIG_USER_ONLY + uint8_t iprio; + int i, irq, rdzero; +#endif CPUState *cs = CPU(dev); RISCVCPU *cpu = RISCV_CPU(cs); RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu); @@ -392,6 +396,21 @@ static void riscv_cpu_reset(DeviceState *dev) env->miclaim = MIP_SGEIP; env->pc = env->resetvec; env->two_stage_lookup = false; + + /* Initialized default priorities of local interrupts. */ + for (i = 0; i < ARRAY_SIZE(env->miprio); i++) { + iprio = riscv_cpu_default_priority(i); + env->miprio[i] = (i == IRQ_M_EXT) ? 0 : iprio; + env->siprio[i] = (i == IRQ_S_EXT) ? 0 : iprio; + env->hviprio[i] = 0; + } + i = 0; + while (!riscv_cpu_hviprio_index2irq(i, &irq, &rdzero)) { + if (!rdzero) { + env->hviprio[irq] = env->miprio[irq]; + } + i++; + } /* mmte is supposed to have pm.current hardwired to 1 */ env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT); #endif diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index cee70f8608..65d2b606fc 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -190,6 +190,10 @@ struct CPURISCVState { target_ulong mcause; target_ulong mtval; /* since: priv-1.10.0 */ + /* Machine and Supervisor interrupt priorities */ + uint8_t miprio[64]; + uint8_t siprio[64]; + /* Hypervisor CSRs */ target_ulong hstatus; target_ulong hedeleg; @@ -202,6 +206,9 @@ struct CPURISCVState { target_ulong hgeip; uint64_t htimedelta; + /* Hypervisor controlled virtual interrupt priorities */ + uint8_t hviprio[64]; + /* Upper 64-bits of 128-bit CSRs */ uint64_t mscratchh; uint64_t sscratchh; @@ -392,6 +399,11 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, int cpuid, void *opaque); int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); +int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero); +uint8_t riscv_cpu_default_priority(int irq); +int riscv_cpu_mirq_pending(CPURISCVState *env); +int riscv_cpu_sirq_pending(CPURISCVState *env); +int riscv_cpu_vsirq_pending(CPURISCVState *env); bool riscv_cpu_fp_enabled(CPURISCVState *env); target_ulong riscv_cpu_get_geilen(CPURISCVState *env); void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 59c8f900df..3a36200780 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -151,36 +151,236 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, } #ifndef CONFIG_USER_ONLY -static int riscv_cpu_local_irq_pending(CPURISCVState *env) + +/* + * The HS-mode is allowed to configure priority only for the + * following VS-mode local interrupts: + * + * 0 (Reserved interrupt, reads as zero) + * 1 Supervisor software interrupt + * 4 (Reserved interrupt, reads as zero) + * 5 Supervisor timer interrupt + * 8 (Reserved interrupt, reads as zero) + * 13 (Reserved interrupt) + * 14 " + * 15 " + * 16 " + * 18 Debug/trace interrupt + * 20 (Reserved interrupt) + * 22 " + * 24 " + * 26 " + * 28 " + * 30 (Reserved for standard reporting of bus or system errors) + */ + +static int hviprio_index2irq[] = + { 0, 1, 4, 5, 8, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30 }; +static int hviprio_index2rdzero[] = + { 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero) { - target_ulong virt_enabled = riscv_cpu_virt_enabled(env); + if (index < 0 || ARRAY_SIZE(hviprio_index2irq) <= index) { + return -EINVAL; + } + + if (out_irq) { + *out_irq = hviprio_index2irq[index]; + } - target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE); - target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE); + if (out_rdzero) { + *out_rdzero = hviprio_index2rdzero[index]; + } - target_ulong vsgemask = - (target_ulong)1 << get_field(env->hstatus, HSTATUS_VGEIN); - target_ulong vsgein = (env->hgeip & vsgemask) ? MIP_VSEIP : 0; + return 0; +} - target_ulong pending = (env->mip | vsgein) & env->mie; +uint8_t riscv_cpu_default_priority(int irq) +{ + int u, l; + uint8_t iprio = IPRIO_MMAXIPRIO; - target_ulong mie = env->priv < PRV_M || - (env->priv == PRV_M && mstatus_mie); - target_ulong sie = env->priv < PRV_S || - (env->priv == PRV_S && mstatus_sie); - target_ulong hsie = virt_enabled || sie; - target_ulong vsie = virt_enabled && sie; + if (irq < 0 || irq > 63) { + return iprio; + } - target_ulong irqs = - (pending & ~env->mideleg & -mie) | - (pending & env->mideleg & ~env->hideleg & -hsie) | - (pending & env->mideleg & env->hideleg & -vsie); + /* + * Default priorities of local interrupts are defined in the + * RISC-V Advanced Interrupt Architecture specification. + * + * ---------------------------------------------------------------- + * Default | + * Priority | Major Interrupt Numbers + * ---------------------------------------------------------------- + * Highest | 63 (3f), 62 (3e), 31 (1f), 30 (1e), 61 (3d), 60 (3c), + * | 59 (3b), 58 (3a), 29 (1d), 28 (1c), 57 (39), 56 (38), + * | 55 (37), 54 (36), 27 (1b), 26 (1a), 53 (35), 52 (34), + * | 51 (33), 50 (32), 25 (19), 24 (18), 49 (31), 48 (30) + * | + * | 11 (0b), 3 (03), 7 (07) + * | 9 (09), 1 (01), 5 (05) + * | 12 (0c) + * | 10 (0a), 2 (02), 6 (06) + * | + * | 47 (2f), 46 (2e), 23 (17), 22 (16), 45 (2d), 44 (2c), + * | 43 (2b), 42 (2a), 21 (15), 20 (14), 41 (29), 40 (28), + * | 39 (27), 38 (26), 19 (13), 18 (12), 37 (25), 36 (24), + * Lowest | 35 (23), 34 (22), 17 (11), 16 (10), 33 (21), 32 (20) + * ---------------------------------------------------------------- + */ - if (irqs) { - return ctz64(irqs); /* since non-zero */ + u = IPRIO_DEFAULT_U(irq); + l = IPRIO_DEFAULT_L(irq); + if (u == 0) { + if (irq == IRQ_VS_EXT || irq == IRQ_VS_TIMER || + irq == IRQ_VS_SOFT) { + iprio = IPRIO_DEFAULT_VS; + } else if (irq == IRQ_S_GEXT) { + iprio = IPRIO_DEFAULT_SGEXT; + } else if (irq == IRQ_S_EXT || irq == IRQ_S_TIMER || + irq == IRQ_S_SOFT) { + iprio = IPRIO_DEFAULT_S; + } else if (irq == IRQ_M_EXT || irq == IRQ_M_TIMER || + irq == IRQ_M_SOFT) { + iprio = IPRIO_DEFAULT_M; + } else { + iprio = IPRIO_DEFAULT_VS; + } + } else if (u == 1) { + if (l < 8) { + iprio = IPRIO_DEFAULT_16_23(irq); + } else { + iprio = IPRIO_DEFAULT_24_31(irq); + } + } else if (u == 2) { + iprio = IPRIO_DEFAULT_32_47(irq); + } else if (u == 3) { + iprio = IPRIO_DEFAULT_48_63(irq); + } + + return iprio; +} + +static int riscv_cpu_pending_to_irq(CPURISCVState *env, + int extirq, unsigned int extirq_def_prio, + uint64_t pending, uint8_t *iprio) +{ + int irq, best_irq = RISCV_EXCP_NONE; + unsigned int prio, best_prio = UINT_MAX; + + if (!pending) { + return RISCV_EXCP_NONE; + } + + irq = ctz64(pending); + if (!riscv_feature(env, RISCV_FEATURE_AIA)) { + return irq; + } + + pending = pending >> irq; + while (pending) { + prio = iprio[irq]; + if (!prio) { + if (irq == extirq) { + prio = extirq_def_prio; + } else { + prio = (riscv_cpu_default_priority(irq) < extirq_def_prio) ? + 1 : IPRIO_MMAXIPRIO; + } + } + if ((pending & 0x1) && (prio <= best_prio)) { + best_irq = irq; + best_prio = prio; + } + irq++; + pending = pending >> 1; + } + + return best_irq; +} + +static uint64_t riscv_cpu_all_pending(CPURISCVState *env) +{ + uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN); + uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; + + return (env->mip | vsgein) & env->mie; +} + +int riscv_cpu_mirq_pending(CPURISCVState *env) +{ + uint64_t irqs = riscv_cpu_all_pending(env) & ~env->mideleg & + ~(MIP_SGEIP | MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); + + return riscv_cpu_pending_to_irq(env, IRQ_M_EXT, IPRIO_DEFAULT_M, + irqs, env->miprio); +} + +int riscv_cpu_sirq_pending(CPURISCVState *env) +{ + uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & + ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); + + return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, + irqs, env->siprio); +} + +int riscv_cpu_vsirq_pending(CPURISCVState *env) +{ + uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & + (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); + + return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, + irqs >> 1, env->hviprio); +} + +static int riscv_cpu_local_irq_pending(CPURISCVState *env) +{ + int virq; + uint64_t irqs, pending, mie, hsie, vsie; + + /* Determine interrupt enable state of all privilege modes */ + if (riscv_cpu_virt_enabled(env)) { + mie = 1; + hsie = 1; + vsie = (env->priv < PRV_S) || + (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_SIE)); } else { - return RISCV_EXCP_NONE; /* indicates no pending interrupt */ + mie = (env->priv < PRV_M) || + (env->priv == PRV_M && get_field(env->mstatus, MSTATUS_MIE)); + hsie = (env->priv < PRV_S) || + (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_SIE)); + vsie = 0; } + + /* Determine all pending interrupts */ + pending = riscv_cpu_all_pending(env); + + /* Check M-mode interrupts */ + irqs = pending & ~env->mideleg & -mie; + if (irqs) { + return riscv_cpu_pending_to_irq(env, IRQ_M_EXT, IPRIO_DEFAULT_M, + irqs, env->miprio); + } + + /* Check HS-mode interrupts */ + irqs = pending & env->mideleg & ~env->hideleg & -hsie; + if (irqs) { + return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, + irqs, env->siprio); + } + + /* Check VS-mode interrupts */ + irqs = pending & env->mideleg & env->hideleg & -vsie; + if (irqs) { + virq = riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, + irqs >> 1, env->hviprio); + return (virq <= 0) ? virq : virq + 1; + } + + /* Indicate no pending interrupt */ + return RISCV_EXCP_NONE; } bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request) diff --git a/target/riscv/machine.c b/target/riscv/machine.c index c11eb4639c..bae4f69725 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -92,6 +92,7 @@ static const VMStateDescription vmstate_hyper = { VMSTATE_UINTTL(env.hgeie, RISCVCPU), VMSTATE_UINTTL(env.hgeip, RISCVCPU), VMSTATE_UINT64(env.htimedelta, RISCVCPU), + VMSTATE_UINT8_ARRAY(env.hviprio, RISCVCPU, 64), VMSTATE_UINT64(env.vsstatus, RISCVCPU), VMSTATE_UINTTL(env.vstvec, RISCVCPU), @@ -194,6 +195,8 @@ const VMStateDescription vmstate_riscv_cpu = { .fields = (VMStateField[]) { VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32), VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32), + VMSTATE_UINT8_ARRAY(env.miprio, RISCVCPU, 64), + VMSTATE_UINT8_ARRAY(env.siprio, RISCVCPU, 64), VMSTATE_UINTTL(env.pc, RISCVCPU), VMSTATE_UINTTL(env.load_res, RISCVCPU), VMSTATE_UINTTL(env.load_val, RISCVCPU), From patchwork Mon Jan 17 13:28:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715442 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 0FD90C433EF for ; Mon, 17 Jan 2022 14:12:02 +0000 (UTC) Received: from localhost ([::1]:47194 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9Sjp-0004Kg-Hf for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:12:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38544) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5D-0001KE-OH for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:04 -0500 Received: from [2607:f8b0:4864:20::62d] (port=34433 helo=mail-pl1-x62d.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S58-0000hC-N8 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:03 -0500 Received: by mail-pl1-x62d.google.com with SMTP id a7so18484381plh.1 for ; Mon, 17 Jan 2022 05:29:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=V5sk68nEwMh15eBg6i9tW8x2m3gI6TDuT2K2k+iDNW4=; b=PHW221/xm32ri2KLuAC/FvhUSzjfAea03aXtdw7Q74RHgaQAlY/UMInXMagplwRFIF uOJVwJRdo2/YVNU4Xv7N0iZ042UF4eDKmkGbEhDEoFb9jci2Wuil0Z16HPF4nT6lnXwy hFXCgSojLU6x0CVrgNnHTpv4362gYfYakDeoTdzfKI8LyK+Y9GI6vs/xoHKJfuwHlQpv 4EL43oUVr0ZbVNdHRi1f5++puhVjk8Ls0rWOsSLVkacvxBODxb1L2ZBwRiU/OQrc/Zu1 IEKtfXMvx3Ocn2HJTk0HHeC1oqIVkpKTjS20aHtNSa2K/Qkmt3ij3odF5SWeZhnbotaq 0uxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=V5sk68nEwMh15eBg6i9tW8x2m3gI6TDuT2K2k+iDNW4=; b=HpDJQojFRQ22QvksbY4VmIGbrgD2uqdX/jbBVRTLWKd9cLxNQ4D8XHYSK6g7FRA0NG t9G3cWFrIYHol8mGj9WR/nX0L30F65Ue+TGnLkbco10MMvH/9PG4cW3K55qDESRTE4AE jeWJh9HaoM0C+DBS+yB4NLE/M9N5eCmncsEXdX1Vj1ujZAMmSGMo+MSY9KCZxqRzAsR3 E0eUzYz1PvPu1+TUWPWnQQv3qYloZ9lSItpaEIeusFGtcm/JNVUfeCZeVIRtY+8Z3D5U yuQTQJt27/GwNlLFYXjofflrMmwmtX3Gt0dlzuCms4Gm22zNrys0W3MFwgQXs4D0+k4G P9Vg== X-Gm-Message-State: AOAM532gq4QhXBh75NSeek6PO8fAcXgRN2p6jM8tf5uDhvbIzOgWP2uA bVo6a8UreH3mDdcERG3JtmkQag== X-Google-Smtp-Source: ABdhPJy3Y490gG+zh+LkecHlt3XM8k7iBC2QsIgtBQcuhEZQRn0nqsYXcz22nXEeNQqPncf5w/anFg== X-Received: by 2002:a17:902:7fc4:b0:14a:9f3d:3358 with SMTP id t4-20020a1709027fc400b0014a9f3d3358mr10600185plb.165.1642426195358; Mon, 17 Jan 2022 05:29:55 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:54 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 10/23] target/riscv: Implement AIA CSRs for 64 local interrupts on RV32 Date: Mon, 17 Jan 2022 18:58:13 +0530 Message-Id: <20220117132826.426418-11-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::62d (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::62d; envelope-from=anup@brainfault.org; helo=mail-pl1-x62d.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The AIA specification adds new CSRs for RV32 so that RISC-V hart can support 64 local interrupts on both RV32 and RV64. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu.h | 14 +- target/riscv/cpu_helper.c | 10 +- target/riscv/csr.c | 560 +++++++++++++++++++++++++++++++------- target/riscv/machine.c | 10 +- 4 files changed, 474 insertions(+), 120 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 65d2b606fc..a141686b58 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -170,12 +170,12 @@ struct CPURISCVState { */ uint64_t mstatus; - target_ulong mip; + uint64_t mip; - uint32_t miclaim; + uint64_t miclaim; - target_ulong mie; - target_ulong mideleg; + uint64_t mie; + uint64_t mideleg; target_ulong satp; /* since: priv-1.10.0 */ target_ulong stval; @@ -197,7 +197,7 @@ struct CPURISCVState { /* Hypervisor CSRs */ target_ulong hstatus; target_ulong hedeleg; - target_ulong hideleg; + uint64_t hideleg; target_ulong hcounteren; target_ulong htval; target_ulong htinst; @@ -433,8 +433,8 @@ void riscv_cpu_list(void); #ifndef CONFIG_USER_ONLY bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request); void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env); -int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts); -uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value); +int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts); +uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value); #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */ void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t), uint32_t arg); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 3a36200780..98eb99c2d4 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -545,7 +545,7 @@ bool riscv_cpu_two_stage_lookup(int mmu_idx) return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK; } -int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts) +int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts) { CPURISCVState *env = &cpu->env; if (env->miclaim & interrupts) { @@ -556,11 +556,11 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts) } } -uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value) +uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) { CPURISCVState *env = &cpu->env; CPUState *cs = CPU(cpu); - uint32_t gein, vsgein = 0, old = env->mip; + uint64_t gein, vsgein = 0, old = env->mip; bool locked = false; if (riscv_cpu_virt_enabled(env)) { @@ -1264,7 +1264,7 @@ void riscv_cpu_do_interrupt(CPUState *cs) */ bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG); target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK; - target_ulong deleg = async ? env->mideleg : env->medeleg; + uint64_t deleg = async ? env->mideleg : env->medeleg; target_ulong tval = 0; target_ulong htval = 0; target_ulong mtval2 = 0; @@ -1331,7 +1331,7 @@ void riscv_cpu_do_interrupt(CPUState *cs) cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) { /* handle the trap in S-mode */ if (riscv_has_ext(env, RVH)) { - target_ulong hdeleg = async ? env->hideleg : env->hedeleg; + uint64_t hdeleg = async ? env->hideleg : env->hedeleg; if (riscv_cpu_virt_enabled(env) && ((hdeleg >> cause) & 1)) { /* Trap to VS mode */ diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 6d6f56af3c..cab02a48e5 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -154,6 +154,15 @@ static RISCVException any32(CPURISCVState *env, int csrno) } +static int aia_any32(CPURISCVState *env, int csrno) +{ + if (!riscv_feature(env, RISCV_FEATURE_AIA)) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return any32(env, csrno); +} + static RISCVException smode(CPURISCVState *env, int csrno) { if (riscv_has_ext(env, RVS)) { @@ -163,6 +172,24 @@ static RISCVException smode(CPURISCVState *env, int csrno) return RISCV_EXCP_ILLEGAL_INST; } +static int smode32(CPURISCVState *env, int csrno) +{ + if (riscv_cpu_mxl(env) != MXL_RV32) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return smode(env, csrno); +} + +static int aia_smode32(CPURISCVState *env, int csrno) +{ + if (!riscv_feature(env, RISCV_FEATURE_AIA)) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return smode32(env, csrno); +} + static RISCVException hmode(CPURISCVState *env, int csrno) { if (riscv_has_ext(env, RVS) && @@ -203,6 +230,15 @@ static RISCVException pointer_masking(CPURISCVState *env, int csrno) return RISCV_EXCP_ILLEGAL_INST; } +static int aia_hmode32(CPURISCVState *env, int csrno) +{ + if (!riscv_feature(env, RISCV_FEATURE_AIA)) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return hmode32(env, csrno); +} + static RISCVException pmp(CPURISCVState *env, int csrno) { if (riscv_feature(env, RISCV_FEATURE_PMP)) { @@ -443,15 +479,15 @@ static RISCVException read_timeh(CPURISCVState *env, int csrno, /* Machine constants */ -#define M_MODE_INTERRUPTS (MIP_MSIP | MIP_MTIP | MIP_MEIP) -#define S_MODE_INTERRUPTS (MIP_SSIP | MIP_STIP | MIP_SEIP) -#define VS_MODE_INTERRUPTS (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP) -#define HS_MODE_INTERRUPTS (MIP_SGEIP | VS_MODE_INTERRUPTS) +#define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP)) +#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP)) +#define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)) +#define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS)) -static const target_ulong delegable_ints = S_MODE_INTERRUPTS | +static const uint64_t delegable_ints = S_MODE_INTERRUPTS | VS_MODE_INTERRUPTS; -static const target_ulong vs_delegable_ints = VS_MODE_INTERRUPTS; -static const target_ulong all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS | +static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS; +static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS | HS_MODE_INTERRUPTS; #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \ (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \ @@ -718,40 +754,107 @@ static RISCVException write_medeleg(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -static RISCVException read_mideleg(CPURISCVState *env, int csrno, - target_ulong *val) +static RISCVException rmw_mideleg64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) { - *val = env->mideleg; - return RISCV_EXCP_NONE; -} + uint64_t mask = wr_mask & delegable_ints; + + if (ret_val) { + *ret_val = env->mideleg; + } + + env->mideleg = (env->mideleg & ~mask) | (new_val & mask); -static RISCVException write_mideleg(CPURISCVState *env, int csrno, - target_ulong val) -{ - env->mideleg = (env->mideleg & ~delegable_ints) | (val & delegable_ints); if (riscv_has_ext(env, RVH)) { env->mideleg |= HS_MODE_INTERRUPTS; } + return RISCV_EXCP_NONE; } -static RISCVException read_mie(CPURISCVState *env, int csrno, - target_ulong *val) +static RISCVException rmw_mideleg(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) { - *val = env->mie; - return RISCV_EXCP_NONE; + uint64_t rval; + RISCVException ret; + + ret = rmw_mideleg64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; } -static RISCVException write_mie(CPURISCVState *env, int csrno, - target_ulong val) +static RISCVException rmw_midelegh(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, + target_ulong wr_mask) { - env->mie = (env->mie & ~all_ints) | (val & all_ints); + uint64_t rval; + RISCVException ret; + + ret = rmw_mideleg64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + + return ret; +} + +static RISCVException rmw_mie64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) +{ + uint64_t mask = wr_mask & all_ints; + + if (ret_val) { + *ret_val = env->mie; + } + + env->mie = (env->mie & ~mask) | (new_val & mask); + if (!riscv_has_ext(env, RVH)) { - env->mie &= ~MIP_SGEIP; + env->mie &= ~((uint64_t)MIP_SGEIP); } + return RISCV_EXCP_NONE; } +static RISCVException rmw_mie(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; +} + +static RISCVException rmw_mieh(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_mie64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + + return ret; +} + static RISCVException read_mtvec(CPURISCVState *env, int csrno, target_ulong *val) { @@ -857,17 +960,17 @@ static RISCVException write_mtval(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -static RISCVException rmw_mip(CPURISCVState *env, int csrno, - target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +static RISCVException rmw_mip64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) { RISCVCPU *cpu = env_archcpu(env); /* Allow software control of delegable interrupts not claimed by hardware */ - target_ulong mask = write_mask & delegable_ints & ~env->miclaim; - uint32_t gin, old_mip; + uint64_t old_mip, mask = wr_mask & delegable_ints & ~env->miclaim; + uint32_t gin; if (mask) { - old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask)); + old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask)); } else { old_mip = env->mip; } @@ -877,13 +980,44 @@ static RISCVException rmw_mip(CPURISCVState *env, int csrno, old_mip |= (env->hgeip & ((target_ulong)1 << gin)) ? MIP_VSEIP : 0; } - if (ret_value) { - *ret_value = old_mip; + if (ret_val) { + *ret_val = old_mip; } return RISCV_EXCP_NONE; } +static RISCVException rmw_mip(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; +} + +static RISCVException rmw_miph(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_mip64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + + return ret; +} + /* Supervisor Trap Setup */ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno, Int128 *val) @@ -913,45 +1047,112 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno, return write_mstatus(env, CSR_MSTATUS, newval); } -static RISCVException read_vsie(CPURISCVState *env, int csrno, - target_ulong *val) +static RISCVException rmw_vsie64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) { - /* Shift the VS bits to their S bit location in vsie */ - *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1; - return RISCV_EXCP_NONE; + RISCVException ret; + uint64_t rval, vsbits, mask = env->hideleg & VS_MODE_INTERRUPTS; + + /* Bring VS-level bits to correct position */ + vsbits = new_val & (VS_MODE_INTERRUPTS >> 1); + new_val &= ~(VS_MODE_INTERRUPTS >> 1); + new_val |= vsbits << 1; + vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1); + wr_mask &= ~(VS_MODE_INTERRUPTS >> 1); + wr_mask |= vsbits << 1; + + ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask); + if (ret_val) { + rval &= mask; + vsbits = rval & VS_MODE_INTERRUPTS; + rval &= ~VS_MODE_INTERRUPTS; + *ret_val = rval | (vsbits >> 1); + } + + return ret; } -static RISCVException read_sie(CPURISCVState *env, int csrno, - target_ulong *val) +static RISCVException rmw_vsie(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) { - if (riscv_cpu_virt_enabled(env)) { - read_vsie(env, CSR_VSIE, val); - } else { - *val = env->mie & env->mideleg; + uint64_t rval; + RISCVException ret; + + ret = rmw_vsie64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; } - return RISCV_EXCP_NONE; + + return ret; } -static RISCVException write_vsie(CPURISCVState *env, int csrno, - target_ulong val) +static RISCVException rmw_vsieh(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) { - /* Shift the S bits to their VS bit location in mie */ - target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) | - ((val << 1) & env->hideleg & VS_MODE_INTERRUPTS); - return write_mie(env, CSR_MIE, newval); + uint64_t rval; + RISCVException ret; + + ret = rmw_vsie64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + + return ret; } -static int write_sie(CPURISCVState *env, int csrno, target_ulong val) +static RISCVException rmw_sie64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) { + RISCVException ret; + uint64_t mask = env->mideleg & S_MODE_INTERRUPTS; + if (riscv_cpu_virt_enabled(env)) { - write_vsie(env, CSR_VSIE, val); + ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask); } else { - target_ulong newval = (env->mie & ~S_MODE_INTERRUPTS) | - (val & S_MODE_INTERRUPTS); - write_mie(env, CSR_MIE, newval); + ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask); } - return RISCV_EXCP_NONE; + if (ret_val) { + *ret_val &= mask; + } + + return ret; +} + +static RISCVException rmw_sie(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_sie64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; +} + +static RISCVException rmw_sieh(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_sie64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + + return ret; } static RISCVException read_stvec(CPURISCVState *env, int csrno, @@ -1059,38 +1260,111 @@ static RISCVException write_stval(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +static RISCVException rmw_vsip64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) +{ + RISCVException ret; + uint64_t rval, vsbits, mask = env->hideleg & vsip_writable_mask; + + /* Bring VS-level bits to correct position */ + vsbits = new_val & (VS_MODE_INTERRUPTS >> 1); + new_val &= ~(VS_MODE_INTERRUPTS >> 1); + new_val |= vsbits << 1; + vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1); + wr_mask &= ~(VS_MODE_INTERRUPTS >> 1); + wr_mask |= vsbits << 1; + + ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask & mask); + if (ret_val) { + rval &= mask; + vsbits = rval & VS_MODE_INTERRUPTS; + rval &= ~VS_MODE_INTERRUPTS; + *ret_val = rval | (vsbits >> 1); + } + + return ret; +} + static RISCVException rmw_vsip(CPURISCVState *env, int csrno, - target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) { - /* Shift the S bits to their VS bit location in mip */ - int ret = rmw_mip(env, csrno, ret_value, new_value << 1, - (write_mask << 1) & vsip_writable_mask & env->hideleg); + uint64_t rval; + RISCVException ret; - if (ret_value) { - *ret_value &= VS_MODE_INTERRUPTS; - /* Shift the VS bits to their S bit location in vsip */ - *ret_value >>= 1; + ret = rmw_vsip64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; } + return ret; } -static RISCVException rmw_sip(CPURISCVState *env, int csrno, - target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) +static RISCVException rmw_vsiph(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) { - int ret; + uint64_t rval; + RISCVException ret; + + ret = rmw_vsip64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + + return ret; +} + +static RISCVException rmw_sip64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) +{ + RISCVException ret; + uint64_t mask = env->mideleg & sip_writable_mask; if (riscv_cpu_virt_enabled(env)) { - ret = rmw_vsip(env, CSR_VSIP, ret_value, new_value, write_mask); + ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask); } else { - ret = rmw_mip(env, csrno, ret_value, new_value, - write_mask & env->mideleg & sip_writable_mask); + ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask); } - if (ret_value) { - *ret_value &= env->mideleg & S_MODE_INTERRUPTS; + if (ret_val) { + *ret_val &= env->mideleg & S_MODE_INTERRUPTS; + } + + return ret; +} + +static RISCVException rmw_sip(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_sip64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; } + + return ret; +} + +static RISCVException rmw_siph(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_sip64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + return ret; } @@ -1185,30 +1459,94 @@ static RISCVException write_hedeleg(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -static RISCVException read_hideleg(CPURISCVState *env, int csrno, - target_ulong *val) +static RISCVException rmw_hideleg64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) { - *val = env->hideleg; + uint64_t mask = wr_mask & vs_delegable_ints; + + if (ret_val) { + *ret_val = env->hideleg & vs_delegable_ints; + } + + env->hideleg = (env->hideleg & ~mask) | (new_val & mask); return RISCV_EXCP_NONE; } -static RISCVException write_hideleg(CPURISCVState *env, int csrno, - target_ulong val) +static RISCVException rmw_hideleg(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) { - env->hideleg = val & vs_delegable_ints; - return RISCV_EXCP_NONE; + uint64_t rval; + RISCVException ret; + + ret = rmw_hideleg64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; +} + +static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_hideleg64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + + return ret; +} + +static RISCVException rmw_hvip64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) +{ + RISCVException ret; + + ret = rmw_mip64(env, csrno, ret_val, new_val, + wr_mask & hvip_writable_mask); + if (ret_val) { + *ret_val &= VS_MODE_INTERRUPTS; + } + + return ret; } static RISCVException rmw_hvip(CPURISCVState *env, int csrno, - target_ulong *ret_value, - target_ulong new_value, target_ulong write_mask) + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) { - int ret = rmw_mip(env, csrno, ret_value, new_value, - write_mask & hvip_writable_mask); + uint64_t rval; + RISCVException ret; - if (ret_value) { - *ret_value &= VS_MODE_INTERRUPTS; + ret = rmw_hvip64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; +} + +static RISCVException rmw_hviph(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_hvip64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; } + return ret; } @@ -1225,18 +1563,19 @@ static RISCVException rmw_hip(CPURISCVState *env, int csrno, return ret; } -static RISCVException read_hie(CPURISCVState *env, int csrno, - target_ulong *val) +static RISCVException rmw_hie(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) { - *val = env->mie & HS_MODE_INTERRUPTS; - return RISCV_EXCP_NONE; -} + uint64_t rval; + RISCVException ret; -static RISCVException write_hie(CPURISCVState *env, int csrno, - target_ulong val) -{ - target_ulong newval = (env->mie & ~HS_MODE_INTERRUPTS) | (val & HS_MODE_INTERRUPTS); - return write_mie(env, CSR_MIE, newval); + ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & HS_MODE_INTERRUPTS); + if (ret_val) { + *ret_val = rval & HS_MODE_INTERRUPTS; + } + + return ret; } static RISCVException read_hcounteren(CPURISCVState *env, int csrno, @@ -2050,9 +2389,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { read_mstatus_i128 }, [CSR_MISA] = { "misa", any, read_misa, write_misa, NULL, read_misa_i128 }, - [CSR_MIDELEG] = { "mideleg", any, read_mideleg, write_mideleg }, + [CSR_MIDELEG] = { "mideleg", any, NULL, NULL, rmw_mideleg }, [CSR_MEDELEG] = { "medeleg", any, read_medeleg, write_medeleg }, - [CSR_MIE] = { "mie", any, read_mie, write_mie }, + [CSR_MIE] = { "mie", any, NULL, NULL, rmw_mie }, [CSR_MTVEC] = { "mtvec", any, read_mtvec, write_mtvec }, [CSR_MCOUNTEREN] = { "mcounteren", any, read_mcounteren, write_mcounteren }, @@ -2066,10 +2405,15 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval }, [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip }, + /* Machine-Level High-Half CSRs (AIA) */ + [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh }, + [CSR_MIEH] = { "mieh", aia_any32, NULL, NULL, rmw_mieh }, + [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph }, + /* Supervisor Trap Setup */ [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL, read_sstatus_i128 }, - [CSR_SIE] = { "sie", smode, read_sie, write_sie }, + [CSR_SIE] = { "sie", smode, NULL, NULL, rmw_sie }, [CSR_STVEC] = { "stvec", smode, read_stvec, write_stvec }, [CSR_SCOUNTEREN] = { "scounteren", smode, read_scounteren, write_scounteren }, @@ -2084,12 +2428,16 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Supervisor Protection and Translation */ [CSR_SATP] = { "satp", smode, read_satp, write_satp }, + /* Supervisor-Level High-Half CSRs (AIA) */ + [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh }, + [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph }, + [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus }, [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg }, - [CSR_HIDELEG] = { "hideleg", hmode, read_hideleg, write_hideleg }, + [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg }, [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip }, [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip }, - [CSR_HIE] = { "hie", hmode, read_hie, write_hie }, + [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie }, [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren }, [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie }, [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval }, @@ -2101,7 +2449,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus }, [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip }, - [CSR_VSIE] = { "vsie", hmode, read_vsie, write_vsie }, + [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie }, [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec }, [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch }, [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc }, @@ -2112,6 +2460,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2 }, [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst }, + /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */ + [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh }, + [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph }, + [CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh }, + [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph }, + /* Physical Memory Protection */ [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg }, [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg }, diff --git a/target/riscv/machine.c b/target/riscv/machine.c index bae4f69725..99f932be9c 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -84,7 +84,7 @@ static const VMStateDescription vmstate_hyper = { .fields = (VMStateField[]) { VMSTATE_UINTTL(env.hstatus, RISCVCPU), VMSTATE_UINTTL(env.hedeleg, RISCVCPU), - VMSTATE_UINTTL(env.hideleg, RISCVCPU), + VMSTATE_UINT64(env.hideleg, RISCVCPU), VMSTATE_UINTTL(env.hcounteren, RISCVCPU), VMSTATE_UINTTL(env.htval, RISCVCPU), VMSTATE_UINTTL(env.htinst, RISCVCPU), @@ -215,10 +215,10 @@ const VMStateDescription vmstate_riscv_cpu = { VMSTATE_UINTTL(env.resetvec, RISCVCPU), VMSTATE_UINTTL(env.mhartid, RISCVCPU), VMSTATE_UINT64(env.mstatus, RISCVCPU), - VMSTATE_UINTTL(env.mip, RISCVCPU), - VMSTATE_UINT32(env.miclaim, RISCVCPU), - VMSTATE_UINTTL(env.mie, RISCVCPU), - VMSTATE_UINTTL(env.mideleg, RISCVCPU), + VMSTATE_UINT64(env.mip, RISCVCPU), + VMSTATE_UINT64(env.miclaim, RISCVCPU), + VMSTATE_UINT64(env.mie, RISCVCPU), + VMSTATE_UINT64(env.mideleg, RISCVCPU), VMSTATE_UINTTL(env.satp, RISCVCPU), VMSTATE_UINTTL(env.stval, RISCVCPU), VMSTATE_UINTTL(env.medeleg, RISCVCPU), From patchwork Mon Jan 17 13:28:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715446 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id D7837C433EF for ; Mon, 17 Jan 2022 14:16:49 +0000 (UTC) Received: from localhost ([::1]:57292 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9SoS-00022X-Pq for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:16:48 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38854) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5T-0001Mk-NI for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:20 -0500 Received: from [2607:f8b0:4864:20::42f] (port=39574 helo=mail-pf1-x42f.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5A-0000iA-RQ for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:14 -0500 Received: by mail-pf1-x42f.google.com with SMTP id f144so9447713pfa.6 for ; Mon, 17 Jan 2022 05:30:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pJywUDyiV0TiiPTTsFZ1k+iKTYkcWX2yjf8//u9zbLg=; b=hj1dxqgYFu4tCg9KTu/sZHzqUnXtvxJLF0PXusiXC4k0hZlX5FvdJcSxbn8y1mDYZF mzRYOI3A2OknhnDxs7MWDVBFEMsFxsdlyM5HgdQ0EYOfv5nfadXtNyy8O8fdNtvudJVH 3PevP0iR9zMT35iPnc26Tv5caeZYblrclKyhYFfkAMEYeQBUJn7pJw4QHWHsS4PpwQEd m8tdUj2SToQWszdwbtW42DVubKa+AEXeMd2v848oTsBv+lOiSoIj1P8qCTJB115dgYUm Pr9cOwgRCbFSuiLXBdL8xdyDpJ7dhkDC3AqfwQIYQKgQMOsCmgwVT2Wg1E86n/VE4jV4 1pyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pJywUDyiV0TiiPTTsFZ1k+iKTYkcWX2yjf8//u9zbLg=; b=op4jSaw1Wvrhs2PRX7xnyvKoEX2ElSzqSmAzZU9rY4RGZW3fNiT9S/jNCy/huubs/D x+TUDtLoWtxVaAQ0QVKA+HT0vq8rJl9oxMcD9R/EyVBefd+HduCC+j3sr5Pb9zyJFgbV Mb9IXyq9KVewvh87wkB1QepVZFrVQrYI0ni7Bgh7Z6WdhxMzsOqSiCYSiwIsUf8KuHDk NUaatCuZNk2idSegHMh1950SoxTxPs7S2s1Sbpvt4pI7qZzBRMyTTfnKBZVpdwQhU4zV n0yUHq5JLA4Yi3NN0mIXW6q+5Ly/F7EgtZSRtot/7B03+fDtFFKKO3c+FkULz/hXDWI0 1UNQ== X-Gm-Message-State: AOAM5335CK5azlbslidTy+TvAzvRiBKHjj3fP8i92RBblUxXShl50A1A jMLYSX2OWquZ4CfsHXp47oqC0w== X-Google-Smtp-Source: ABdhPJykwld0eMorPLZ124XXhdIU9ffGmrn9qABD43j9Ii7lJRqntUtorsQXqZPti1vVW+N36SMCMg== X-Received: by 2002:a63:920f:: with SMTP id o15mr19241111pgd.510.1642426199547; Mon, 17 Jan 2022 05:29:59 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:29:58 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 11/23] target/riscv: Implement AIA hvictl and hviprioX CSRs Date: Mon, 17 Jan 2022 18:58:14 +0530 Message-Id: <20220117132826.426418-12-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::42f (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::42f; envelope-from=anup@brainfault.org; helo=mail-pf1-x42f.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The AIA hvictl and hviprioX CSRs allow hypervisor to control interrupts visible at VS-level. This patch implements AIA hvictl and hviprioX CSRs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu.h | 2 + target/riscv/csr.c | 126 +++++++++++++++++++++++++++++++++++++++++ target/riscv/machine.c | 2 + 3 files changed, 130 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index a141686b58..d09abc3654 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -207,6 +207,7 @@ struct CPURISCVState { uint64_t htimedelta; /* Hypervisor controlled virtual interrupt priorities */ + target_ulong hvictl; uint8_t hviprio[64]; /* Upper 64-bits of 128-bit CSRs */ @@ -488,6 +489,7 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env) return env->misa_mxl; } #endif +#define riscv_cpu_mxl_bits(env) (1UL << (4 + riscv_cpu_mxl(env))) /* * Encode LMUL to lmul as follows: diff --git a/target/riscv/csr.c b/target/riscv/csr.c index cab02a48e5..f0d8cb097b 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -230,6 +230,15 @@ static RISCVException pointer_masking(CPURISCVState *env, int csrno) return RISCV_EXCP_ILLEGAL_INST; } +static int aia_hmode(CPURISCVState *env, int csrno) +{ + if (!riscv_feature(env, RISCV_FEATURE_AIA)) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return hmode(env, csrno); +} + static int aia_hmode32(CPURISCVState *env, int csrno) { if (!riscv_feature(env, RISCV_FEATURE_AIA)) { @@ -1112,6 +1121,9 @@ static RISCVException rmw_sie64(CPURISCVState *env, int csrno, uint64_t mask = env->mideleg & S_MODE_INTERRUPTS; if (riscv_cpu_virt_enabled(env)) { + if (env->hvictl & HVICTL_VTI) { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask); } else { ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask); @@ -1325,6 +1337,9 @@ static RISCVException rmw_sip64(CPURISCVState *env, int csrno, uint64_t mask = env->mideleg & sip_writable_mask; if (riscv_cpu_virt_enabled(env)) { + if (env->hvictl & HVICTL_VTI) { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } ret = rmw_vsip64(env, CSR_VSIP, ret_val, new_val, wr_mask); } else { ret = rmw_mip64(env, csrno, ret_val, new_val, wr_mask & mask); @@ -1711,6 +1726,110 @@ static RISCVException write_htimedeltah(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +static int read_hvictl(CPURISCVState *env, int csrno, target_ulong *val) +{ + *val = env->hvictl; + return RISCV_EXCP_NONE; +} + +static int write_hvictl(CPURISCVState *env, int csrno, target_ulong val) +{ + env->hvictl = val & HVICTL_VALID_MASK; + return RISCV_EXCP_NONE; +} + +static int read_hvipriox(CPURISCVState *env, int first_index, + uint8_t *iprio, target_ulong *val) +{ + int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32); + + /* First index has to be a multiple of number of irqs per register */ + if (first_index % num_irqs) { + return (riscv_cpu_virt_enabled(env)) ? + RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST; + } + + /* Fill-up return value */ + *val = 0; + for (i = 0; i < num_irqs; i++) { + if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) { + continue; + } + if (rdzero) { + continue; + } + *val |= ((target_ulong)iprio[irq]) << (i * 8); + } + + return RISCV_EXCP_NONE; +} + +static int write_hvipriox(CPURISCVState *env, int first_index, + uint8_t *iprio, target_ulong val) +{ + int i, irq, rdzero, num_irqs = 4 * (riscv_cpu_mxl_bits(env) / 32); + + /* First index has to be a multiple of number of irqs per register */ + if (first_index % num_irqs) { + return (riscv_cpu_virt_enabled(env)) ? + RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST; + } + + /* Fill-up priority arrary */ + for (i = 0; i < num_irqs; i++) { + if (riscv_cpu_hviprio_index2irq(first_index + i, &irq, &rdzero)) { + continue; + } + if (rdzero) { + iprio[irq] = 0; + } else { + iprio[irq] = (val >> (i * 8)) & 0xff; + } + } + + return RISCV_EXCP_NONE; +} + +static int read_hviprio1(CPURISCVState *env, int csrno, target_ulong *val) +{ + return read_hvipriox(env, 0, env->hviprio, val); +} + +static int write_hviprio1(CPURISCVState *env, int csrno, target_ulong val) +{ + return write_hvipriox(env, 0, env->hviprio, val); +} + +static int read_hviprio1h(CPURISCVState *env, int csrno, target_ulong *val) +{ + return read_hvipriox(env, 4, env->hviprio, val); +} + +static int write_hviprio1h(CPURISCVState *env, int csrno, target_ulong val) +{ + return write_hvipriox(env, 4, env->hviprio, val); +} + +static int read_hviprio2(CPURISCVState *env, int csrno, target_ulong *val) +{ + return read_hvipriox(env, 8, env->hviprio, val); +} + +static int write_hviprio2(CPURISCVState *env, int csrno, target_ulong val) +{ + return write_hvipriox(env, 8, env->hviprio, val); +} + +static int read_hviprio2h(CPURISCVState *env, int csrno, target_ulong *val) +{ + return read_hvipriox(env, 12, env->hviprio, val); +} + +static int write_hviprio2h(CPURISCVState *env, int csrno, target_ulong val) +{ + return write_hvipriox(env, 12, env->hviprio, val); +} + /* Virtual CSR Registers */ static RISCVException read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val) @@ -2460,9 +2579,16 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2 }, [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst }, + /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */ + [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl, write_hvictl }, + [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 }, + [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 }, + /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */ [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh }, [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph }, + [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, write_hviprio1h }, + [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h, write_hviprio2h }, [CSR_VSIEH] = { "vsieh", aia_hmode32, NULL, NULL, rmw_vsieh }, [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph }, diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 99f932be9c..be6af2bbf1 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -92,6 +92,8 @@ static const VMStateDescription vmstate_hyper = { VMSTATE_UINTTL(env.hgeie, RISCVCPU), VMSTATE_UINTTL(env.hgeip, RISCVCPU), VMSTATE_UINT64(env.htimedelta, RISCVCPU), + + VMSTATE_UINTTL(env.hvictl, RISCVCPU), VMSTATE_UINT8_ARRAY(env.hviprio, RISCVCPU, 64), VMSTATE_UINT64(env.vsstatus, RISCVCPU), From patchwork Mon Jan 17 13:28:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715534 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 14522C433F5 for ; Mon, 17 Jan 2022 15:17:09 +0000 (UTC) Received: from localhost ([::1]:38352 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9Tkq-0006OV-Nj for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 10:17:08 -0500 Received: from eggs.gnu.org ([209.51.188.92]:40490) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9SB0-0005IN-SV for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:36:06 -0500 Received: from [2607:f8b0:4864:20::929] (port=37695 helo=mail-ua1-x929.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9SAq-00023p-ED for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:35:55 -0500 Received: by mail-ua1-x929.google.com with SMTP id h28so5294258uax.4 for ; Mon, 17 Jan 2022 05:35:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3nsDPgbxXT0RftBOVWKLNr91iXQOw4zty79cR5/Fa/E=; b=JWZHJ9gi2nRZXcv1ifovMY+zJwhn1Lt2FznCkiXnpk+1OkZQlQuxe8EqC3zYTJXmea ok9O2diCD51GagOieuT/7WLTRo8UxV1lEFLUbuGrOWqcWKUPUC3aXoaQd+mqQ4YLs3Ea 0MfWz8vEPSRAZ74dKF5LZGIIeg0ry+8mGyNX5+cGTQQw3uKm9ZfSx/2nGVbUPimZ6XQt 4Ilm95wq23UiNWP0jtuMKQ2nHN4+tpMSddufAeinvWvNMhCWWdcXqqYAAETX1XkS8bPa uerAzAe6LpKaalyHTTQlZv7lMc0iXgxBBA12HQ4qqS0gfwZgcesFxd4ny5sY41Tv3JAZ sCnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3nsDPgbxXT0RftBOVWKLNr91iXQOw4zty79cR5/Fa/E=; b=CQCzSMDdWK4fJyayJfCB5zQvxPm4K5lbKlXruJs16Tz0bLxDu0xm7gKdiKeXzHlOYK v+Y2qqD8t2HYHBOW+LRHRNIqjgKv/1rW20VbP5Y4/NKAmYjDeJ4aUqYZcwPrPPDMezVQ xZts9KOuXAcIBfqAulov/mk4RyiU9rpwG2MuKiX/AQvK/nmYWjeFklWgNCIZC2vXvjye Jti7jmTfB4yeZNdKVyptb6TAem6Ajpmcap8FWFhs7qAd7/J9A9mwG36u9YdtoD7Z3AgT YgDqBbNpt32aB/ukNpdGMV9NR/KiETlk0Sc1i6S3YGKYAWnd7UWnOtK/DM2nAzF7W8aQ F3Dg== X-Gm-Message-State: AOAM531G8Ms48Kiwn3tamPdgz2UgdmH9nrfGxfUVJ5CrIek3DxH/EklA PEarBjw/lWuxYw+3yr7BE0+XpzcU8OW+XA== X-Google-Smtp-Source: ABdhPJwV+iOf/oPXQi289mF3/UHgVUEo4hLskHAqB4SjYNYnHS+YjWsaPsuBZ2XFvsCRbSGz07zQ9A== X-Received: by 2002:a17:903:11c3:b0:14a:58c4:f34c with SMTP id q3-20020a17090311c300b0014a58c4f34cmr22119295plh.151.1642426203487; Mon, 17 Jan 2022 05:30:03 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.29.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:02 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 12/23] target/riscv: Implement AIA interrupt filtering CSRs Date: Mon, 17 Jan 2022 18:58:15 +0530 Message-Id: <20220117132826.426418-13-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::929 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::929; envelope-from=anup@brainfault.org; helo=mail-ua1-x929.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The AIA specificaiton adds interrupt filtering support for M-mode and HS-mode. Using AIA interrupt filtering M-mode and H-mode can take local interrupt 13 or above and selectively inject same local interrupt to lower privilege modes. At the moment, we don't have any local interrupts above 12 so we add dummy implementation (i.e. read zero and ignore write) of AIA interrupt filtering CSRs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/csr.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index f0d8cb097b..d018cbae72 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -154,6 +154,15 @@ static RISCVException any32(CPURISCVState *env, int csrno) } +static int aia_any(CPURISCVState *env, int csrno) +{ + if (!riscv_feature(env, RISCV_FEATURE_AIA)) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return any(env, csrno); +} + static int aia_any32(CPURISCVState *env, int csrno) { if (!riscv_feature(env, RISCV_FEATURE_AIA)) { @@ -553,6 +562,12 @@ static RISCVException read_zero(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +static RISCVException write_ignore(CPURISCVState *env, int csrno, + target_ulong val) +{ + return RISCV_EXCP_NONE; +} + static RISCVException read_mhartid(CPURISCVState *env, int csrno, target_ulong *val) { @@ -2524,9 +2539,15 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval }, [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip }, + /* Virtual Interrupts for Supervisor Level (AIA) */ + [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore }, + [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore }, + /* Machine-Level High-Half CSRs (AIA) */ [CSR_MIDELEGH] = { "midelegh", aia_any32, NULL, NULL, rmw_midelegh }, [CSR_MIEH] = { "mieh", aia_any32, NULL, NULL, rmw_mieh }, + [CSR_MVIENH] = { "mvienh", aia_any32, read_zero, write_ignore }, + [CSR_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore }, [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph }, /* Supervisor Trap Setup */ @@ -2580,12 +2601,14 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst }, /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */ + [CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore }, [CSR_HVICTL] = { "hvictl", aia_hmode, read_hvictl, write_hvictl }, [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 }, [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 }, /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */ [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh }, + [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, write_ignore }, [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph }, [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, write_hviprio1h }, [CSR_HVIPRIO2H] = { "hviprio2h", aia_hmode32, read_hviprio2h, write_hviprio2h }, From patchwork Mon Jan 17 13:28:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715493 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 1D80EC433EF for ; Mon, 17 Jan 2022 14:42:20 +0000 (UTC) Received: from localhost ([::1]:35490 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9TD7-0007aE-VV for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:42:18 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38856) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5T-0001Ml-NL for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:20 -0500 Received: from [2607:f8b0:4864:20::629] (port=37386 helo=mail-pl1-x629.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5N-0000w2-Rl for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:16 -0500 Received: by mail-pl1-x629.google.com with SMTP id n11so19280819plf.4 for ; Mon, 17 Jan 2022 05:30:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KTfk3DmbikzaVS0b0VI0kpffQBFqqD7zkkReLT20zDw=; b=rQGkqXsHmexJOwR4o1Hlk28gvsqB3R1ZSWWZ4yjHWbAe8Y1vA2ge4FSfKgGf0D+Nlc jcWJr7xJ6aJL6YIFMlWiY6Qa4YYXP/kHHL09FcZJCpDka/iB6kn/WIH3kK3hGk7bmYAy NMT1tkYu34Rg/Q/lF5+NGimo2/0Arw2EAnoWRjxLeeH5j8MzLD6WsQZcdZRbSPBilJ9v YnCPTRG/f/2Mt69tufJIVYptlrAwEFOjDSUArk766z8nOvUwC5SooX/Kc4fs5AjDmKp3 LDNynZYOUa2neT3T94mCY7cLh7r8wX+fRoPBZuenbNqL43IXg57yyHn/COq7DWJHKUFR tFYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KTfk3DmbikzaVS0b0VI0kpffQBFqqD7zkkReLT20zDw=; b=FKMAyGXewl8sVwQesRxd20ztiKpYdmbeivlHklwAT342vDovE/CV5/zYVVJedINrpW 727AHSEIK+uQfZODbRWs/AXSC2DdwAzcy5v4vqtbiGUB9dztnfvagNHLAiGktcmuTpL8 M1edRJE89QTE48Hezdcy00ZySb3Gqqhf6bSS0d5ngd+C7C8ecmGNMiq2JtoWXU9wyFCe 0izOqNMtMRt91uhXUExy6cZbVZsu/cPRKsk0+nKfSXCB0nOzDxLTI9xg5nEHJEU11r05 O2pi9rgzqea0YuPgWGOfDYTw5fdEmu3E+PKifrYstc9LyaXMNBjmXkl03PCbb8P6dIwp piFg== X-Gm-Message-State: AOAM530r9MukMWJxR4UzcN3EAzhEeFNIqGYLjC3BmbhJPXN84xTKBy/i 0G7eiuJEGrKIlIe+X67yf8fX3g== X-Google-Smtp-Source: ABdhPJymj2i9SN59Sc9E0i5atMX94LWenCmEGABR2jw73jU75H/iBAHBfb38zsEWQi4RRh3tSyJwcg== X-Received: by 2002:a17:902:b204:b0:149:d1ca:4e57 with SMTP id t4-20020a170902b20400b00149d1ca4e57mr22875819plr.126.1642426208629; Mon, 17 Jan 2022 05:30:08 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:07 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 13/23] target/riscv: Implement AIA mtopi, stopi, and vstopi CSRs Date: Mon, 17 Jan 2022 18:58:16 +0530 Message-Id: <20220117132826.426418-14-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::629 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::629; envelope-from=anup@brainfault.org; helo=mail-pl1-x629.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The AIA specification introduces new [m|s|vs]topi CSRs for reporting pending local IRQ number and associated IRQ priority. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Frank Chang --- target/riscv/csr.c | 156 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index d018cbae72..e92a1915a8 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -190,6 +190,15 @@ static int smode32(CPURISCVState *env, int csrno) return smode(env, csrno); } +static int aia_smode(CPURISCVState *env, int csrno) +{ + if (!riscv_feature(env, RISCV_FEATURE_AIA)) { + return RISCV_EXCP_ILLEGAL_INST; + } + + return smode(env, csrno); +} + static int aia_smode32(CPURISCVState *env, int csrno) { if (!riscv_feature(env, RISCV_FEATURE_AIA)) { @@ -502,6 +511,8 @@ static RISCVException read_timeh(CPURISCVState *env, int csrno, #define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)) #define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS)) +#define VSTOPI_NUM_SRCS 5 + static const uint64_t delegable_ints = S_MODE_INTERRUPTS | VS_MODE_INTERRUPTS; static const uint64_t vs_delegable_ints = VS_MODE_INTERRUPTS; @@ -879,6 +890,28 @@ static RISCVException rmw_mieh(CPURISCVState *env, int csrno, return ret; } +static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val) +{ + int irq; + uint8_t iprio; + + irq = riscv_cpu_mirq_pending(env); + if (irq <= 0 || irq > 63) { + *val = 0; + } else { + iprio = env->miprio[irq]; + if (!iprio) { + if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_M) { + iprio = IPRIO_MMAXIPRIO; + } + } + *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT; + *val |= iprio; + } + + return RISCV_EXCP_NONE; +} + static RISCVException read_mtvec(CPURISCVState *env, int csrno, target_ulong *val) { @@ -1448,6 +1481,120 @@ static RISCVException write_satp(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +static int read_vstopi(CPURISCVState *env, int csrno, target_ulong *val) +{ + int irq, ret; + target_ulong topei; + uint64_t vseip, vsgein; + uint32_t iid, iprio, hviid, hviprio, gein; + uint32_t s, scount = 0, siid[VSTOPI_NUM_SRCS], siprio[VSTOPI_NUM_SRCS]; + + gein = get_field(env->hstatus, HSTATUS_VGEIN); + hviid = get_field(env->hvictl, HVICTL_IID); + hviprio = get_field(env->hvictl, HVICTL_IPRIO); + + if (gein) { + vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; + vseip = env->mie & (env->mip | vsgein) & MIP_VSEIP; + if (gein <= env->geilen && vseip) { + siid[scount] = IRQ_S_EXT; + siprio[scount] = IPRIO_MMAXIPRIO + 1; + if (env->aia_ireg_rmw_fn[PRV_S]) { + /* + * Call machine specific IMSIC register emulation for + * reading TOPEI. + */ + ret = env->aia_ireg_rmw_fn[PRV_S]( + env->aia_ireg_rmw_fn_arg[PRV_S], + AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, PRV_S, true, gein, + riscv_cpu_mxl_bits(env)), + &topei, 0, 0); + if (!ret && topei) { + siprio[scount] = topei & IMSIC_TOPEI_IPRIO_MASK; + } + } + scount++; + } + } else { + if (hviid == IRQ_S_EXT && hviprio) { + siid[scount] = IRQ_S_EXT; + siprio[scount] = hviprio; + scount++; + } + } + + if (env->hvictl & HVICTL_VTI) { + if (hviid != IRQ_S_EXT) { + siid[scount] = hviid; + siprio[scount] = hviprio; + scount++; + } + } else { + irq = riscv_cpu_vsirq_pending(env); + if (irq != IRQ_S_EXT && 0 < irq && irq <= 63) { + siid[scount] = irq; + siprio[scount] = env->hviprio[irq]; + scount++; + } + } + + iid = 0; + iprio = UINT_MAX; + for (s = 0; s < scount; s++) { + if (siprio[s] < iprio) { + iid = siid[s]; + iprio = siprio[s]; + } + } + + if (iid) { + if (env->hvictl & HVICTL_IPRIOM) { + if (iprio > IPRIO_MMAXIPRIO) { + iprio = IPRIO_MMAXIPRIO; + } + if (!iprio) { + if (riscv_cpu_default_priority(iid) > IPRIO_DEFAULT_S) { + iprio = IPRIO_MMAXIPRIO; + } + } + } else { + iprio = 1; + } + } else { + iprio = 0; + } + + *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT; + *val |= iprio; + return RISCV_EXCP_NONE; +} + +static int read_stopi(CPURISCVState *env, int csrno, target_ulong *val) +{ + int irq; + uint8_t iprio; + + if (riscv_cpu_virt_enabled(env)) { + return read_vstopi(env, CSR_VSTOPI, val); + } + + irq = riscv_cpu_sirq_pending(env); + if (irq <= 0 || irq > 63) { + *val = 0; + } else { + iprio = env->siprio[irq]; + if (!iprio) { + if (riscv_cpu_default_priority(irq) > IPRIO_DEFAULT_S) { + iprio = IPRIO_MMAXIPRIO; + } + } + *val = (irq & TOPI_IID_MASK) << TOPI_IID_SHIFT; + *val |= iprio; + } + + return RISCV_EXCP_NONE; +} + /* Hypervisor Extensions */ static RISCVException read_hstatus(CPURISCVState *env, int csrno, target_ulong *val) @@ -2539,6 +2686,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval }, [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip }, + /* Machine-Level Interrupts (AIA) */ + [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi }, + /* Virtual Interrupts for Supervisor Level (AIA) */ [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore }, [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore }, @@ -2568,6 +2718,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Supervisor Protection and Translation */ [CSR_SATP] = { "satp", smode, read_satp, write_satp }, + /* Supervisor-Level Interrupts (AIA) */ + [CSR_STOPI] = { "stopi", aia_smode, read_stopi }, + /* Supervisor-Level High-Half CSRs (AIA) */ [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh }, [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph }, @@ -2606,6 +2759,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 }, [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 }, + /* VS-Level Interrupts (H-extension with AIA) */ + [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi }, + /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */ [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh }, [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, write_ignore }, From patchwork Mon Jan 17 13:28:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715445 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 0EE34C433F5 for ; Mon, 17 Jan 2022 14:16:40 +0000 (UTC) Received: from localhost ([::1]:56358 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9SoJ-0001ZQ-Pu for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:16:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38868) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5U-0001Mo-4p for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:23 -0500 Received: from [2607:f8b0:4864:20::62c] (port=45884 helo=mail-pl1-x62c.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5O-0000wU-Gl for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:19 -0500 Received: by mail-pl1-x62c.google.com with SMTP id g5so21185483plo.12 for ; Mon, 17 Jan 2022 05:30:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hQY+m9fuC7vMypurkGGjBusC5p3WfUoDr2Ct0YoQ1kY=; b=2rzSNHFav0xYBNFe3YIQdhFr4DsibwIGh+MULxXvsqqhoB5Vm+D6BN6+Rev9TT5gTo 6p2gWbLJZ6BwR+k659mx2VLNJh2H7tZkBxWC6Kmf0A9VW++hQoO7Www633EWZKggq2Vl Matcg1KUAnHPxpA+rAuVeZ0kVxncsvIMl2u3UjV7zBtyDyA8Qt2kfGmYRPkZD40m+0GP oC2Sv/4h14nMF5dFysFFHhIqsF8bqKgioAA7RrwzTQnjCzQjXUNQlcAldUgpaH+e1Alr rdlVmpnicWe0S3XkA33bYN95VRy28JXLjGw+yCNiA6E302+5zE3oLvLhoHDWMco3ei+z oDow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=hQY+m9fuC7vMypurkGGjBusC5p3WfUoDr2Ct0YoQ1kY=; b=mO05typ2j3TKgET3fhnAcGLsBMmieNj7HcQirK1zMTmCwJY5MIn/jZ8NsFhdfAxy3S bSQuZwGJJuF++OXl0HBOvI91ikC4dYXuKM3fQejSa/AQTzQ41gkbSoA1dp2Zj4W5cmMy p6p09J3gGe5uDlhAlOHG7anlx887LttH5QZKe1ewg43wST305EMLXaLU2C52C1hlgf5m t8ed9T4gU7GygpSVKFrq0EY45p6oXgYvZkzgOTs5i/XNUysMzKUrwRhX4pv/O685yDyj cyoTwLBSHxDPzcORitahPXPtJglCMdgPB8Us0JWb455JVgUIjwnpWBNKpT85xZnejzZg PJrw== X-Gm-Message-State: AOAM532hPOGwClbxUzyNvPjfcsFuDbEF9tF2NfAGVZtwqgepSMn3BEuT GkFNxr+Gs6m7JhkktoND5bUuAA== X-Google-Smtp-Source: ABdhPJxO/r0p4AkhAY6Dnwmf94XMZPVhkTTWZUIYzthCzkaYr44pXsmxStFxevTYc/Vn2PVHDNPgEQ== X-Received: by 2002:a17:90b:4b4c:: with SMTP id mi12mr23072144pjb.85.1642426212866; Mon, 17 Jan 2022 05:30:12 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:11 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 14/23] target/riscv: Implement AIA xiselect and xireg CSRs Date: Mon, 17 Jan 2022 18:58:17 +0530 Message-Id: <20220117132826.426418-15-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::62c (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::62c; envelope-from=anup@brainfault.org; helo=mail-pl1-x62c.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The AIA specification defines [m|s|vs]iselect and [m|s|vs]ireg CSRs which allow indirect access to interrupt priority arrays and per-HART IMSIC registers. This patch implements AIA xiselect and xireg CSRs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Frank Chang --- target/riscv/cpu.h | 7 ++ target/riscv/csr.c | 175 +++++++++++++++++++++++++++++++++++++++++ target/riscv/machine.c | 3 + 3 files changed, 185 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d09abc3654..7b4cf19350 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -194,6 +194,10 @@ struct CPURISCVState { uint8_t miprio[64]; uint8_t siprio[64]; + /* AIA CSRs */ + target_ulong miselect; + target_ulong siselect; + /* Hypervisor CSRs */ target_ulong hstatus; target_ulong hedeleg; @@ -227,6 +231,9 @@ struct CPURISCVState { target_ulong vstval; target_ulong vsatp; + /* AIA VS-mode CSRs */ + target_ulong vsiselect; + target_ulong mtval2; target_ulong mtinst; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index e92a1915a8..7a787d3a3f 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -912,6 +912,169 @@ static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val) return RISCV_EXCP_NONE; } +static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno) +{ + if (!riscv_cpu_virt_enabled(env)) { + return csrno; + } + + switch (csrno) { + case CSR_SISELECT: + return CSR_VSISELECT; + case CSR_SIREG: + return CSR_VSIREG; + default: + return csrno; + }; +} + +static int rmw_xiselect(CPURISCVState *env, int csrno, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + target_ulong *iselect; + + /* Translate CSR number for VS-mode */ + csrno = aia_xlate_vs_csrno(env, csrno); + + /* Find the iselect CSR based on CSR number */ + switch (csrno) { + case CSR_MISELECT: + iselect = &env->miselect; + break; + case CSR_SISELECT: + iselect = &env->siselect; + break; + case CSR_VSISELECT: + iselect = &env->vsiselect; + break; + default: + return RISCV_EXCP_ILLEGAL_INST; + }; + + if (val) { + *val = *iselect; + } + + wr_mask &= ISELECT_MASK; + if (wr_mask) { + *iselect = (*iselect & ~wr_mask) | (new_val & wr_mask); + } + + return RISCV_EXCP_NONE; +} + +static int rmw_iprio(target_ulong xlen, + target_ulong iselect, uint8_t *iprio, + target_ulong *val, target_ulong new_val, + target_ulong wr_mask, int ext_irq_no) +{ + int i, firq, nirqs; + target_ulong old_val; + + if (iselect < ISELECT_IPRIO0 || ISELECT_IPRIO15 < iselect) { + return -EINVAL; + } + if (xlen != 32 && iselect & 0x1) { + return -EINVAL; + } + + nirqs = 4 * (xlen / 32); + firq = ((iselect - ISELECT_IPRIO0) / (xlen / 32)) * (nirqs); + + old_val = 0; + for (i = 0; i < nirqs; i++) { + old_val |= ((target_ulong)iprio[firq + i]) << (IPRIO_IRQ_BITS * i); + } + + if (val) { + *val = old_val; + } + + if (wr_mask) { + new_val = (old_val & ~wr_mask) | (new_val & wr_mask); + for (i = 0; i < nirqs; i++) { + /* + * M-level and S-level external IRQ priority always read-only + * zero. This means default priority order is always preferred + * for M-level and S-level external IRQs. + */ + if ((firq + i) == ext_irq_no) { + continue; + } + iprio[firq + i] = (new_val >> (IPRIO_IRQ_BITS * i)) & 0xff; + } + } + + return 0; +} + +static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + bool virt; + uint8_t *iprio; + int ret = -EINVAL; + target_ulong priv, isel, vgein; + + /* Translate CSR number for VS-mode */ + csrno = aia_xlate_vs_csrno(env, csrno); + + /* Decode register details from CSR number */ + virt = false; + switch (csrno) { + case CSR_MIREG: + iprio = env->miprio; + isel = env->miselect; + priv = PRV_M; + break; + case CSR_SIREG: + iprio = env->siprio; + isel = env->siselect; + priv = PRV_S; + break; + case CSR_VSIREG: + iprio = env->hviprio; + isel = env->vsiselect; + priv = PRV_S; + virt = true; + break; + default: + goto done; + }; + + /* Find the selected guest interrupt file */ + vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0; + + if (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) { + /* Local interrupt priority registers not available for VS-mode */ + if (!virt) { + ret = rmw_iprio(riscv_cpu_mxl_bits(env), + isel, iprio, val, new_val, wr_mask, + (priv == PRV_M) ? IRQ_M_EXT : IRQ_S_EXT); + } + } else if (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST) { + /* IMSIC registers only available when machine implements it. */ + if (env->aia_ireg_rmw_fn[priv]) { + /* Selected guest interrupt file should not be zero */ + if (virt && (!vgein || env->geilen < vgein)) { + goto done; + } + /* Call machine specific IMSIC register emulation */ + ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv], + AIA_MAKE_IREG(isel, priv, virt, vgein, + riscv_cpu_mxl_bits(env)), + val, new_val, wr_mask); + } + } + +done: + if (ret) { + return (riscv_cpu_virt_enabled(env) && virt) ? + RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST; + } + return RISCV_EXCP_NONE; +} + static RISCVException read_mtvec(CPURISCVState *env, int csrno, target_ulong *val) { @@ -2686,6 +2849,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_MTVAL] = { "mtval", any, read_mtval, write_mtval }, [CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip }, + /* Machine-Level Window to Indirectly Accessed Registers (AIA) */ + [CSR_MISELECT] = { "miselect", aia_any, NULL, NULL, rmw_xiselect }, + [CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg }, + /* Machine-Level Interrupts (AIA) */ [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi }, @@ -2718,6 +2885,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Supervisor Protection and Translation */ [CSR_SATP] = { "satp", smode, read_satp, write_satp }, + /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */ + [CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect }, + [CSR_SIREG] = { "sireg", aia_smode, NULL, NULL, rmw_xireg }, + /* Supervisor-Level Interrupts (AIA) */ [CSR_STOPI] = { "stopi", aia_smode, read_stopi }, @@ -2759,6 +2930,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_HVIPRIO1] = { "hviprio1", aia_hmode, read_hviprio1, write_hviprio1 }, [CSR_HVIPRIO2] = { "hviprio2", aia_hmode, read_hviprio2, write_hviprio2 }, + /* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */ + [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL, rmw_xiselect }, + [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg }, + /* VS-Level Interrupts (H-extension with AIA) */ [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi }, diff --git a/target/riscv/machine.c b/target/riscv/machine.c index be6af2bbf1..b8269272d2 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -103,6 +103,7 @@ static const VMStateDescription vmstate_hyper = { VMSTATE_UINTTL(env.vscause, RISCVCPU), VMSTATE_UINTTL(env.vstval, RISCVCPU), VMSTATE_UINTTL(env.vsatp, RISCVCPU), + VMSTATE_UINTTL(env.vsiselect, RISCVCPU), VMSTATE_UINTTL(env.mtval2, RISCVCPU), VMSTATE_UINTTL(env.mtinst, RISCVCPU), @@ -231,6 +232,8 @@ const VMStateDescription vmstate_riscv_cpu = { VMSTATE_UINTTL(env.mepc, RISCVCPU), VMSTATE_UINTTL(env.mcause, RISCVCPU), VMSTATE_UINTTL(env.mtval, RISCVCPU), + VMSTATE_UINTTL(env.miselect, RISCVCPU), + VMSTATE_UINTTL(env.siselect, RISCVCPU), VMSTATE_UINTTL(env.scounteren, RISCVCPU), VMSTATE_UINTTL(env.mcounteren, RISCVCPU), VMSTATE_UINTTL(env.sscratch, RISCVCPU), From patchwork Mon Jan 17 13:28:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715496 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 9FCE0C433F5 for ; Mon, 17 Jan 2022 14:49:21 +0000 (UTC) Received: from localhost ([::1]:45206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9TJw-0005YX-Aa for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:49:20 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38908) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5W-0001NK-5t for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:24 -0500 Received: from [2607:f8b0:4864:20::629] (port=40560 helo=mail-pl1-x629.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5T-0000zA-93 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:21 -0500 Received: by mail-pl1-x629.google.com with SMTP id b3so12158921plc.7 for ; Mon, 17 Jan 2022 05:30:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SoX8hpwu94Gg/X7ao3T/GWOSkUY2xCeXA4rNASzVTmE=; b=f8+yxU2KUJJNN0qIvLcl0SaJldRjZfxRTwIWJ2k2f1vWAURHPL0qPRClpMEkoD5BEd jJQpDI21Q5AD0ErS4eYZE9Refdiw41mk35uakgt6i4Mcg+IjP/e9s2HGlOCSA8GZUgIj 9pU0wCFI+DlnLfEXZosWJt6FEoZ9wy+6IJ7g1aMO8/fc9VCkKP4OF/hibACOlgyuE0vS 6w8KNx/o+xg1BHBCIo7fHbRI+6n68lh32O6oirlvjjA6se4qERVT0rOms5jfvgYsNg6M 6BBdf5fFR/5HT2qJB2RG+t98UEcRAIXG7j8hVMEXx+b5tOZKgaoD5U5XAuRyvmmqc68I QGKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SoX8hpwu94Gg/X7ao3T/GWOSkUY2xCeXA4rNASzVTmE=; b=ZuJgr00wb4jwneN4h0qZvcsvX4XDK8Qbz4AHhlEfxMa+sE+84WjdApOW/8xDAb/KgG hfN260dyZV1KeE50s8827yCNA6tyGMRsr19e+uHYKqzbaEXR1jBRporOTPT8e8mr8GbW YWDGjmGPBVX5l47X6ZFxLLHbMIpqHsJ3MDIAAZea9eSrAiVwdmtfL25Jol3SJ163Ztpv YToskXKnMata7CawWSPKXZi56JI3xWmS1FpgOO1MxmiQ/l7iOk0luk7U9BpA/8DgkHNA KmCznx1+wXTt0/re2RJBxanhq7okAaQGI6CuIaS2l7AfJsBkgGo2vL7KZ1+QV1UnIUyM Qa4w== X-Gm-Message-State: AOAM530uAFEeYyFPbYGMX4u1SjxuVl6XwC0FQU1xNML9IoUinVbvKOvG AX6zWn+kDFa0+w+pIEZwAQ7S3g== X-Google-Smtp-Source: ABdhPJywTNkEex8bBnn5M0g8lB5DSzHYIuxk/o5n2N+tCRMDcWin6HyzhoYDdxTwqeU06PdDwG7OKQ== X-Received: by 2002:a17:90b:3905:: with SMTP id ob5mr6612544pjb.179.1642426216533; Mon, 17 Jan 2022 05:30:16 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:15 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 15/23] target/riscv: Implement AIA IMSIC interface CSRs Date: Mon, 17 Jan 2022 18:58:18 +0530 Message-Id: <20220117132826.426418-16-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::629 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::629; envelope-from=anup@brainfault.org; helo=mail-pl1-x629.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anup Patel , Bin Meng , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Atish Patra Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The AIA specification defines IMSIC interface CSRs for easy access to the per-HART IMSIC registers without using indirect xiselect and xireg CSRs. This patch implements the AIA IMSIC interface CSRs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Frank Chang --- target/riscv/csr.c | 203 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 7a787d3a3f..68e6009006 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -923,6 +923,16 @@ static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno) return CSR_VSISELECT; case CSR_SIREG: return CSR_VSIREG; + case CSR_SSETEIPNUM: + return CSR_VSSETEIPNUM; + case CSR_SCLREIPNUM: + return CSR_VSCLREIPNUM; + case CSR_SSETEIENUM: + return CSR_VSSETEIENUM; + case CSR_SCLREIENUM: + return CSR_VSCLREIENUM; + case CSR_STOPEI: + return CSR_VSTOPEI; default: return csrno; }; @@ -1075,6 +1085,178 @@ done: return RISCV_EXCP_NONE; } +static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + int ret = -EINVAL; + bool set, pend, virt; + target_ulong priv, isel, vgein, xlen, nval, wmask; + + /* Translate CSR number for VS-mode */ + csrno = aia_xlate_vs_csrno(env, csrno); + + /* Decode register details from CSR number */ + virt = set = pend = false; + switch (csrno) { + case CSR_MSETEIPNUM: + priv = PRV_M; + set = true; + pend = true; + break; + case CSR_MCLREIPNUM: + priv = PRV_M; + pend = true; + break; + case CSR_MSETEIENUM: + priv = PRV_M; + set = true; + break; + case CSR_MCLREIENUM: + priv = PRV_M; + break; + case CSR_SSETEIPNUM: + priv = PRV_S; + set = true; + pend = true; + break; + case CSR_SCLREIPNUM: + priv = PRV_S; + pend = true; + break; + case CSR_SSETEIENUM: + priv = PRV_S; + set = true; + break; + case CSR_SCLREIENUM: + priv = PRV_S; + break; + case CSR_VSSETEIPNUM: + priv = PRV_S; + virt = true; + set = true; + pend = true; + break; + case CSR_VSCLREIPNUM: + priv = PRV_S; + virt = true; + pend = true; + break; + case CSR_VSSETEIENUM: + priv = PRV_S; + virt = true; + set = true; + break; + case CSR_VSCLREIENUM: + priv = PRV_S; + virt = true; + break; + default: + goto done; + }; + + /* IMSIC CSRs only available when machine implements IMSIC. */ + if (!env->aia_ireg_rmw_fn[priv]) { + goto done; + } + + /* Find the selected guest interrupt file */ + vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0; + + /* Selected guest interrupt file should be valid */ + if (virt && (!vgein || env->geilen < vgein)) { + goto done; + } + + /* Set/Clear CSRs always read zero */ + if (val) { + *val = 0; + } + + if (wr_mask) { + /* Get interrupt number */ + new_val &= wr_mask; + + /* Find target interrupt pending/enable register */ + xlen = riscv_cpu_mxl_bits(env); + isel = (new_val / xlen); + isel *= (xlen / IMSIC_EIPx_BITS); + isel += (pend) ? ISELECT_IMSIC_EIP0 : ISELECT_IMSIC_EIE0; + + /* Find the interrupt bit to be set/clear */ + wmask = ((target_ulong)1) << (new_val % xlen); + nval = (set) ? wmask : 0; + + /* Call machine specific IMSIC register emulation */ + ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv], + AIA_MAKE_IREG(isel, priv, virt, + vgein, xlen), + NULL, nval, wmask); + } else { + ret = 0; + } + +done: + if (ret) { + return (riscv_cpu_virt_enabled(env) && virt) ? + RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST; + } + return RISCV_EXCP_NONE; +} + +static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + bool virt; + int ret = -EINVAL; + target_ulong priv, vgein; + + /* Translate CSR number for VS-mode */ + csrno = aia_xlate_vs_csrno(env, csrno); + + /* Decode register details from CSR number */ + virt = false; + switch (csrno) { + case CSR_MTOPEI: + priv = PRV_M; + break; + case CSR_STOPEI: + priv = PRV_S; + break; + case CSR_VSTOPEI: + priv = PRV_S; + virt = true; + break; + default: + goto done; + }; + + /* IMSIC CSRs only available when machine implements IMSIC. */ + if (!env->aia_ireg_rmw_fn[priv]) { + goto done; + } + + /* Find the selected guest interrupt file */ + vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0; + + /* Selected guest interrupt file should be valid */ + if (virt && (!vgein || env->geilen < vgein)) { + goto done; + } + + /* Call machine specific IMSIC register emulation for TOPEI */ + ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv], + AIA_MAKE_IREG(ISELECT_IMSIC_TOPEI, priv, virt, vgein, + riscv_cpu_mxl_bits(env)), + val, new_val, wr_mask); + +done: + if (ret) { + return (riscv_cpu_virt_enabled(env) && virt) ? + RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST; + } + return RISCV_EXCP_NONE; +} + static RISCVException read_mtvec(CPURISCVState *env, int csrno, target_ulong *val) { @@ -2856,6 +3038,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Machine-Level Interrupts (AIA) */ [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi }, + /* Machine-Level IMSIC Interface (AIA) */ + [CSR_MSETEIPNUM] = { "mseteipnum", aia_any, NULL, NULL, rmw_xsetclreinum }, + [CSR_MCLREIPNUM] = { "mclreipnum", aia_any, NULL, NULL, rmw_xsetclreinum }, + [CSR_MSETEIENUM] = { "mseteienum", aia_any, NULL, NULL, rmw_xsetclreinum }, + [CSR_MCLREIENUM] = { "mclreienum", aia_any, NULL, NULL, rmw_xsetclreinum }, + [CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei }, + /* Virtual Interrupts for Supervisor Level (AIA) */ [CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore }, [CSR_MVIP] = { "mvip", aia_any, read_zero, write_ignore }, @@ -2892,6 +3081,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Supervisor-Level Interrupts (AIA) */ [CSR_STOPI] = { "stopi", aia_smode, read_stopi }, + /* Supervisor-Level IMSIC Interface (AIA) */ + [CSR_SSETEIPNUM] = { "sseteipnum", aia_smode, NULL, NULL, rmw_xsetclreinum }, + [CSR_SCLREIPNUM] = { "sclreipnum", aia_smode, NULL, NULL, rmw_xsetclreinum }, + [CSR_SSETEIENUM] = { "sseteienum", aia_smode, NULL, NULL, rmw_xsetclreinum }, + [CSR_SCLREIENUM] = { "sclreienum", aia_smode, NULL, NULL, rmw_xsetclreinum }, + [CSR_STOPEI] = { "stopei", aia_smode, NULL, NULL, rmw_xtopei }, + /* Supervisor-Level High-Half CSRs (AIA) */ [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh }, [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph }, @@ -2937,6 +3133,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* VS-Level Interrupts (H-extension with AIA) */ [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi }, + /* VS-Level IMSIC Interface (H-extension with AIA) */ + [CSR_VSSETEIPNUM] = { "vsseteipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum }, + [CSR_VSCLREIPNUM] = { "vsclreipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum }, + [CSR_VSSETEIENUM] = { "vsseteienum", aia_hmode, NULL, NULL, rmw_xsetclreinum }, + [CSR_VSCLREIENUM] = { "vsclreienum", aia_hmode, NULL, NULL, rmw_xsetclreinum }, + [CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei }, + /* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */ [CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh }, [CSR_HVIENH] = { "hvienh", aia_hmode32, read_zero, write_ignore }, From patchwork Mon Jan 17 13:28:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715491 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id D885FC433EF for ; Mon, 17 Jan 2022 14:35:34 +0000 (UTC) Received: from localhost ([::1]:50670 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9T6b-0006yd-UZ for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:35:33 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38968) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5d-0001QN-H0 for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:30 -0500 Received: from [2607:f8b0:4864:20::1029] (port=53793 helo=mail-pj1-x1029.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5W-00012Y-2s for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:24 -0500 Received: by mail-pj1-x1029.google.com with SMTP id m13so20544031pji.3 for ; Mon, 17 Jan 2022 05:30:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=E5KywehhW+LFtSyAdk7dOMvOyCasUk5k/8EijDUesrA=; b=tgH9gvV2iv7HrcAPhTFo6vmyJt7EYdeFdsobxyC9g+LScFe3Bg7ZXha/a19TiMj3Qt Avw+uwi7En0vIRYE0IXwNF31bpAxWbpOkXEDCoMalclsSoABV0hAnQdK4laoxPApZeTg IZIfwyCjolJc7sasIh01B9Ut9huJKvKWtpJ6nRnWg6VtP4W3BlJaxiQ8KM2iH/4bUjZI MEecaDJwf6xTWoV84XmrHmr9E9h6f2zFjbw9IbUqGCQ2VjzoK69iEOSofIoN1LgocwaE g3ObRUESCs5iJgnl8hSkTW55gxHVrxFswPl5ZtDg0U5DLwBoyXQttcBD5xXIFd0yfcaY UkbQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=E5KywehhW+LFtSyAdk7dOMvOyCasUk5k/8EijDUesrA=; b=S/GSYJl0UO3Az97RsbEXa/MwABxQbYlTvE73YzLGduTqVTJWNnM79T9Q/EVbGN+/W2 WY1W3fsI40cQqXysy2lx31+++JnNBCby/EahrVJ6NBZQW5E1Kn5nmIyokCsIcdiOI64/ 31z4+XIw+E6DIo2cyHJws3rarYh8IkSKnjTkHjlVVQiWqyrG9S4tthAkORHhTlDPDtdO 7LrqXiH3bKt0aYM4P9PFAvCbZu4BrLmzo2bltKO7j/zkb+ls9WUDzYmqbPt1cL5jvadU XjIzDYKYMqRgLtOMk7VFYktPK40UGIy+NIK6qsPlTMwf65VGKlD2cjJIWafivFs9NflK 4YAw== X-Gm-Message-State: AOAM5330n852Yvw/F7VJl1wg/Y1orMRlmimNX9MRypg7Fdo2iivKD/3t 1+LjFL70TFEZIxfmorkSR58WcA== X-Google-Smtp-Source: ABdhPJwqZzB3amuPIz1FkyaatCIUeHr3Q5ZIaQ68Q7aHoq+9TvxRQqLwrBipVrTValJipycKOD3o5g== X-Received: by 2002:a17:90b:4b83:: with SMTP id lr3mr25830254pjb.59.1642426220666; Mon, 17 Jan 2022 05:30:20 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:19 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 16/23] hw/riscv: virt: Use AIA INTC compatible string when available Date: Mon, 17 Jan 2022 18:58:19 +0530 Message-Id: <20220117132826.426418-17-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::1029 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::1029; envelope-from=anup@brainfault.org; helo=mail-pj1-x1029.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel We should use the AIA INTC compatible string in the CPU INTC DT nodes when the CPUs support AIA feature. This will allow Linux INTC driver to use AIA local interrupt CSRs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- hw/riscv/virt.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 3af074148e..720641b1dd 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -211,8 +211,17 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket, qemu_fdt_add_subnode(mc->fdt, intc_name); qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle", intc_phandles[cpu]); - qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible", - "riscv,cpu-intc"); + if (riscv_feature(&s->soc[socket].harts[cpu].env, + RISCV_FEATURE_AIA)) { + static const char * const compat[2] = { + "riscv,cpu-intc-aia", "riscv,cpu-intc" + }; + qemu_fdt_setprop_string_array(mc->fdt, intc_name, "compatible", + (char **)&compat, ARRAY_SIZE(compat)); + } else { + qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible", + "riscv,cpu-intc"); + } qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller", NULL, 0); qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1); From patchwork Mon Jan 17 13:28:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715453 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 616F0C433EF for ; Mon, 17 Jan 2022 14:20:59 +0000 (UTC) Received: from localhost ([::1]:43622 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9SsU-0001Hg-DP for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:20:58 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39036) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5s-0001TG-0s for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:46 -0500 Received: from [2607:f8b0:4864:20::102e] (port=41723 helo=mail-pj1-x102e.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5d-00015A-8y for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:43 -0500 Received: by mail-pj1-x102e.google.com with SMTP id b1-20020a17090a990100b001b14bd47532so22116887pjp.0 for ; Mon, 17 Jan 2022 05:30:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=20K4RdXoe3H4bZAsI9EGd1rCghLs9x2ucpo40UARMzM=; b=ghUAMdOA/0pE2NYnL2+8OzHTHJepEU3gTZe63Bj8CB/nR0/YRIjCHr1OqOcmVNlkMX Pr/fcSRn91nas7Ovys2gcsfxaJ0lOLNVZUMRJWZ3HAN7cZvvn3sIJWuP3WCfhYWHLfbt rvH6E5g/8myCrqIXQ+eAL/3JNMjXJPBtAwdnVmLiR/m3WgnnHAlxbFtRnGLUYTZaWm7l 0Q+t41hjlpeFknqGNEo/JBpkZ001qX7uXk5YsW22eh0HyjDxXeypSej8mTuR2yFCLRz9 Bbu9dwry6ZQFLo+9hMWsf3nwrcegQ86tlKkG+MNxqRtRjQYSNmyXbsP+VgYfVmyCM41L 3ovQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=20K4RdXoe3H4bZAsI9EGd1rCghLs9x2ucpo40UARMzM=; b=wHYJm9cO6bxvGgrDuAfxrAHP1vgF2RiUYWuQ0MQY/i/Dg6v8xwXVH/8OM0TfWSe4FV 7/ruP0wJSQH+5utSISly30s1LfiIPof8GKGK6sCQ9zXhaYeteIIF7b6VTd2p+5hUv7wc l2IUO/PXzCE+ySXqVEis7xI7u2V+HNWCbMC783Z1gaSGt99HxaAXwWCn+C+MMx1wNTrh R1lSOfsES15H+D5L5U3VaKGzfidsGMydcGCROLz1LRBTuRYkM+0yMWfBlSW7fPcRFORb 3PSmDtvVNiM29z+/uoSo3ZCdDCtZ86yO546Vf8ECbBTxT7ske/EQ7v4exiNO1wY+bhFK e45w== X-Gm-Message-State: AOAM533+cPhUXVIvhKEhNWTDunnb297QYic2jsUQQsPWk82IHZ70mxnh s6qJoStLLXLBQEZWSATEp/lKtWHsKu5dVQ== X-Google-Smtp-Source: ABdhPJwz4kZe+SG1tT3NAjCuWhAiYov9H1tJqllduBKd8fGiNOcPNPoDFMAtAoz+clI35/WOTAWKvQ== X-Received: by 2002:a17:90a:2e85:: with SMTP id r5mr18002613pjd.149.1642426224846; Mon, 17 Jan 2022 05:30:24 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:23 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 17/23] target/riscv: Allow users to force enable AIA CSRs in HART Date: Mon, 17 Jan 2022 18:58:20 +0530 Message-Id: <20220117132826.426418-18-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::102e (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::102e; envelope-from=anup@brainfault.org; helo=mail-pj1-x102e.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel We add "x-aia" command-line option for RISC-V HART using which allows users to force enable CPU AIA CSRs without changing the interrupt controller available in RISC-V machine. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- target/riscv/cpu.c | 5 +++++ target/riscv/cpu.h | 1 + 2 files changed, 6 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 167d86eef7..26b2ced8a6 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -488,6 +488,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) } } + if (cpu->cfg.aia) { + riscv_set_feature(env, RISCV_FEATURE_AIA); + } + set_resetvec(env, cpu->cfg.resetvec); /* Validate that MISA_MXL is set properly. */ @@ -719,6 +723,7 @@ static Property riscv_cpu_properties[] = { DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false), /* ePMP 0.9.3 */ DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false), + DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false), DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC), DEFINE_PROP_END_OF_LIST(), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 7b4cf19350..3df52cbc22 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -374,6 +374,7 @@ struct RISCVCPU { bool mmu; bool pmp; bool epmp; + bool aia; uint64_t resetvec; } cfg; }; From patchwork Mon Jan 17 13:28:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715535 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 75DF9C433EF for ; Mon, 17 Jan 2022 15:21:51 +0000 (UTC) Received: from localhost ([::1]:47864 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9TpN-0004iB-0m for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 10:21:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:41058) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9SDL-0006en-Kt for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:38:28 -0500 Received: from [2607:f8b0:4864:20::232] (port=45622 helo=mail-oi1-x232.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9SDJ-0002a4-7F for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:38:27 -0500 Received: by mail-oi1-x232.google.com with SMTP id t9so23349316oie.12 for ; Mon, 17 Jan 2022 05:38:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=E/kCm7OfSfvFhunsvzlwA7HQ30gJuUNMAar3JtatnQ4=; b=29Km1xYwERmOKWS1DkBefru9od1O7Dz0ZeCum4asQDasHqk1MloT4KffY6NYzyjw+A UK6X2Sk+bq8ztfR97+TRlkTZ67SIQxGt3qP53Etb6MySR1jJT9hPvrHue1rlrydqJPD7 Yi4G7jqKaImeuA+pfD9zfEovpxfXdseO5RIxFsUxxu3dtn6WI4i+JuVTy4EHJwEmcUOw SZwUwWlFdwCEPGEKLW+X+9SuQksSWRZQQW6OJ+OyVIA9Uryj9vmzLQspyFR1ay5T53J8 xNg5MxQ71YdJYxjPcuY4eSZjk804lGCa95G35u5zXJHPN4RxgZ8cO47lRQTnHc+CQBOD YDyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=E/kCm7OfSfvFhunsvzlwA7HQ30gJuUNMAar3JtatnQ4=; b=fU3vQHE8hhaUqDkuntOFlc6QLjgTH8MjzNcfgTy8EcdtyrmHV860L5Yxb/IJWVSWAP zFL9p0SN6RpPlEvPYcuPqe8lj+a5i19biX6EnaIzN+tWH4RqkYMgqu2wJPm3YzQWrw9P yuGwOtB5VkDHRJCMjb0qaieCXYAPXMFbUrXsPn5L+vi8t6C9QzX3XLMTaRsYZm+9NJ3U fy7PL6PWaTNm0wJxUbQ697WxhVNToimXi5LslFlqf1znDLvYh0u0Wib9hxWJSgZv3Inl r6MwvccOEeaGdOwlAi5Ov5GL/6deFqFNa7USVVYfR2UBSpRFGQ1WQgg8C2X4X8vOkoBK uwuA== X-Gm-Message-State: AOAM533hjk8VLs+sQmJr3uQOokr39y1u6pilqTuCIr8TW6dpQ7egMq6k fmwBYPWUcwStKlZ1bb6/Qd67csqMLezTLw== X-Google-Smtp-Source: ABdhPJwO4d/EUGW7+M70VJT1U07EEdpJlbc7wQKQDvU6UYSceEyZZXCn0XH5s91Q8l4WSVSRVVLqfw== X-Received: by 2002:a17:90a:f015:: with SMTP id bt21mr25139826pjb.3.1642426232566; Mon, 17 Jan 2022 05:30:32 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:31 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 19/23] hw/riscv: virt: Add optional AIA APLIC support to virt machine Date: Mon, 17 Jan 2022 18:58:22 +0530 Message-Id: <20220117132826.426418-20-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::232 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::232; envelope-from=anup@brainfault.org; helo=mail-oi1-x232.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anup Patel , Bin Meng , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Atish Patra Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel We extend virt machine to emulate AIA APLIC devices only when "aia=aplic" parameter is passed along with machine name in QEMU command-line. When "aia=none" or not specified then we fallback to original PLIC device emulation. Signed-off-by: Anup Patel Signed-off-by: Anup Patel --- hw/riscv/Kconfig | 1 + hw/riscv/virt.c | 293 ++++++++++++++++++++++++++++++++-------- include/hw/riscv/virt.h | 26 +++- 3 files changed, 260 insertions(+), 60 deletions(-) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index d2d869aaad..c30bb7cb6c 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -42,6 +42,7 @@ config RISCV_VIRT select PFLASH_CFI01 select SERIAL select RISCV_ACLINT + select RISCV_APLIC select SIFIVE_PLIC select SIFIVE_TEST select VIRTIO_MMIO diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 720641b1dd..45d85d274f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -33,6 +33,7 @@ #include "hw/riscv/boot.h" #include "hw/riscv/numa.h" #include "hw/intc/riscv_aclint.h" +#include "hw/intc/riscv_aplic.h" #include "hw/intc/sifive_plic.h" #include "hw/misc/sifive_test.h" #include "chardev/char.h" @@ -51,6 +52,8 @@ static const MemMapEntry virt_memmap[] = { [VIRT_ACLINT_SSWI] = { 0x2F00000, 0x4000 }, [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 }, [VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) }, + [VIRT_APLIC_M] = { 0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) }, + [VIRT_APLIC_S] = { 0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) }, [VIRT_UART0] = { 0x10000000, 0x100 }, [VIRT_VIRTIO] = { 0x10001000, 0x1000 }, [VIRT_FW_CFG] = { 0x10100000, 0x18 }, @@ -132,12 +135,13 @@ static void virt_flash_map(RISCVVirtState *s, sysmem); } -static void create_pcie_irq_map(void *fdt, char *nodename, - uint32_t plic_phandle) +static void create_pcie_irq_map(RISCVVirtState *s, void *fdt, char *nodename, + uint32_t irqchip_phandle) { int pin, dev; - uint32_t - full_irq_map[GPEX_NUM_IRQS * GPEX_NUM_IRQS * FDT_INT_MAP_WIDTH] = {}; + uint32_t irq_map_stride = 0; + uint32_t full_irq_map[GPEX_NUM_IRQS * GPEX_NUM_IRQS * + FDT_MAX_INT_MAP_WIDTH] = {}; uint32_t *irq_map = full_irq_map; /* This code creates a standard swizzle of interrupts such that @@ -155,23 +159,31 @@ static void create_pcie_irq_map(void *fdt, char *nodename, int irq_nr = PCIE_IRQ + ((pin + PCI_SLOT(devfn)) % GPEX_NUM_IRQS); int i = 0; + /* Fill PCI address cells */ irq_map[i] = cpu_to_be32(devfn << 8); - i += FDT_PCI_ADDR_CELLS; - irq_map[i] = cpu_to_be32(pin + 1); + /* Fill PCI Interrupt cells */ + irq_map[i] = cpu_to_be32(pin + 1); i += FDT_PCI_INT_CELLS; - irq_map[i++] = cpu_to_be32(plic_phandle); - i += FDT_PLIC_ADDR_CELLS; - irq_map[i] = cpu_to_be32(irq_nr); - - irq_map += FDT_INT_MAP_WIDTH; + /* Fill interrupt controller phandle and cells */ + irq_map[i++] = cpu_to_be32(irqchip_phandle); + irq_map[i++] = cpu_to_be32(irq_nr); + if (s->aia_type != VIRT_AIA_TYPE_NONE) { + irq_map[i++] = cpu_to_be32(0x4); + } + + if (!irq_map_stride) { + irq_map_stride = i; + } + irq_map += irq_map_stride; } } - qemu_fdt_setprop(fdt, nodename, "interrupt-map", - full_irq_map, sizeof(full_irq_map)); + qemu_fdt_setprop(fdt, nodename, "interrupt-map", full_irq_map, + GPEX_NUM_IRQS * GPEX_NUM_IRQS * + irq_map_stride * sizeof(uint32_t)); qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask", 0x1800, 0, 0, 0x7); @@ -394,8 +406,6 @@ static void create_fdt_socket_plic(RISCVVirtState *s, plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket); plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr); qemu_fdt_add_subnode(mc->fdt, plic_name); - qemu_fdt_setprop_cell(mc->fdt, plic_name, - "#address-cells", FDT_PLIC_ADDR_CELLS); qemu_fdt_setprop_cell(mc->fdt, plic_name, "#interrupt-cells", FDT_PLIC_INT_CELLS); qemu_fdt_setprop_string_array(mc->fdt, plic_name, "compatible", @@ -415,6 +425,76 @@ static void create_fdt_socket_plic(RISCVVirtState *s, g_free(plic_cells); } +static void create_fdt_socket_aia(RISCVVirtState *s, + const MemMapEntry *memmap, int socket, + uint32_t *phandle, uint32_t *intc_phandles, + uint32_t *aplic_phandles) +{ + int cpu; + char *aplic_name; + uint32_t *aplic_cells; + unsigned long aplic_addr; + MachineState *mc = MACHINE(s); + uint32_t aplic_m_phandle, aplic_s_phandle; + + aplic_m_phandle = (*phandle)++; + aplic_s_phandle = (*phandle)++; + aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); + + /* M-level APLIC node */ + for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { + aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); + aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT); + } + aplic_addr = memmap[VIRT_APLIC_M].base + + (memmap[VIRT_APLIC_M].size * socket); + aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr); + qemu_fdt_add_subnode(mc->fdt, aplic_name); + qemu_fdt_setprop_string(mc->fdt, aplic_name, "compatible", "riscv,aplic"); + qemu_fdt_setprop_cell(mc->fdt, aplic_name, + "#interrupt-cells", FDT_APLIC_INT_CELLS); + qemu_fdt_setprop(mc->fdt, aplic_name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended", + aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2); + qemu_fdt_setprop_cells(mc->fdt, aplic_name, "reg", + 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size); + qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources", + VIRT_IRQCHIP_NUM_SOURCES); + qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,children", + aplic_s_phandle); + qemu_fdt_setprop_cells(mc->fdt, aplic_name, "riscv,delegate", + aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES); + riscv_socket_fdt_write_id(mc, mc->fdt, aplic_name, socket); + qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_m_phandle); + g_free(aplic_name); + + /* S-level APLIC node */ + for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { + aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); + aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT); + } + aplic_addr = memmap[VIRT_APLIC_S].base + + (memmap[VIRT_APLIC_S].size * socket); + aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr); + qemu_fdt_add_subnode(mc->fdt, aplic_name); + qemu_fdt_setprop_string(mc->fdt, aplic_name, "compatible", "riscv,aplic"); + qemu_fdt_setprop_cell(mc->fdt, aplic_name, + "#interrupt-cells", FDT_APLIC_INT_CELLS); + qemu_fdt_setprop(mc->fdt, aplic_name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended", + aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2); + qemu_fdt_setprop_cells(mc->fdt, aplic_name, "reg", + 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size); + qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources", + VIRT_IRQCHIP_NUM_SOURCES); + riscv_socket_fdt_write_id(mc, mc->fdt, aplic_name, socket); + qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_s_phandle); + g_free(aplic_name); + + g_free(aplic_cells); + aplic_phandles[socket] = aplic_s_phandle; +} + static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, bool is_32_bit, uint32_t *phandle, uint32_t *irq_mmio_phandle, @@ -451,8 +531,13 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, create_fdt_socket_clint(s, memmap, socket, intc_phandles); } - create_fdt_socket_plic(s, memmap, socket, phandle, - intc_phandles, xplic_phandles); + if (s->aia_type == VIRT_AIA_TYPE_NONE) { + create_fdt_socket_plic(s, memmap, socket, phandle, + intc_phandles, xplic_phandles); + } else { + create_fdt_socket_aia(s, memmap, socket, phandle, + intc_phandles, xplic_phandles); + } g_free(intc_phandles); g_free(clust_name); @@ -493,7 +578,13 @@ static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap, 0x0, memmap[VIRT_VIRTIO].size); qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent", irq_virtio_phandle); - qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", VIRTIO_IRQ + i); + if (s->aia_type == VIRT_AIA_TYPE_NONE) { + qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", + VIRTIO_IRQ + i); + } else { + qemu_fdt_setprop_cells(mc->fdt, name, "interrupts", + VIRTIO_IRQ + i, 0x4); + } g_free(name); } } @@ -531,7 +622,7 @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, 2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.size); - create_pcie_irq_map(mc->fdt, name, irq_pcie_phandle); + create_pcie_irq_map(s, mc->fdt, name, irq_pcie_phandle); g_free(name); } @@ -590,7 +681,11 @@ static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap, 0x0, memmap[VIRT_UART0].size); qemu_fdt_setprop_cell(mc->fdt, name, "clock-frequency", 3686400); qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent", irq_mmio_phandle); - qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", UART0_IRQ); + if (s->aia_type == VIRT_AIA_TYPE_NONE) { + qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", UART0_IRQ); + } else { + qemu_fdt_setprop_cells(mc->fdt, name, "interrupts", UART0_IRQ, 0x4); + } qemu_fdt_add_subnode(mc->fdt, "/chosen"); qemu_fdt_setprop_string(mc->fdt, "/chosen", "stdout-path", name); @@ -611,7 +706,11 @@ static void create_fdt_rtc(RISCVVirtState *s, const MemMapEntry *memmap, 0x0, memmap[VIRT_RTC].base, 0x0, memmap[VIRT_RTC].size); qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent", irq_mmio_phandle); - qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", RTC_IRQ); + if (s->aia_type == VIRT_AIA_TYPE_NONE) { + qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", RTC_IRQ); + } else { + qemu_fdt_setprop_cells(mc->fdt, name, "interrupts", RTC_IRQ, 0x4); + } g_free(name); } @@ -692,7 +791,7 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, hwaddr high_mmio_base, hwaddr high_mmio_size, hwaddr pio_base, - DeviceState *plic) + DeviceState *irqchip) { DeviceState *dev; MemoryRegion *ecam_alias, *ecam_reg; @@ -726,7 +825,7 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, pio_base); for (i = 0; i < GPEX_NUM_IRQS; i++) { - irq = qdev_get_gpio_in(plic, PCIE_IRQ + i); + irq = qdev_get_gpio_in(irqchip, PCIE_IRQ + i); sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq); gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ + i); @@ -757,18 +856,75 @@ static FWCfgState *create_fw_cfg(const MachineState *mc) return fw_cfg; } +static DeviceState *virt_create_plic(const MemMapEntry *memmap, int socket, + int base_hartid, int hart_count) +{ + DeviceState *ret; + char *plic_hart_config; + + /* Per-socket PLIC hart topology configuration string */ + plic_hart_config = riscv_plic_hart_config_string(hart_count); + + /* Per-socket PLIC */ + ret = sifive_plic_create( + memmap[VIRT_PLIC].base + socket * memmap[VIRT_PLIC].size, + plic_hart_config, hart_count, base_hartid, + VIRT_IRQCHIP_NUM_SOURCES, + ((1U << VIRT_IRQCHIP_NUM_PRIO_BITS) - 1), + VIRT_PLIC_PRIORITY_BASE, + VIRT_PLIC_PENDING_BASE, + VIRT_PLIC_ENABLE_BASE, + VIRT_PLIC_ENABLE_STRIDE, + VIRT_PLIC_CONTEXT_BASE, + VIRT_PLIC_CONTEXT_STRIDE, + memmap[VIRT_PLIC].size); + + g_free(plic_hart_config); + + return ret; +} + +static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, + const MemMapEntry *memmap, int socket, + int base_hartid, int hart_count) +{ + DeviceState *aplic_m; + + /* Per-socket M-level APLIC */ + aplic_m = riscv_aplic_create( + memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size, + memmap[VIRT_APLIC_M].size, + base_hartid, hart_count, + VIRT_IRQCHIP_NUM_SOURCES, + VIRT_IRQCHIP_NUM_PRIO_BITS, + false, true, NULL); + + if (aplic_m) { + /* Per-socket S-level APLIC */ + riscv_aplic_create( + memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size, + memmap[VIRT_APLIC_S].size, + base_hartid, hart_count, + VIRT_IRQCHIP_NUM_SOURCES, + VIRT_IRQCHIP_NUM_PRIO_BITS, + false, false, aplic_m); + } + + return aplic_m; +} + static void virt_machine_init(MachineState *machine) { const MemMapEntry *memmap = virt_memmap; RISCVVirtState *s = RISCV_VIRT_MACHINE(machine); MemoryRegion *system_memory = get_system_memory(); MemoryRegion *mask_rom = g_new(MemoryRegion, 1); - char *plic_hart_config, *soc_name; + char *soc_name; target_ulong start_addr = memmap[VIRT_DRAM].base; target_ulong firmware_end_addr, kernel_start_addr; uint32_t fdt_load_addr; uint64_t kernel_entry; - DeviceState *mmio_plic, *virtio_plic, *pcie_plic; + DeviceState *mmio_irqchip, *virtio_irqchip, *pcie_irqchip; int i, base_hartid, hart_count; /* Check socket count limit */ @@ -779,7 +935,7 @@ static void virt_machine_init(MachineState *machine) } /* Initialize sockets */ - mmio_plic = virtio_plic = pcie_plic = NULL; + mmio_irqchip = virtio_irqchip = pcie_irqchip = NULL; for (i = 0; i < riscv_socket_count(machine); i++) { if (!riscv_socket_check_hartids(machine, i)) { error_report("discontinuous hartids in socket%d", i); @@ -829,36 +985,27 @@ static void virt_machine_init(MachineState *machine) base_hartid, hart_count, true); } - /* Per-socket PLIC hart topology configuration string */ - plic_hart_config = riscv_plic_hart_config_string(hart_count); - - /* Per-socket PLIC */ - s->plic[i] = sifive_plic_create( - memmap[VIRT_PLIC].base + i * memmap[VIRT_PLIC].size, - plic_hart_config, hart_count, base_hartid, - VIRT_PLIC_NUM_SOURCES, - VIRT_PLIC_NUM_PRIORITIES, - VIRT_PLIC_PRIORITY_BASE, - VIRT_PLIC_PENDING_BASE, - VIRT_PLIC_ENABLE_BASE, - VIRT_PLIC_ENABLE_STRIDE, - VIRT_PLIC_CONTEXT_BASE, - VIRT_PLIC_CONTEXT_STRIDE, - memmap[VIRT_PLIC].size); - g_free(plic_hart_config); + /* Per-socket interrupt controller */ + if (s->aia_type == VIRT_AIA_TYPE_NONE) { + s->irqchip[i] = virt_create_plic(memmap, i, + base_hartid, hart_count); + } else { + s->irqchip[i] = virt_create_aia(s->aia_type, memmap, i, + base_hartid, hart_count); + } - /* Try to use different PLIC instance based device type */ + /* Try to use different IRQCHIP instance based device type */ if (i == 0) { - mmio_plic = s->plic[i]; - virtio_plic = s->plic[i]; - pcie_plic = s->plic[i]; + mmio_irqchip = s->irqchip[i]; + virtio_irqchip = s->irqchip[i]; + pcie_irqchip = s->irqchip[i]; } if (i == 1) { - virtio_plic = s->plic[i]; - pcie_plic = s->plic[i]; + virtio_irqchip = s->irqchip[i]; + pcie_irqchip = s->irqchip[i]; } if (i == 2) { - pcie_plic = s->plic[i]; + pcie_irqchip = s->irqchip[i]; } } @@ -957,7 +1104,7 @@ static void virt_machine_init(MachineState *machine) for (i = 0; i < VIRTIO_COUNT; i++) { sysbus_create_simple("virtio-mmio", memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size, - qdev_get_gpio_in(DEVICE(virtio_plic), VIRTIO_IRQ + i)); + qdev_get_gpio_in(DEVICE(virtio_irqchip), VIRTIO_IRQ + i)); } gpex_pcie_init(system_memory, @@ -968,14 +1115,14 @@ static void virt_machine_init(MachineState *machine) virt_high_pcie_memmap.base, virt_high_pcie_memmap.size, memmap[VIRT_PCIE_PIO].base, - DEVICE(pcie_plic)); + DEVICE(pcie_irqchip)); serial_mm_init(system_memory, memmap[VIRT_UART0].base, - 0, qdev_get_gpio_in(DEVICE(mmio_plic), UART0_IRQ), 399193, + 0, qdev_get_gpio_in(DEVICE(mmio_irqchip), UART0_IRQ), 399193, serial_hd(0), DEVICE_LITTLE_ENDIAN); sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base, - qdev_get_gpio_in(DEVICE(mmio_plic), RTC_IRQ)); + qdev_get_gpio_in(DEVICE(mmio_irqchip), RTC_IRQ)); virt_flash_create(s); @@ -991,6 +1138,37 @@ static void virt_machine_instance_init(Object *obj) { } +static char *virt_get_aia(Object *obj, Error **errp) +{ + RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); + const char *val; + + switch (s->aia_type) { + case VIRT_AIA_TYPE_APLIC: + val = "aplic"; + break; + default: + val = "none"; + break; + }; + + return g_strdup(val); +} + +static void virt_set_aia(Object *obj, const char *val, Error **errp) +{ + RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); + + if (!strcmp(val, "none")) { + s->aia_type = VIRT_AIA_TYPE_NONE; + } else if (!strcmp(val, "aplic")) { + s->aia_type = VIRT_AIA_TYPE_APLIC; + } else { + error_setg(errp, "Invalid AIA interrupt controller type"); + error_append_hint(errp, "Valid values are none, and aplic.\n"); + } +} + static bool virt_get_aclint(Object *obj, Error **errp) { MachineState *ms = MACHINE(obj); @@ -1029,6 +1207,13 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) object_class_property_set_description(oc, "aclint", "Set on/off to enable/disable " "emulating ACLINT devices"); + + object_class_property_add_str(oc, "aia", virt_get_aia, + virt_set_aia); + object_class_property_set_description(oc, "aia", + "Set type of AIA interrupt " + "conttoller. Valid values are " + "none, and aplic."); } static const TypeInfo virt_machine_typeinfo = { diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 6e9f61ccd9..4584042090 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -32,18 +32,24 @@ typedef struct RISCVVirtState RISCVVirtState; DECLARE_INSTANCE_CHECKER(RISCVVirtState, RISCV_VIRT_MACHINE, TYPE_RISCV_VIRT_MACHINE) +typedef enum RISCVVirtAIAType { + VIRT_AIA_TYPE_NONE=0, + VIRT_AIA_TYPE_APLIC, +} RISCVVirtAIAType; + struct RISCVVirtState { /*< private >*/ MachineState parent; /*< public >*/ RISCVHartArrayState soc[VIRT_SOCKETS_MAX]; - DeviceState *plic[VIRT_SOCKETS_MAX]; + DeviceState *irqchip[VIRT_SOCKETS_MAX]; PFlashCFI01 *flash[2]; FWCfgState *fw_cfg; int fdt_size; bool have_aclint; + RISCVVirtAIAType aia_type; }; enum { @@ -54,6 +60,8 @@ enum { VIRT_CLINT, VIRT_ACLINT_SSWI, VIRT_PLIC, + VIRT_APLIC_M, + VIRT_APLIC_S, VIRT_UART0, VIRT_VIRTIO, VIRT_FW_CFG, @@ -73,8 +81,9 @@ enum { VIRTIO_NDEV = 0x35 /* Arbitrary maximum number of interrupts */ }; -#define VIRT_PLIC_NUM_SOURCES 127 -#define VIRT_PLIC_NUM_PRIORITIES 7 +#define VIRT_IRQCHIP_NUM_SOURCES 127 +#define VIRT_IRQCHIP_NUM_PRIO_BITS 3 + #define VIRT_PLIC_PRIORITY_BASE 0x04 #define VIRT_PLIC_PENDING_BASE 0x1000 #define VIRT_PLIC_ENABLE_BASE 0x2000 @@ -86,9 +95,14 @@ enum { #define FDT_PCI_ADDR_CELLS 3 #define FDT_PCI_INT_CELLS 1 -#define FDT_PLIC_ADDR_CELLS 0 #define FDT_PLIC_INT_CELLS 1 -#define FDT_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + 1 + \ - FDT_PLIC_ADDR_CELLS + FDT_PLIC_INT_CELLS) +#define FDT_APLIC_INT_CELLS 2 +#define FDT_MAX_INT_CELLS 2 +#define FDT_MAX_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \ + 1 + FDT_MAX_INT_CELLS) +#define FDT_PLIC_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \ + 1 + FDT_PLIC_INT_CELLS) +#define FDT_APLIC_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \ + 1 + FDT_APLIC_INT_CELLS) #endif From patchwork Mon Jan 17 13:28:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715467 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id C861EC433F5 for ; Mon, 17 Jan 2022 14:29:21 +0000 (UTC) Received: from localhost ([::1]:36550 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9T0a-0005ZJ-Uo for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:29:20 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39158) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5w-0001UU-CS for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:52 -0500 Received: from [2607:f8b0:4864:20::62b] (port=37391 helo=mail-pl1-x62b.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5n-00017n-Uc for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:47 -0500 Received: by mail-pl1-x62b.google.com with SMTP id n11so19282627plf.4 for ; Mon, 17 Jan 2022 05:30:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yuJnuVLozU1oR581OJV22HvkkVWxlrTWFpwzTqeMxwM=; b=tGvVVaV7zLL6GOk0ZJIlnaCixM/ufKjH5B9KWfl37b3VkUiyJ1CC6uKmoNSOZM6/DM byrafYm0lMuTIgg8fNcjDqT7ddFroiXr5gn7sl+8oZSVXQYxagb1/AOLV9+MpuMwNgtR l95cbsDKfD33vCDN+Sd/Me/5pW2vCw2G77AQCJqjPiE8hMwZwbaFJJPD3o7RysXUmR8N uoxRbjln74M+X2tugvjyuZsiam4Nv134LAX33CqYxyehyKcT6i9K7/Jr7UIkU+uPZE3c MxAYc243oxtsyN4or+ypx8mD8ZxcFlEfdFGbQuc3CKHCy/DKVUWLZfLjMbyE912jPeHa hWrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yuJnuVLozU1oR581OJV22HvkkVWxlrTWFpwzTqeMxwM=; b=jXiweVJRbf1O5+v7IXOMVSlpow5jLmS269FVKIv3NKwht2ap2d7CvB9VxyNuOT0mcC hEart6gaFUS/+qoMng48G0OKq9tnWFsbBfEuiP7l7z/DLQZguEIcSINYbea8A1AhDbTE yy4B3dAmpjhlGs9ZdRqJnQMbRU/KpAXqe7PEpxXWg2oWoAkyupdgOCvC3LYH8PtX2+4y qHObELfVSr5UG7yFcePVRfp9XZbYIBKGWs1eZQFGdJBM5KC0pEApbLhuc4W1C+GTsgNe UlTIFdkmpxfyW0sFUHyey+D/3T0z3zFCrOBVo8jRbrOiwxBVhm3bPKJbKl/XFrnF7uVy 1B2w== X-Gm-Message-State: AOAM532cH5U/axEb/cA4iX8R4Bg3SuN6qlmbNul9y0bDLbS8kQ4e/VBw 9efIZGuaVEQ/0p1gCraciO5fOw== X-Google-Smtp-Source: ABdhPJwgSDgNGhn060EePOxSbhKfr1blo31XqCciOMm2wmGVQOjFvNwZZ+D1G9oCAama8U1MdpYt6A== X-Received: by 2002:a17:902:8605:b0:149:9a25:103c with SMTP id f5-20020a170902860500b001499a25103cmr22988303plo.155.1642426236196; Mon, 17 Jan 2022 05:30:36 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:35 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 20/23] hw/intc: Add RISC-V AIA IMSIC device emulation Date: Mon, 17 Jan 2022 18:58:23 +0530 Message-Id: <20220117132826.426418-21-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::62b (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::62b; envelope-from=anup@brainfault.org; helo=mail-pl1-x62b.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anup Patel , Bin Meng , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Atish Patra Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel The RISC-V AIA (Advanced Interrupt Architecture) defines a new interrupt controller for MSIs (message signal interrupts) called IMSIC (Incoming Message Signal Interrupt Controller). The IMSIC is per-HART device and also suppport virtualizaiton of MSIs using dedicated VS-level guest interrupt files. This patch adds device emulation for RISC-V AIA IMSIC which supports M-level, S-level, and VS-level MSIs. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Frank Chang --- hw/intc/Kconfig | 3 + hw/intc/meson.build | 1 + hw/intc/riscv_imsic.c | 448 ++++++++++++++++++++++++++++++++++ include/hw/intc/riscv_imsic.h | 68 ++++++ 4 files changed, 520 insertions(+) create mode 100644 hw/intc/riscv_imsic.c create mode 100644 include/hw/intc/riscv_imsic.h diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig index 528e77b4a6..ec8d4cec29 100644 --- a/hw/intc/Kconfig +++ b/hw/intc/Kconfig @@ -73,6 +73,9 @@ config RISCV_ACLINT config RISCV_APLIC bool +config RISCV_IMSIC + bool + config SIFIVE_PLIC bool diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 7466024402..5caa337654 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -51,6 +51,7 @@ specific_ss.add(when: 'CONFIG_S390_FLIC_KVM', if_true: files('s390_flic_kvm.c')) specific_ss.add(when: 'CONFIG_SH_INTC', if_true: files('sh_intc.c')) specific_ss.add(when: 'CONFIG_RISCV_ACLINT', if_true: files('riscv_aclint.c')) specific_ss.add(when: 'CONFIG_RISCV_APLIC', if_true: files('riscv_aplic.c')) +specific_ss.add(when: 'CONFIG_RISCV_IMSIC', if_true: files('riscv_imsic.c')) specific_ss.add(when: 'CONFIG_SIFIVE_PLIC', if_true: files('sifive_plic.c')) specific_ss.add(when: 'CONFIG_XICS', if_true: files('xics.c')) specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XICS'], diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c new file mode 100644 index 0000000000..18d2877832 --- /dev/null +++ b/hw/intc/riscv_imsic.c @@ -0,0 +1,448 @@ +/* + * RISC-V IMSIC (Incoming Message Signaled Interrupt Controller) + * + * Copyright (c) 2021 Western Digital Corporation or its affiliates. + * + * 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 . + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qemu/error-report.h" +#include "qemu/bswap.h" +#include "exec/address-spaces.h" +#include "hw/sysbus.h" +#include "hw/pci/msi.h" +#include "hw/boards.h" +#include "hw/qdev-properties.h" +#include "hw/intc/riscv_imsic.h" +#include "hw/irq.h" +#include "target/riscv/cpu.h" +#include "target/riscv/cpu_bits.h" +#include "sysemu/sysemu.h" +#include "migration/vmstate.h" + +#define IMSIC_MMIO_PAGE_LE 0x00 +#define IMSIC_MMIO_PAGE_BE 0x04 + +#define IMSIC_MIN_ID ((IMSIC_EIPx_BITS * 2) - 1) +#define IMSIC_MAX_ID (IMSIC_TOPEI_IID_MASK) + +#define IMSIC_EISTATE_PENDING (1U << 0) +#define IMSIC_EISTATE_ENABLED (1U << 1) +#define IMSIC_EISTATE_ENPEND (IMSIC_EISTATE_ENABLED | \ + IMSIC_EISTATE_PENDING) + +static uint32_t riscv_imsic_topei(RISCVIMSICState *imsic, uint32_t page) +{ + uint32_t i, max_irq, base; + + base = page * imsic->num_irqs; + max_irq = (imsic->eithreshold[page] && + (imsic->eithreshold[page] <= imsic->num_irqs)) ? + imsic->eithreshold[page] : imsic->num_irqs; + for (i = 1; i < max_irq; i++) { + if ((imsic->eistate[base + i] & IMSIC_EISTATE_ENPEND) == + IMSIC_EISTATE_ENPEND) { + return (i << IMSIC_TOPEI_IID_SHIFT) | i; + } + } + + return 0; +} + +static void riscv_imsic_update(RISCVIMSICState *imsic, uint32_t page) +{ + if (imsic->eidelivery[page] && riscv_imsic_topei(imsic, page)) { + qemu_irq_raise(imsic->external_irqs[page]); + } else { + qemu_irq_lower(imsic->external_irqs[page]); + } +} + +static int riscv_imsic_eidelivery_rmw(RISCVIMSICState *imsic, uint32_t page, + target_ulong *val, + target_ulong new_val, + target_ulong wr_mask) +{ + target_ulong old_val = imsic->eidelivery[page]; + + if (val) { + *val = old_val; + } + + wr_mask &= 0x1; + imsic->eidelivery[page] = (old_val & ~wr_mask) | (new_val & wr_mask); + + riscv_imsic_update(imsic, page); + return 0; +} + +static int riscv_imsic_eithreshold_rmw(RISCVIMSICState *imsic, uint32_t page, + target_ulong *val, + target_ulong new_val, + target_ulong wr_mask) +{ + target_ulong old_val = imsic->eithreshold[page]; + + if (val) { + *val = old_val; + } + + wr_mask &= IMSIC_MAX_ID; + imsic->eithreshold[page] = (old_val & ~wr_mask) | (new_val & wr_mask); + + riscv_imsic_update(imsic, page); + return 0; +} + +static int riscv_imsic_topei_rmw(RISCVIMSICState *imsic, uint32_t page, + target_ulong *val, target_ulong new_val, + target_ulong wr_mask) +{ + uint32_t base, topei = riscv_imsic_topei(imsic, page); + + /* Read pending and enabled interrupt with highest priority */ + if (val) { + *val = topei; + } + + /* Writes ignore value and clear top pending interrupt */ + if (topei && wr_mask) { + topei >>= IMSIC_TOPEI_IID_SHIFT; + base = page * imsic->num_irqs; + if (topei) { + imsic->eistate[base + topei] &= ~IMSIC_EISTATE_PENDING; + } + + riscv_imsic_update(imsic, page); + } + + return 0; +} + +static int riscv_imsic_eix_rmw(RISCVIMSICState *imsic, + uint32_t xlen, uint32_t page, + uint32_t num, bool pend, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + uint32_t i, base; + target_ulong mask; + uint32_t state = (pend) ? IMSIC_EISTATE_PENDING : IMSIC_EISTATE_ENABLED; + + if (xlen != 32) { + if (num & 0x1) { + return -EINVAL; + } + num >>= 1; + } + if (num >= (imsic->num_irqs / xlen)) { + return -EINVAL; + } + + base = (page * imsic->num_irqs) + (num * xlen); + + if (val) { + *val = 0; + for (i = 0; i < xlen; i++) { + mask = (target_ulong)1 << i; + *val |= (imsic->eistate[base + i] & state) ? mask : 0; + } + } + + for (i = 0; i < xlen; i++) { + /* Bit0 of eip0 and eie0 are read-only zero */ + if (!num && !i) { + continue; + } + + mask = (target_ulong)1 << i; + if (wr_mask & mask) { + if (new_val & mask) { + imsic->eistate[base + i] |= state; + } else { + imsic->eistate[base + i] &= ~state; + } + } + } + + riscv_imsic_update(imsic, page); + return 0; +} + +static int riscv_imsic_rmw(void *arg, target_ulong reg, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + RISCVIMSICState *imsic = arg; + uint32_t isel, priv, virt, vgein, xlen, page; + + priv = AIA_IREG_PRIV(reg); + virt = AIA_IREG_VIRT(reg); + isel = AIA_IREG_ISEL(reg); + vgein = AIA_IREG_VGEIN(reg); + xlen = AIA_IREG_XLEN(reg); + + if (imsic->mmode) { + if (priv == PRV_M && !virt) { + page = 0; + } else { + goto err; + } + } else { + if (priv == PRV_S) { + if (virt) { + if (vgein && vgein < imsic->num_pages) { + page = vgein; + } else { + goto err; + } + } else { + page = 0; + } + } else { + goto err; + } + } + + switch (isel) { + case ISELECT_IMSIC_EIDELIVERY: + return riscv_imsic_eidelivery_rmw(imsic, page, val, + new_val, wr_mask); + case ISELECT_IMSIC_EITHRESHOLD: + return riscv_imsic_eithreshold_rmw(imsic, page, val, + new_val, wr_mask); + case ISELECT_IMSIC_TOPEI: + return riscv_imsic_topei_rmw(imsic, page, val, new_val, wr_mask); + case ISELECT_IMSIC_EIP0 ... ISELECT_IMSIC_EIP63: + return riscv_imsic_eix_rmw(imsic, xlen, page, + isel - ISELECT_IMSIC_EIP0, + true, val, new_val, wr_mask); + case ISELECT_IMSIC_EIE0 ... ISELECT_IMSIC_EIE63: + return riscv_imsic_eix_rmw(imsic, xlen, page, + isel - ISELECT_IMSIC_EIE0, + false, val, new_val, wr_mask); + default: + break; + }; + +err: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Invalid register priv=%d virt=%d isel=%d vgein=%d\n", + __func__, priv, virt, isel, vgein); + return -EINVAL; +} + +static uint64_t riscv_imsic_read(void *opaque, hwaddr addr, unsigned size) +{ + RISCVIMSICState *imsic = opaque; + + /* Reads must be 4 byte words */ + if ((addr & 0x3) != 0) { + goto err; + } + + /* Reads cannot be out of range */ + if (addr > IMSIC_MMIO_SIZE(imsic->num_pages)) { + goto err; + } + + return 0; + +err: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Invalid register read 0x%" HWADDR_PRIx "\n", + __func__, addr); + return 0; +} + +static void riscv_imsic_write(void *opaque, hwaddr addr, uint64_t value, + unsigned size) +{ + RISCVIMSICState *imsic = opaque; + uint32_t page; + + /* Writes must be 4 byte words */ + if ((addr & 0x3) != 0) { + goto err; + } + + /* Writes cannot be out of range */ + if (addr > IMSIC_MMIO_SIZE(imsic->num_pages)) { + goto err; + } + + /* Writes only supported for MSI little-endian registers */ + page = addr >> IMSIC_MMIO_PAGE_SHIFT; + if ((addr & (IMSIC_MMIO_PAGE_SZ - 1)) == IMSIC_MMIO_PAGE_LE) { + if (value && (value < imsic->num_irqs)) { + imsic->eistate[(page * imsic->num_irqs) + value] |= + IMSIC_EISTATE_PENDING; + } + } + + /* Update CPU external interrupt status */ + riscv_imsic_update(imsic, page); + + return; + +err: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Invalid register write 0x%" HWADDR_PRIx "\n", + __func__, addr); +} + +static const MemoryRegionOps riscv_imsic_ops = { + .read = riscv_imsic_read, + .write = riscv_imsic_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4 + } +}; + +static void riscv_imsic_realize(DeviceState *dev, Error **errp) +{ + RISCVIMSICState *imsic = RISCV_IMSIC(dev); + RISCVCPU *rcpu = RISCV_CPU(qemu_get_cpu(imsic->hartid)); + CPUState *cpu = qemu_get_cpu(imsic->hartid); + CPURISCVState *env = cpu ? cpu->env_ptr : NULL; + + imsic->num_eistate = imsic->num_pages * imsic->num_irqs; + imsic->eidelivery = g_new0(uint32_t, imsic->num_pages); + imsic->eithreshold = g_new0(uint32_t, imsic->num_pages); + imsic->eistate = g_new0(uint32_t, imsic->num_eistate); + + memory_region_init_io(&imsic->mmio, OBJECT(dev), &riscv_imsic_ops, + imsic, TYPE_RISCV_IMSIC, + IMSIC_MMIO_SIZE(imsic->num_pages)); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &imsic->mmio); + + /* Claim the CPU interrupt to be triggered by this IMSIC */ + if (riscv_cpu_claim_interrupts(rcpu, + (imsic->mmode) ? MIP_MEIP : MIP_SEIP) < 0) { + error_report("%s already claimed", + (imsic->mmode) ? "MEIP" : "SEIP"); + exit(1); + } + + /* Create output IRQ lines */ + imsic->external_irqs = g_malloc(sizeof(qemu_irq) * imsic->num_pages); + qdev_init_gpio_out(dev, imsic->external_irqs, imsic->num_pages); + + /* Force select AIA feature and setup CSR read-modify-write callback */ + if (env) { + riscv_set_feature(env, RISCV_FEATURE_AIA); + if (!imsic->mmode) { + riscv_cpu_set_geilen(env, imsic->num_pages - 1); + } + riscv_cpu_set_aia_ireg_rmw_fn(env, (imsic->mmode) ? PRV_M : PRV_S, + riscv_imsic_rmw, imsic); + } + + msi_nonbroken = true; +} + +static Property riscv_imsic_properties[] = { + DEFINE_PROP_BOOL("mmode", RISCVIMSICState, mmode, 0), + DEFINE_PROP_UINT32("hartid", RISCVIMSICState, hartid, 0), + DEFINE_PROP_UINT32("num-pages", RISCVIMSICState, num_pages, 0), + DEFINE_PROP_UINT32("num-irqs", RISCVIMSICState, num_irqs, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static const VMStateDescription vmstate_riscv_imsic = { + .name = "riscv_imsic", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT32(eidelivery, RISCVIMSICState, + num_pages, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(eithreshold, RISCVIMSICState, + num_pages, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(eistate, RISCVIMSICState, + num_eistate, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_END_OF_LIST() + } +}; + +static void riscv_imsic_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + device_class_set_props(dc, riscv_imsic_properties); + dc->realize = riscv_imsic_realize; + dc->vmsd = &vmstate_riscv_imsic; +} + +static const TypeInfo riscv_imsic_info = { + .name = TYPE_RISCV_IMSIC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(RISCVIMSICState), + .class_init = riscv_imsic_class_init, +}; + +static void riscv_imsic_register_types(void) +{ + type_register_static(&riscv_imsic_info); +} + +type_init(riscv_imsic_register_types) + +/* + * Create IMSIC device. + */ +DeviceState *riscv_imsic_create(hwaddr addr, uint32_t hartid, bool mmode, + uint32_t num_pages, uint32_t num_ids) +{ + DeviceState *dev = qdev_new(TYPE_RISCV_IMSIC); + CPUState *cpu = qemu_get_cpu(hartid); + uint32_t i; + + assert(!(addr & (IMSIC_MMIO_PAGE_SZ - 1))); + if (mmode) { + assert(num_pages == 1); + } else { + assert(num_pages >= 1 && num_pages <= (IRQ_LOCAL_GUEST_MAX + 1)); + } + assert(IMSIC_MIN_ID <= num_ids); + assert(num_ids <= IMSIC_MAX_ID); + assert((num_ids & IMSIC_MIN_ID) == IMSIC_MIN_ID); + + qdev_prop_set_bit(dev, "mmode", mmode); + qdev_prop_set_uint32(dev, "hartid", hartid); + qdev_prop_set_uint32(dev, "num-pages", num_pages); + qdev_prop_set_uint32(dev, "num-irqs", num_ids + 1); + + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); + + for (i = 0; i < num_pages; i++) { + if (!i) { + qdev_connect_gpio_out_named(dev, NULL, i, + qdev_get_gpio_in(DEVICE(cpu), + (mmode) ? IRQ_M_EXT : IRQ_S_EXT)); + } else { + qdev_connect_gpio_out_named(dev, NULL, i, + qdev_get_gpio_in(DEVICE(cpu), + IRQ_LOCAL_MAX + i - 1)); + } + } + + return dev; +} diff --git a/include/hw/intc/riscv_imsic.h b/include/hw/intc/riscv_imsic.h new file mode 100644 index 0000000000..58c2aaa8dc --- /dev/null +++ b/include/hw/intc/riscv_imsic.h @@ -0,0 +1,68 @@ +/* + * RISC-V IMSIC (Incoming Message Signal Interrupt Controller) interface + * + * Copyright (c) 2021 Western Digital Corporation or its affiliates. + * + * 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 HW_RISCV_IMSIC_H +#define HW_RISCV_IMSIC_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define TYPE_RISCV_IMSIC "riscv.imsic" + +typedef struct RISCVIMSICState RISCVIMSICState; +DECLARE_INSTANCE_CHECKER(RISCVIMSICState, RISCV_IMSIC, TYPE_RISCV_IMSIC) + +#define IMSIC_MMIO_PAGE_SHIFT 12 +#define IMSIC_MMIO_PAGE_SZ (1UL << IMSIC_MMIO_PAGE_SHIFT) +#define IMSIC_MMIO_SIZE(__num_pages) ((__num_pages) * IMSIC_MMIO_PAGE_SZ) + +#define IMSIC_MMIO_HART_GUEST_MAX_BTIS 6 +#define IMSIC_MMIO_GROUP_MIN_SHIFT 24 + +#define IMSIC_HART_NUM_GUESTS(__guest_bits) \ + (1U << (__guest_bits)) +#define IMSIC_HART_SIZE(__guest_bits) \ + (IMSIC_HART_NUM_GUESTS(__guest_bits) * IMSIC_MMIO_PAGE_SZ) +#define IMSIC_GROUP_NUM_HARTS(__hart_bits) \ + (1U << (__hart_bits)) +#define IMSIC_GROUP_SIZE(__hart_bits, __guest_bits) \ + (IMSIC_GROUP_NUM_HARTS(__hart_bits) * IMSIC_HART_SIZE(__guest_bits)) + +struct RISCVIMSICState { + /*< private >*/ + SysBusDevice parent_obj; + qemu_irq *external_irqs; + + /*< public >*/ + MemoryRegion mmio; + uint32_t num_eistate; + uint32_t *eidelivery; + uint32_t *eithreshold; + uint32_t *eistate; + + /* config */ + bool mmode; + uint32_t hartid; + uint32_t num_pages; + uint32_t num_irqs; +}; + +DeviceState *riscv_imsic_create(hwaddr addr, uint32_t hartid, bool mmode, + uint32_t num_pages, uint32_t num_ids); + +#endif From patchwork Mon Jan 17 13:28:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715504 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 51F00C433EF for ; Mon, 17 Jan 2022 15:02:54 +0000 (UTC) Received: from localhost ([::1]:44844 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9TWz-0007mf-6G for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 10:02:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39242) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S61-0001Y9-1V for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:54 -0500 Received: from [2607:f8b0:4864:20::102e] (port=33711 helo=mail-pj1-x102e.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5p-0001AM-Gg for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:52 -0500 Received: by mail-pj1-x102e.google.com with SMTP id g11-20020a17090a7d0b00b001b2c12c7273so10425384pjl.0 for ; Mon, 17 Jan 2022 05:30:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0+v+tn6fSf0CxSp3HiUfvEiZNnLwgF0oy6XKKX69EWs=; b=ZZqthHPKgfQlFb4dsucdw5KN4pV8YZA/Bogy//NHfmUVBm1bkolRu8jFMIVslPQJin nKDn+HABBqqfiL/hiwBpGC5rOeFz3QOxkmoIiTCqQCC3kme/KxSU/K9kwEYqaIA7dnFd nvHtUXXCVVGpqTK9BEN8lYjUEDtAnu0ztspKXgwk8nROcs029JVlYSqHg4AWmZgL5YBW QC/qfB+wwDjowPVV9sH5zBwy9xvllRKaGPQx709FeJsxt5KDriVpi8bIMtKhGebRGOwy AdotPlLj0VKEVybTRueAHHEgWo+sDAN5XkmAYV+18y2DpYHdMpn6c2oiAInJzNFkP+ZK kpkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0+v+tn6fSf0CxSp3HiUfvEiZNnLwgF0oy6XKKX69EWs=; b=2MReRsikzNUGGtUjixOu4a1xytNL87YoM1tHuebkTOt0oBve5NP/4WATrkCM1W92Mg 7tycwmO6RMpBxeqFwPPvqal1Ea9cgm1OR0FWdAwNziABnkgpFh2lsrxaiHXgf0sNs8LQ VaxlFOkg7fpk15z0xoIY1MlS7nXSzGCClZLSKu1Msrs3VkdhX2/UowD87C4BJ+XxLhYE TwqplzuDw3nNVqB+gwclSMDonVi/ScFMZNoTGEKpam8RMLCpQeYqluXSUrS2p0KILShJ 1iP/UQKPlJ2K+TTwRwqCLWd/yvIjaq9Qw2FDD76XultFg7Gb8HqNvuUEYyTWjcPIDugc t3cg== X-Gm-Message-State: AOAM533y6xsTBe62tAVJZAK/4ShvZnZwmfPMv7dQlb4W5mHCOSBq/W4h MmSALNY1uWcTfJTfhkb1N4lFjg== X-Google-Smtp-Source: ABdhPJybTcYYRAn+XOuacfYpkboHTIpPatS/XnDyEGLqlbifHXI4Ti1l1p29ryDBSpu2P3RMzrT6VQ== X-Received: by 2002:a17:90b:1bc9:: with SMTP id oa9mr5625349pjb.47.1642426240116; Mon, 17 Jan 2022 05:30:40 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:39 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 21/23] hw/riscv: virt: Add optional AIA IMSIC support to virt machine Date: Mon, 17 Jan 2022 18:58:24 +0530 Message-Id: <20220117132826.426418-22-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::102e (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::102e; envelope-from=anup@brainfault.org; helo=mail-pj1-x102e.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anup Patel , Bin Meng , qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Atish Patra Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel We extend virt machine to emulate both AIA IMSIC and AIA APLIC devices only when "aia=aplic-imsic" parameter is passed along with machine name in the QEMU command-line. The AIA IMSIC is only a per-HART MSI controller so we use AIA APLIC in MSI-mode to forward all wired interrupts as MSIs to the AIA IMSIC. We also provide "aia-guests=" parameter which can be used to specify number of VS-level AIA IMSIC Guests MMIO pages for each HART. Signed-off-by: Anup Patel Signed-off-by: Anup Patel --- hw/riscv/Kconfig | 1 + hw/riscv/virt.c | 434 ++++++++++++++++++++++++++++++++-------- include/hw/riscv/virt.h | 17 +- 3 files changed, 368 insertions(+), 84 deletions(-) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index c30bb7cb6c..91bb9d21c4 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -43,6 +43,7 @@ config RISCV_VIRT select SERIAL select RISCV_ACLINT select RISCV_APLIC + select RISCV_IMSIC select SIFIVE_PLIC select SIFIVE_TEST select VIRTIO_MMIO diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 45d85d274f..73b2be7b60 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -34,6 +34,7 @@ #include "hw/riscv/numa.h" #include "hw/intc/riscv_aclint.h" #include "hw/intc/riscv_aplic.h" +#include "hw/intc/riscv_imsic.h" #include "hw/intc/sifive_plic.h" #include "hw/misc/sifive_test.h" #include "chardev/char.h" @@ -43,6 +44,18 @@ #include "hw/pci-host/gpex.h" #include "hw/display/ramfb.h" +#define VIRT_IMSIC_GROUP_MAX_SIZE (1U << IMSIC_MMIO_GROUP_MIN_SHIFT) +#if VIRT_IMSIC_GROUP_MAX_SIZE < \ + IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS) +#error "Can't accomodate single IMSIC group in address space" +#endif + +#define VIRT_IMSIC_MAX_SIZE (VIRT_SOCKETS_MAX * \ + VIRT_IMSIC_GROUP_MAX_SIZE) +#if 0x4000000 < VIRT_IMSIC_MAX_SIZE +#error "Can't accomodate all IMSIC groups in address space" +#endif + static const MemMapEntry virt_memmap[] = { [VIRT_DEBUG] = { 0x0, 0x100 }, [VIRT_MROM] = { 0x1000, 0xf000 }, @@ -58,6 +71,8 @@ static const MemMapEntry virt_memmap[] = { [VIRT_VIRTIO] = { 0x10001000, 0x1000 }, [VIRT_FW_CFG] = { 0x10100000, 0x18 }, [VIRT_FLASH] = { 0x20000000, 0x4000000 }, + [VIRT_IMSIC_M] = { 0x24000000, VIRT_IMSIC_MAX_SIZE }, + [VIRT_IMSIC_S] = { 0x28000000, VIRT_IMSIC_MAX_SIZE }, [VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 }, [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 }, [VIRT_DRAM] = { 0x80000000, 0x0 }, @@ -309,7 +324,7 @@ static void create_fdt_socket_aclint(RISCVVirtState *s, { int cpu; char *name; - unsigned long addr; + unsigned long addr, size; uint32_t aclint_cells_size; uint32_t *aclint_mswi_cells; uint32_t *aclint_sswi_cells; @@ -330,29 +345,38 @@ static void create_fdt_socket_aclint(RISCVVirtState *s, } aclint_cells_size = s->soc[socket].num_harts * sizeof(uint32_t) * 2; - addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket); - name = g_strdup_printf("/soc/mswi@%lx", addr); - qemu_fdt_add_subnode(mc->fdt, name); - qemu_fdt_setprop_string(mc->fdt, name, "compatible", "riscv,aclint-mswi"); - qemu_fdt_setprop_cells(mc->fdt, name, "reg", - 0x0, addr, 0x0, RISCV_ACLINT_SWI_SIZE); - qemu_fdt_setprop(mc->fdt, name, "interrupts-extended", - aclint_mswi_cells, aclint_cells_size); - qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0); - qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0); - riscv_socket_fdt_write_id(mc, mc->fdt, name, socket); - g_free(name); + if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) { + addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket); + name = g_strdup_printf("/soc/mswi@%lx", addr); + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", + "riscv,aclint-mswi"); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", + 0x0, addr, 0x0, RISCV_ACLINT_SWI_SIZE); + qemu_fdt_setprop(mc->fdt, name, "interrupts-extended", + aclint_mswi_cells, aclint_cells_size); + qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0); + riscv_socket_fdt_write_id(mc, mc->fdt, name, socket); + g_free(name); + } - addr = memmap[VIRT_CLINT].base + RISCV_ACLINT_SWI_SIZE + - (memmap[VIRT_CLINT].size * socket); + if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { + addr = memmap[VIRT_CLINT].base + + (RISCV_ACLINT_DEFAULT_MTIMER_SIZE * socket); + size = RISCV_ACLINT_DEFAULT_MTIMER_SIZE; + } else { + addr = memmap[VIRT_CLINT].base + RISCV_ACLINT_SWI_SIZE + + (memmap[VIRT_CLINT].size * socket); + size = memmap[VIRT_CLINT].size - RISCV_ACLINT_SWI_SIZE; + } name = g_strdup_printf("/soc/mtimer@%lx", addr); qemu_fdt_add_subnode(mc->fdt, name); qemu_fdt_setprop_string(mc->fdt, name, "compatible", "riscv,aclint-mtimer"); qemu_fdt_setprop_cells(mc->fdt, name, "reg", 0x0, addr + RISCV_ACLINT_DEFAULT_MTIME, - 0x0, memmap[VIRT_CLINT].size - RISCV_ACLINT_SWI_SIZE - - RISCV_ACLINT_DEFAULT_MTIME, + 0x0, size - RISCV_ACLINT_DEFAULT_MTIME, 0x0, addr + RISCV_ACLINT_DEFAULT_MTIMECMP, 0x0, RISCV_ACLINT_DEFAULT_MTIME); qemu_fdt_setprop(mc->fdt, name, "interrupts-extended", @@ -360,19 +384,22 @@ static void create_fdt_socket_aclint(RISCVVirtState *s, riscv_socket_fdt_write_id(mc, mc->fdt, name, socket); g_free(name); - addr = memmap[VIRT_ACLINT_SSWI].base + - (memmap[VIRT_ACLINT_SSWI].size * socket); - name = g_strdup_printf("/soc/sswi@%lx", addr); - qemu_fdt_add_subnode(mc->fdt, name); - qemu_fdt_setprop_string(mc->fdt, name, "compatible", "riscv,aclint-sswi"); - qemu_fdt_setprop_cells(mc->fdt, name, "reg", - 0x0, addr, 0x0, memmap[VIRT_ACLINT_SSWI].size); - qemu_fdt_setprop(mc->fdt, name, "interrupts-extended", - aclint_sswi_cells, aclint_cells_size); - qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0); - qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0); - riscv_socket_fdt_write_id(mc, mc->fdt, name, socket); - g_free(name); + if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) { + addr = memmap[VIRT_ACLINT_SSWI].base + + (memmap[VIRT_ACLINT_SSWI].size * socket); + name = g_strdup_printf("/soc/sswi@%lx", addr); + qemu_fdt_add_subnode(mc->fdt, name); + qemu_fdt_setprop_string(mc->fdt, name, "compatible", + "riscv,aclint-sswi"); + qemu_fdt_setprop_cells(mc->fdt, name, "reg", + 0x0, addr, 0x0, memmap[VIRT_ACLINT_SSWI].size); + qemu_fdt_setprop(mc->fdt, name, "interrupts-extended", + aclint_sswi_cells, aclint_cells_size); + qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0); + qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0); + riscv_socket_fdt_write_id(mc, mc->fdt, name, socket); + g_free(name); + } g_free(aclint_mswi_cells); g_free(aclint_mtimer_cells); @@ -425,10 +452,145 @@ static void create_fdt_socket_plic(RISCVVirtState *s, g_free(plic_cells); } -static void create_fdt_socket_aia(RISCVVirtState *s, - const MemMapEntry *memmap, int socket, - uint32_t *phandle, uint32_t *intc_phandles, - uint32_t *aplic_phandles) +static uint32_t imsic_num_bits(uint32_t count) +{ + uint32_t ret = 0; + + while (BIT(ret) < count) { + ret++; + } + + return ret; +} + +static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap, + uint32_t *phandle, uint32_t *intc_phandles, + uint32_t *msi_m_phandle, uint32_t *msi_s_phandle) +{ + int cpu, socket; + char *imsic_name; + MachineState *mc = MACHINE(s); + uint32_t imsic_max_hart_per_socket, imsic_guest_bits; + uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size; + + *msi_m_phandle = (*phandle)++; + *msi_s_phandle = (*phandle)++; + imsic_cells = g_new0(uint32_t, mc->smp.cpus * 2); + imsic_regs = g_new0(uint32_t, riscv_socket_count(mc) * 4); + + /* M-level IMSIC node */ + for (cpu = 0; cpu < mc->smp.cpus; cpu++) { + imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); + imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT); + } + imsic_max_hart_per_socket = 0; + for (socket = 0; socket < riscv_socket_count(mc); socket++) { + imsic_addr = memmap[VIRT_IMSIC_M].base + + socket * VIRT_IMSIC_GROUP_MAX_SIZE; + imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts; + imsic_regs[socket * 4 + 0] = 0; + imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr); + imsic_regs[socket * 4 + 2] = 0; + imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size); + if (imsic_max_hart_per_socket < s->soc[socket].num_harts) { + imsic_max_hart_per_socket = s->soc[socket].num_harts; + } + } + imsic_name = g_strdup_printf("/soc/imsics@%lx", + memmap[VIRT_IMSIC_M].base); + qemu_fdt_add_subnode(mc->fdt, imsic_name); + qemu_fdt_setprop_string(mc->fdt, imsic_name, "compatible", + "riscv,imsics"); + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "#interrupt-cells", + FDT_IMSIC_INT_CELLS); + qemu_fdt_setprop(mc->fdt, imsic_name, "interrupt-controller", + NULL, 0); + qemu_fdt_setprop(mc->fdt, imsic_name, "msi-controller", + NULL, 0); + qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended", + imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2); + qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs, + riscv_socket_count(mc) * sizeof(uint32_t) * 4); + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids", + VIRT_IRQCHIP_NUM_MSIS); + qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id", + VIRT_IRQCHIP_IPI_MSI); + if (riscv_socket_count(mc) > 1) { + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits", + imsic_num_bits(imsic_max_hart_per_socket)); + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits", + imsic_num_bits(riscv_socket_count(mc))); + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift", + IMSIC_MMIO_GROUP_MIN_SHIFT); + } + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_m_phandle); + g_free(imsic_name); + + /* S-level IMSIC node */ + for (cpu = 0; cpu < mc->smp.cpus; cpu++) { + imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); + imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT); + } + imsic_guest_bits = imsic_num_bits(s->aia_guests + 1); + imsic_max_hart_per_socket = 0; + for (socket = 0; socket < riscv_socket_count(mc); socket++) { + imsic_addr = memmap[VIRT_IMSIC_S].base + + socket * VIRT_IMSIC_GROUP_MAX_SIZE; + imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) * + s->soc[socket].num_harts; + imsic_regs[socket * 4 + 0] = 0; + imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr); + imsic_regs[socket * 4 + 2] = 0; + imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size); + if (imsic_max_hart_per_socket < s->soc[socket].num_harts) { + imsic_max_hart_per_socket = s->soc[socket].num_harts; + } + } + imsic_name = g_strdup_printf("/soc/imsics@%lx", + memmap[VIRT_IMSIC_S].base); + qemu_fdt_add_subnode(mc->fdt, imsic_name); + qemu_fdt_setprop_string(mc->fdt, imsic_name, "compatible", + "riscv,imsics"); + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "#interrupt-cells", + FDT_IMSIC_INT_CELLS); + qemu_fdt_setprop(mc->fdt, imsic_name, "interrupt-controller", + NULL, 0); + qemu_fdt_setprop(mc->fdt, imsic_name, "msi-controller", + NULL, 0); + qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended", + imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2); + qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs, + riscv_socket_count(mc) * sizeof(uint32_t) * 4); + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids", + VIRT_IRQCHIP_NUM_MSIS); + qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id", + VIRT_IRQCHIP_IPI_MSI); + if (imsic_guest_bits) { + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits", + imsic_guest_bits); + } + if (riscv_socket_count(mc) > 1) { + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits", + imsic_num_bits(imsic_max_hart_per_socket)); + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits", + imsic_num_bits(riscv_socket_count(mc))); + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift", + IMSIC_MMIO_GROUP_MIN_SHIFT); + } + qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_s_phandle); + g_free(imsic_name); + + g_free(imsic_regs); + g_free(imsic_cells); +} + +static void create_fdt_socket_aplic(RISCVVirtState *s, + const MemMapEntry *memmap, int socket, + uint32_t msi_m_phandle, + uint32_t msi_s_phandle, + uint32_t *phandle, + uint32_t *intc_phandles, + uint32_t *aplic_phandles) { int cpu; char *aplic_name; @@ -454,8 +616,13 @@ static void create_fdt_socket_aia(RISCVVirtState *s, qemu_fdt_setprop_cell(mc->fdt, aplic_name, "#interrupt-cells", FDT_APLIC_INT_CELLS); qemu_fdt_setprop(mc->fdt, aplic_name, "interrupt-controller", NULL, 0); - qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended", - aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2); + if (s->aia_type == VIRT_AIA_TYPE_APLIC) { + qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended", + aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2); + } else { + qemu_fdt_setprop_cell(mc->fdt, aplic_name, "msi-parent", + msi_m_phandle); + } qemu_fdt_setprop_cells(mc->fdt, aplic_name, "reg", 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size); qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources", @@ -481,8 +648,13 @@ static void create_fdt_socket_aia(RISCVVirtState *s, qemu_fdt_setprop_cell(mc->fdt, aplic_name, "#interrupt-cells", FDT_APLIC_INT_CELLS); qemu_fdt_setprop(mc->fdt, aplic_name, "interrupt-controller", NULL, 0); - qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended", - aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2); + if (s->aia_type == VIRT_AIA_TYPE_APLIC) { + qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended", + aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2); + } else { + qemu_fdt_setprop_cell(mc->fdt, aplic_name, "msi-parent", + msi_s_phandle); + } qemu_fdt_setprop_cells(mc->fdt, aplic_name, "reg", 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size); qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources", @@ -499,13 +671,14 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, bool is_32_bit, uint32_t *phandle, uint32_t *irq_mmio_phandle, uint32_t *irq_pcie_phandle, - uint32_t *irq_virtio_phandle) + uint32_t *irq_virtio_phandle, + uint32_t *msi_pcie_phandle) { - int socket; char *clust_name; - uint32_t *intc_phandles; + int socket, phandle_pos; MachineState *mc = MACHINE(s); - uint32_t xplic_phandles[MAX_NODES]; + uint32_t msi_m_phandle = 0, msi_s_phandle = 0; + uint32_t *intc_phandles, xplic_phandles[MAX_NODES]; qemu_fdt_add_subnode(mc->fdt, "/cpus"); qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency", @@ -514,35 +687,53 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#address-cells", 0x1); qemu_fdt_add_subnode(mc->fdt, "/cpus/cpu-map"); + intc_phandles = g_new0(uint32_t, mc->smp.cpus); + + phandle_pos = mc->smp.cpus; for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) { + phandle_pos -= s->soc[socket].num_harts; + clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket); qemu_fdt_add_subnode(mc->fdt, clust_name); - intc_phandles = g_new0(uint32_t, s->soc[socket].num_harts); - create_fdt_socket_cpus(s, socket, clust_name, phandle, - is_32_bit, intc_phandles); + is_32_bit, &intc_phandles[phandle_pos]); create_fdt_socket_memory(s, memmap, socket); + g_free(clust_name); + if (s->have_aclint) { - create_fdt_socket_aclint(s, memmap, socket, intc_phandles); + create_fdt_socket_aclint(s, memmap, socket, + &intc_phandles[phandle_pos]); } else { - create_fdt_socket_clint(s, memmap, socket, intc_phandles); + create_fdt_socket_clint(s, memmap, socket, + &intc_phandles[phandle_pos]); } + } + + if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { + create_fdt_imsic(s, memmap, phandle, intc_phandles, + &msi_m_phandle, &msi_s_phandle); + *msi_pcie_phandle = msi_s_phandle; + } + + phandle_pos = mc->smp.cpus; + for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) { + phandle_pos -= s->soc[socket].num_harts; if (s->aia_type == VIRT_AIA_TYPE_NONE) { create_fdt_socket_plic(s, memmap, socket, phandle, - intc_phandles, xplic_phandles); + &intc_phandles[phandle_pos], xplic_phandles); } else { - create_fdt_socket_aia(s, memmap, socket, phandle, - intc_phandles, xplic_phandles); + create_fdt_socket_aplic(s, memmap, socket, + msi_m_phandle, msi_s_phandle, phandle, + &intc_phandles[phandle_pos], xplic_phandles); } - - g_free(intc_phandles); - g_free(clust_name); } + g_free(intc_phandles); + for (socket = 0; socket < riscv_socket_count(mc); socket++) { if (socket == 0) { *irq_mmio_phandle = xplic_phandles[socket]; @@ -590,7 +781,8 @@ static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap, } static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, - uint32_t irq_pcie_phandle) + uint32_t irq_pcie_phandle, + uint32_t msi_pcie_phandle) { char *name; MachineState *mc = MACHINE(s); @@ -610,6 +802,9 @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, qemu_fdt_setprop_cells(mc->fdt, name, "bus-range", 0, memmap[VIRT_PCIE_ECAM].size / PCIE_MMCFG_SIZE_MIN - 1); qemu_fdt_setprop(mc->fdt, name, "dma-coherent", NULL, 0); + if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { + qemu_fdt_setprop_cell(mc->fdt, name, "msi-parent", msi_pcie_phandle); + } qemu_fdt_setprop_cells(mc->fdt, name, "reg", 0, memmap[VIRT_PCIE_ECAM].base, 0, memmap[VIRT_PCIE_ECAM].size); qemu_fdt_setprop_sized_cells(mc->fdt, name, "ranges", @@ -735,7 +930,7 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, uint64_t mem_size, const char *cmdline, bool is_32_bit) { MachineState *mc = MACHINE(s); - uint32_t phandle = 1, irq_mmio_phandle = 1; + uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1; uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1; if (mc->dtb) { @@ -765,11 +960,12 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, qemu_fdt_setprop_cell(mc->fdt, "/soc", "#address-cells", 0x2); create_fdt_sockets(s, memmap, is_32_bit, &phandle, - &irq_mmio_phandle, &irq_pcie_phandle, &irq_virtio_phandle); + &irq_mmio_phandle, &irq_pcie_phandle, &irq_virtio_phandle, + &msi_pcie_phandle); create_fdt_virtio(s, memmap, irq_virtio_phandle); - create_fdt_pcie(s, memmap, irq_pcie_phandle); + create_fdt_pcie(s, memmap, irq_pcie_phandle, msi_pcie_phandle); create_fdt_reset(s, memmap, &phandle); @@ -884,30 +1080,55 @@ static DeviceState *virt_create_plic(const MemMapEntry *memmap, int socket, return ret; } -static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, +static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests, const MemMapEntry *memmap, int socket, int base_hartid, int hart_count) { + int i; + hwaddr addr; + uint32_t guest_bits; DeviceState *aplic_m; + bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false; + + if (msimode) { + /* Per-socket M-level IMSICs */ + addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE; + for (i = 0; i < hart_count; i++) { + riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0), + base_hartid + i, true, 1, + VIRT_IRQCHIP_NUM_MSIS); + } + + /* Per-socket S-level IMSICs */ + guest_bits = imsic_num_bits(aia_guests + 1); + addr = memmap[VIRT_IMSIC_S].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE; + for (i = 0; i < hart_count; i++) { + riscv_imsic_create(addr + i * IMSIC_HART_SIZE(guest_bits), + base_hartid + i, false, 1 + aia_guests, + VIRT_IRQCHIP_NUM_MSIS); + } + } /* Per-socket M-level APLIC */ aplic_m = riscv_aplic_create( memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size, memmap[VIRT_APLIC_M].size, - base_hartid, hart_count, + (msimode) ? 0 : base_hartid, + (msimode) ? 0 : hart_count, VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_PRIO_BITS, - false, true, NULL); + msimode, true, NULL); if (aplic_m) { /* Per-socket S-level APLIC */ riscv_aplic_create( memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size, memmap[VIRT_APLIC_S].size, - base_hartid, hart_count, + (msimode) ? 0 : base_hartid, + (msimode) ? 0 : hart_count, VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_PRIO_BITS, - false, false, aplic_m); + msimode, false, aplic_m); } return aplic_m; @@ -966,23 +1187,38 @@ static void virt_machine_init(MachineState *machine) hart_count, &error_abort); sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort); - /* Per-socket CLINT */ - riscv_aclint_swi_create( - memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size, - base_hartid, hart_count, false); - riscv_aclint_mtimer_create( - memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size + - RISCV_ACLINT_SWI_SIZE, - RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count, - RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME, - RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true); - - /* Per-socket ACLINT SSWI */ if (s->have_aclint) { + if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { + /* Per-socket ACLINT MTIMER */ + riscv_aclint_mtimer_create(memmap[VIRT_CLINT].base + + i * RISCV_ACLINT_DEFAULT_MTIMER_SIZE, + RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count, + RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME, + RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true); + } else { + /* Per-socket ACLINT MSWI, MTIMER, and SSWI */ + riscv_aclint_swi_create(memmap[VIRT_CLINT].base + + i * memmap[VIRT_CLINT].size, + base_hartid, hart_count, false); + riscv_aclint_mtimer_create(memmap[VIRT_CLINT].base + + i * memmap[VIRT_CLINT].size + RISCV_ACLINT_SWI_SIZE, + RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count, + RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME, + RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true); + riscv_aclint_swi_create(memmap[VIRT_ACLINT_SSWI].base + + i * memmap[VIRT_ACLINT_SSWI].size, + base_hartid, hart_count, true); + } + } else { + /* Per-socket SiFive CLINT */ riscv_aclint_swi_create( - memmap[VIRT_ACLINT_SSWI].base + - i * memmap[VIRT_ACLINT_SSWI].size, - base_hartid, hart_count, true); + memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size, + base_hartid, hart_count, false); + riscv_aclint_mtimer_create(memmap[VIRT_CLINT].base + + i * memmap[VIRT_CLINT].size + RISCV_ACLINT_SWI_SIZE, + RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count, + RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME, + RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true); } /* Per-socket interrupt controller */ @@ -990,8 +1226,9 @@ static void virt_machine_init(MachineState *machine) s->irqchip[i] = virt_create_plic(memmap, i, base_hartid, hart_count); } else { - s->irqchip[i] = virt_create_aia(s->aia_type, memmap, i, - base_hartid, hart_count); + s->irqchip[i] = virt_create_aia(s->aia_type, s->aia_guests, + memmap, i, base_hartid, + hart_count); } /* Try to use different IRQCHIP instance based device type */ @@ -1138,6 +1375,27 @@ static void virt_machine_instance_init(Object *obj) { } +static char *virt_get_aia_guests(Object *obj, Error **errp) +{ + RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); + char val[32]; + + sprintf(val, "%d", s->aia_guests); + return g_strdup(val); +} + +static void virt_set_aia_guests(Object *obj, const char *val, Error **errp) +{ + RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); + + s->aia_guests = atoi(val); + if (s->aia_guests < 0 || s->aia_guests > VIRT_IRQCHIP_MAX_GUESTS) { + error_setg(errp, "Invalid number of AIA IMSIC guests"); + error_append_hint(errp, "Valid values be between 0 and %d.\n", + VIRT_IRQCHIP_MAX_GUESTS); + } +} + static char *virt_get_aia(Object *obj, Error **errp) { RISCVVirtState *s = RISCV_VIRT_MACHINE(obj); @@ -1147,6 +1405,9 @@ static char *virt_get_aia(Object *obj, Error **errp) case VIRT_AIA_TYPE_APLIC: val = "aplic"; break; + case VIRT_AIA_TYPE_APLIC_IMSIC: + val = "aplic-imsic"; + break; default: val = "none"; break; @@ -1163,9 +1424,12 @@ static void virt_set_aia(Object *obj, const char *val, Error **errp) s->aia_type = VIRT_AIA_TYPE_NONE; } else if (!strcmp(val, "aplic")) { s->aia_type = VIRT_AIA_TYPE_APLIC; + } else if (!strcmp(val, "aplic-imsic")) { + s->aia_type = VIRT_AIA_TYPE_APLIC_IMSIC; } else { error_setg(errp, "Invalid AIA interrupt controller type"); - error_append_hint(errp, "Valid values are none, and aplic.\n"); + error_append_hint(errp, "Valid values are none, aplic, and " + "aplic-imsic.\n"); } } @@ -1187,6 +1451,7 @@ static void virt_set_aclint(Object *obj, bool value, Error **errp) static void virt_machine_class_init(ObjectClass *oc, void *data) { + char str[128]; MachineClass *mc = MACHINE_CLASS(oc); mc->desc = "RISC-V VirtIO board"; @@ -1213,7 +1478,14 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) object_class_property_set_description(oc, "aia", "Set type of AIA interrupt " "conttoller. Valid values are " - "none, and aplic."); + "none, aplic, and aplic-imsic."); + + object_class_property_add_str(oc, "aia-guests", + virt_get_aia_guests, + virt_set_aia_guests); + sprintf(str, "Set number of guest MMIO pages for AIA IMSIC. Valid value " + "should be between 0 and %d.", VIRT_IRQCHIP_MAX_GUESTS); + object_class_property_set_description(oc, "aia-guests", str); } static const TypeInfo virt_machine_typeinfo = { diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 4584042090..7898c574af 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -24,8 +24,10 @@ #include "hw/block/flash.h" #include "qom/object.h" -#define VIRT_CPUS_MAX 32 -#define VIRT_SOCKETS_MAX 8 +#define VIRT_CPUS_MAX_BITS 3 +#define VIRT_CPUS_MAX (1 << VIRT_CPUS_MAX_BITS) +#define VIRT_SOCKETS_MAX_BITS 2 +#define VIRT_SOCKETS_MAX (1 << VIRT_SOCKETS_MAX_BITS) #define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("virt") typedef struct RISCVVirtState RISCVVirtState; @@ -35,6 +37,7 @@ DECLARE_INSTANCE_CHECKER(RISCVVirtState, RISCV_VIRT_MACHINE, typedef enum RISCVVirtAIAType { VIRT_AIA_TYPE_NONE=0, VIRT_AIA_TYPE_APLIC, + VIRT_AIA_TYPE_APLIC_IMSIC, } RISCVVirtAIAType; struct RISCVVirtState { @@ -50,6 +53,7 @@ struct RISCVVirtState { int fdt_size; bool have_aclint; RISCVVirtAIAType aia_type; + int aia_guests; }; enum { @@ -65,6 +69,8 @@ enum { VIRT_UART0, VIRT_VIRTIO, VIRT_FW_CFG, + VIRT_IMSIC_M, + VIRT_IMSIC_S, VIRT_FLASH, VIRT_DRAM, VIRT_PCIE_MMIO, @@ -81,8 +87,12 @@ enum { VIRTIO_NDEV = 0x35 /* Arbitrary maximum number of interrupts */ }; -#define VIRT_IRQCHIP_NUM_SOURCES 127 +#define VIRT_IRQCHIP_IPI_MSI 1 +#define VIRT_IRQCHIP_NUM_MSIS 255 +#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV #define VIRT_IRQCHIP_NUM_PRIO_BITS 3 +#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3 +#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U) #define VIRT_PLIC_PRIORITY_BASE 0x04 #define VIRT_PLIC_PENDING_BASE 0x1000 @@ -97,6 +107,7 @@ enum { #define FDT_PCI_INT_CELLS 1 #define FDT_PLIC_INT_CELLS 1 #define FDT_APLIC_INT_CELLS 2 +#define FDT_IMSIC_INT_CELLS 0 #define FDT_MAX_INT_CELLS 2 #define FDT_MAX_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \ 1 + FDT_MAX_INT_CELLS) From patchwork Mon Jan 17 13:28:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715455 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 25387C433F5 for ; Mon, 17 Jan 2022 14:26:53 +0000 (UTC) Received: from localhost ([::1]:57774 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9SyC-0000ne-11 for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:26:52 -0500 Received: from eggs.gnu.org ([209.51.188.92]:40964) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9SCz-0006Wa-Tz for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:38:06 -0500 Received: from [2607:f8b0:4864:20::62d] (port=34487 helo=mail-pl1-x62d.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9SCx-0002V9-6v for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:38:04 -0500 Received: by mail-pl1-x62d.google.com with SMTP id a7so18507581plh.1 for ; Mon, 17 Jan 2022 05:38:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qEJf89SevVQot2Hj3ZJkC4AKQIDCORDOul1GSl8azAo=; b=PBO41w1f7KyjSi3ltr5jfWLTf6tOq00KWOWkK47luy2WjglhssEACIYw6YNk0B94zL IAfagHzYwwfweAPFAemyCBISo+GcA2t21ZeL8sh6yiANh8ezA73LQEDmM69f5fDcOOMi Rdfa7hme3iqT/gf6YRi6rQIKGJWKfyZ3EfdzhUI0jExQXJT4Ma+7cBrFXJ8a0zgSjdsl rM8pKM9MoESYMxfj++bdvFfnHLQnXHViIqDFi+5urB6JZm1nZI1As8i6KxrCiJmQu7Mb 6n1INj3RTzE0cgXyK0uBBM8dz2jSlMiIdkab5dJ1u7cMR8AU1Vr4yzbyy3oI19bsTdMK 8C6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qEJf89SevVQot2Hj3ZJkC4AKQIDCORDOul1GSl8azAo=; b=XoFSdhPRV6aC/4OlIatGru4nXr0KQgHVb+A7LG7gkvvyOhswRwGNrHF0QrThp+JEMF pMiH5ln3jKBRc8ShW6QBkTPzASubpDOmSp/X2rypXgNzJ8wcFYDcQoAP/YMdNoTvXqHP G2SSHAuzv1Ymqk1L7y/inps26MNKYC9N7i8pTwe3LQx0BTJRNpgtPZ7pyZHPA9iiWRzF I8Dlvtsjd8vobYdYjr34TCtD5EucEk11nUU5R8mU0Du1U7USXBknfyVynQQXn9DZ4w+z rQIpmsEb+aeezolseKWxc7vrme302xQooB7S/jbfsfjIrPJUvrfpAMCtGLEtJJlp9Eml Wcbg== X-Gm-Message-State: AOAM532vRRfam7Gu+u6dNogcrhAKhQNQNAtaOJtRTpKdu1Pq1EmokH6I 0lj4Y0r5U4PgyzBaF2J1hNcuO3hTplUcrQ== X-Google-Smtp-Source: ABdhPJypn6ZJztkfH4qe/Z+muk/uatFPLpF6ktH9QijxXhY/ImneVw27USSeUGrV1S73mSthVEmf2Q== X-Received: by 2002:a17:903:11c5:b0:149:a8cf:37da with SMTP id q5-20020a17090311c500b00149a8cf37damr22626511plh.132.1642426244369; Mon, 17 Jan 2022 05:30:44 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:43 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 22/23] docs/system: riscv: Document AIA options for virt machine Date: Mon, 17 Jan 2022 18:58:25 +0530 Message-Id: <20220117132826.426418-23-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::62d (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::62d; envelope-from=anup@brainfault.org; helo=mail-pl1-x62d.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel We have two new machine options "aia" and "aia-guests" available for the RISC-V virt machine so let's document these options. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- docs/system/riscv/virt.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst index fa016584bf..373645513a 100644 --- a/docs/system/riscv/virt.rst +++ b/docs/system/riscv/virt.rst @@ -63,6 +63,22 @@ The following machine-specific options are supported: When this option is "on", ACLINT devices will be emulated instead of SiFive CLINT. When not specified, this option is assumed to be "off". +- aia=[none|aplic|aplic-imsic] + + This option allows selecting interrupt controller defined by the AIA + (advanced interrupt architecture) specification. The "aia=aplic" selects + APLIC (advanced platform level interrupt controller) to handle wired + interrupts whereas the "aia=aplic-imsic" selects APLIC and IMSIC (incoming + message signaled interrupt controller) to handle both wired interrupts and + MSIs. When not specified, this option is assumed to be "none" which selects + SiFive PLIC to handle wired interrupts. + +- aia-guests=nnn + + The number of per-HART VS-level AIA IMSIC pages to be emulated for a guest + having AIA IMSIC (i.e. "aia=aplic-imsic" selected). When not specified, + the default number of per-HART VS-level AIA IMSIC pages is 0. + Running Linux kernel -------------------- From patchwork Mon Jan 17 13:28:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anup Patel X-Patchwork-Id: 12715500 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id B012EC433EF for ; Mon, 17 Jan 2022 14:57:37 +0000 (UTC) Received: from localhost ([::1]:36796 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1n9TRw-00029l-LE for qemu-devel@archiver.kernel.org; Mon, 17 Jan 2022 09:57:36 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39228) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1n9S5z-0001V1-Fy for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:52 -0500 Received: from [2607:f8b0:4864:20::636] (port=34447 helo=mail-pl1-x636.google.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1n9S5x-0001Dm-Uf for qemu-devel@nongnu.org; Mon, 17 Jan 2022 08:30:51 -0500 Received: by mail-pl1-x636.google.com with SMTP id a7so18487610plh.1 for ; Mon, 17 Jan 2022 05:30:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brainfault-org.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OA9iVC50Z2hglMsbE8CcBP//fPzwzBLuLEryH2NJpNY=; b=ESDJM+V+pgLGt62npXJlUYSMR6vAeifl7hCVC4jpvqly6p/aSd1w1BmrCXMD0gMgc5 OeZr/G/RgFQ1CH80JYhhCP+0O2ifbFonb1t//XS+hzNoNEwZLLULoqarxHQUv6DwSUN2 p9zv+bZyGHcuozgZWqLJlF76V9oPJKED3ZbpdWacDCO/4TBCkjEDiTio3/Uh6n+AWjJu 2wH5T61+Ryz3AicFN8ZZ9mH+BPNsu8wSWxpvZzeasSy64Ln2oFeiGjLzvwttip9hWm/m 0OZWLBkHVmrMgzygJa3c3pa935ArcWXjMObbace8KTzrDGi/aCiYCNL2QcBtLfbOp+hW z87g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OA9iVC50Z2hglMsbE8CcBP//fPzwzBLuLEryH2NJpNY=; b=7bu3egB8RXVkdQnqYlllu2OVK8d3YaZopPwtdWSgBjyA7x0QlyovdTM6hQUG65rmQg s3E0UDORWXGvKTqyBw1f7pb2gmTfui4XI47EnRcqtBCbf5Vr86QnL1Mjv9HoNkJE0GcH LAnNJJBy495MWuwfEnZmfmjCNzg7wzmMkykA6fYiETncEjL9zkcvJpmM7OzU0HYL0f1t iVBed2SmrynUJ3VktpFFLvm2FsgfxrPaGoFdIPYuN8oL8lGbkysI7qtz7AWZSgCtbWyU G0p8IZlML313bpSw/8mA2th9gpU5/OpPgH6T8vrjcBzQPIsDKIWwkNzD0djgFbr7AXUt vE4w== X-Gm-Message-State: AOAM533KWZnxx6pSDw5nU+VVInBO1oyOpiFNglIUvM3oewpR0kSQFZWW 2Mnjov2G17/rWVKGjDCt9cxxdQ== X-Google-Smtp-Source: ABdhPJwgLuTzNbJiKYNT3zQSHCvnRsXw3WgP5W1vysBauUI0uuV4rTVfEEyfRDR10atwroLck5j59w== X-Received: by 2002:a17:902:c106:b0:14a:7c95:1b0 with SMTP id 6-20020a170902c10600b0014a7c9501b0mr21768265pli.112.1642426248656; Mon, 17 Jan 2022 05:30:48 -0800 (PST) Received: from localhost.localdomain ([122.179.70.109]) by smtp.gmail.com with ESMTPSA id 7sm9532607pfm.25.2022.01.17.05.30.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Jan 2022 05:30:47 -0800 (PST) From: Anup Patel To: Peter Maydell , Palmer Dabbelt , Alistair Francis , Sagar Karandikar Subject: [PATCH v7 23/23] hw/riscv: virt: Increase maximum number of allowed CPUs Date: Mon, 17 Jan 2022 18:58:26 +0530 Message-Id: <20220117132826.426418-24-anup@brainfault.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220117132826.426418-1-anup@brainfault.org> References: <20220117132826.426418-1-anup@brainfault.org> MIME-Version: 1.0 X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::636 (failed) Received-SPF: none client-ip=2607:f8b0:4864:20::636; envelope-from=anup@brainfault.org; helo=mail-pl1-x636.google.com X-Spam_score_int: -10 X-Spam_score: -1.1 X-Spam_bar: - X-Spam_report: (-1.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, PDS_HP_HELO_NORDNS=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-riscv@nongnu.org, Frank Chang , Anup Patel , qemu-devel@nongnu.org, Alistair Francis , Atish Patra , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Anup Patel To facilitate software development of RISC-V systems with large number of HARTs, we increase the maximum number of allowed CPUs to 512 (2^9). We also add a detailed source level comments about limit defines which impact the physical address space utilization. Signed-off-by: Anup Patel Signed-off-by: Anup Patel Reviewed-by: Alistair Francis Reviewed-by: Frank Chang --- hw/riscv/virt.c | 10 ++++++++++ include/hw/riscv/virt.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 73b2be7b60..f9cf7551b4 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -44,6 +44,16 @@ #include "hw/pci-host/gpex.h" #include "hw/display/ramfb.h" +/* + * The virt machine physical address space used by some of the devices + * namely ACLINT, PLIC, APLIC, and IMSIC depend on number of Sockets, + * number of CPUs, and number of IMSIC guest files. + * + * Various limits defined by VIRT_SOCKETS_MAX_BITS, VIRT_CPUS_MAX_BITS, + * and VIRT_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization + * of virt machine physical address space. + */ + #define VIRT_IMSIC_GROUP_MAX_SIZE (1U << IMSIC_MMIO_GROUP_MIN_SHIFT) #if VIRT_IMSIC_GROUP_MAX_SIZE < \ IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS) diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 7898c574af..78f450eb60 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -24,7 +24,7 @@ #include "hw/block/flash.h" #include "qom/object.h" -#define VIRT_CPUS_MAX_BITS 3 +#define VIRT_CPUS_MAX_BITS 9 #define VIRT_CPUS_MAX (1 << VIRT_CPUS_MAX_BITS) #define VIRT_SOCKETS_MAX_BITS 2 #define VIRT_SOCKETS_MAX (1 << VIRT_SOCKETS_MAX_BITS)