From patchwork Mon Oct 16 11:17:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13423042 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 341BACDB483 for ; Mon, 16 Oct 2023 11:19:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qsLbq-0002f2-LK; Mon, 16 Oct 2023 07:18:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qsLbm-0002c0-LX for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:02 -0400 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qsLbb-0005al-E3 for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:02 -0400 Received: by mail-wr1-x42b.google.com with SMTP id ffacd0b85a97d-32daeed7771so1090260f8f.3 for ; Mon, 16 Oct 2023 04:17:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1697455062; x=1698059862; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JtzE7my5CmntemfMbbeAb9YICyfQZm1oiOKZ3Hj4AGc=; b=p8dHivGO1RqxnIMHYrGdd/2d4TiimOGSI4vwQdEuyW//9rSl+NhG+WgXi2j0EEKpPv erq6sw+Kt9NGT3roXXhiWwME4cBQx/lOxgX8OybgW0bfkZDow6ydRazRgbkUkIsDSGOk ZOZNm/YtUIz2Y+tBgxMJV6mpworB2tLDxWshE1QQXCsZl9cccpP3CG2kG14kEncq9Yqc RL3KpdoQBpVXXgSs+G0x4l49TaU9Nlv70CnGi6olC0vKvURwmcO2AQyXKhIUugav7K2B fXB7G5CKKmz8mvc3zECMcDu+0KE2EjjX1VU2AWac3JUlxnI0IAqMMlbnOA+VuH1WvV0L lbvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697455062; x=1698059862; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JtzE7my5CmntemfMbbeAb9YICyfQZm1oiOKZ3Hj4AGc=; b=e58wq872VEfzLmZroZ0uYmfPa0EkNno8bgBRorMxGNu+m3tXW2ZA4hof9oeKfs5TKJ LWakIs/wP/xPKTyjyhif4VvmNSVn+HlNWdjkUBZsLXy/KGWvjAo4J2hkrFNMntC95j++ M4vnpAwej3fpS7b6G+nRZPfnzGs5ZTzXYyH6F5LbirODBZ9GF+junoG5W2NaEi5oh05u BDe0xE/BtajxpmugXja2nLXPHDxFZcgvoDlhFLGsiefH3gz4LoJfmoIGBqmxqxSC004I 10sTWqn5lVZAA1Ct9AZiGJt7Qxb5AgCXGuub2+d5kSkqapgf6xa/tJjDJ+tvwZTK+hCj NCww== X-Gm-Message-State: AOJu0Yzr6u/FVyQNJjSyGRkpKS5XBivVtLpcgmP6Fi+9441IetUGPu+0 nCZJkt6ZUDEYK7wxE0vqvqn5ww== X-Google-Smtp-Source: AGHT+IHt7zBM7oq34Pt1GjqiaqFwpNreACl3dteb8CaiNPSQ8zXFjZXR0Nrv3tRDWkh7QnITBrajQA== X-Received: by 2002:adf:f2ce:0:b0:32d:9fc9:d14a with SMTP id d14-20020adff2ce000000b0032d9fc9d14amr6477524wrp.12.1697455061845; Mon, 16 Oct 2023 04:17:41 -0700 (PDT) Received: from localhost.localdomain (cpc91760-watf12-2-0-cust235.15-2.cable.virginm.net. [81.111.69.236]) by smtp.gmail.com with ESMTPSA id o15-20020a056000010f00b0032daf848f68sm3114299wrx.59.2023.10.16.04.17.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 04:17:41 -0700 (PDT) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org Cc: palmer@dabbelt.com, alistair.francis@wdc.com, bin.meng@windriver.com, liweiwei@iscas.ac.cn, dbarboza@ventanamicro.com, zhiwei_liu@linux.alibaba.com, atishp@rivosinc.com, apatel@ventanamicro.com, rkanwal@rivosinc.com Subject: [PATCH v5 1/6] target/riscv: Without H-mode mask all HS mode inturrupts in mie. Date: Mon, 16 Oct 2023 12:17:31 +0100 Message-Id: <20231016111736.28721-2-rkanwal@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231016111736.28721-1-rkanwal@rivosinc.com> References: <20231016111736.28721-1-rkanwal@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42b; envelope-from=rkanwal@rivosinc.com; helo=mail-wr1-x42b.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Rajnesh Kanwal Reviewed-by: Alistair Francis --- 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 30cc21e979..4847b47a98 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1525,7 +1525,7 @@ static RISCVException rmw_mie64(CPURISCVState *env, int csrno, env->mie = (env->mie & ~mask) | (new_val & mask); if (!riscv_has_ext(env, RVH)) { - env->mie &= ~((uint64_t)MIP_SGEIP); + env->mie &= ~((uint64_t)HS_MODE_INTERRUPTS); } return RISCV_EXCP_NONE; From patchwork Mon Oct 16 11:17:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13423039 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 BB426CDB483 for ; Mon, 16 Oct 2023 11:18:54 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qsLbp-0002dh-Rk; Mon, 16 Oct 2023 07:18:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qsLbm-0002br-Ir for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:02 -0400 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qsLbb-0005az-E5 for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:02 -0400 Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-32d9effe314so2327108f8f.3 for ; Mon, 16 Oct 2023 04:17:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1697455063; x=1698059863; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9XGMvvJZUGfMnQ/1RecN9n7QRTY4rets8V/xDm2EU20=; b=AU8EidPETbWUhvO7T5gb33hDSaiSelnAYT+eZk2pBp7FcKEaVTY5+lTssMID2WedQQ tSltes8wT9nH6A6/fS0a56cSDFYGkyrd8+5GUfsWO1/BqsI5lYsz929EOliDwMh/q0B8 FHSETChHyEWkxMk/q3qSweCCNCNoSGAm4J0q3CkqKXkzlBYSNEIR3sgKvd+cR4Hk4iU2 LttNpcjTSnn2WLDb7zlTb2OJPvTmp9GkCygmlg2WW9PipRCL5RQ2iYS5ggsvwoPdgaKN WrRI6vE2cgP8qfqe7R3bvDPmld462jvru10YD9DdXY3JxK99G3VXPyWkwWHqR9H8VwCF RMUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697455063; x=1698059863; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9XGMvvJZUGfMnQ/1RecN9n7QRTY4rets8V/xDm2EU20=; b=qJlrR7UER3HyDf5V7HHoBMZX/FAZCYBeBNASXMMeYeisAuYDVNFcuaYmtcxuB+Budm FDFzqPsCwYcLjEvBD7mtYxOVYxmWanXd0pW46dR2F/gRErKW5mjmvI+sYPkKYsC/lJn0 fD2tcft3Gldwe7EZxqVe1AcH19ZUxItYqxRZGjI5iTKWQX7ajS6J9+NCDa0Ha/o69NpG fsSY0tUUJUlm9pcA4TXiqTSgt9LYUeJqwai0mecox4gV4TQ2IImSebHlFKsdqklpL+Ob OyLRuyE1ozQOANf9qccB+PfGnnQ/9VHzotj7HHhdd82sE7irP2pV1GF024sTszetASEE frfQ== X-Gm-Message-State: AOJu0YziWrY8ClPHXp1whAfX81IR/K73WE0qHAwxnBMceaQPE1nTRdSi Wu8uPxk+2kXJB/OOnZrpcpmTnw== X-Google-Smtp-Source: AGHT+IFQ2xP9mg6JJS2xUiKIqHOwwbYL8cijrH2V6O3hwT+E23v/6IUUZqEBnbp3w9PyKpI2sjzN7g== X-Received: by 2002:adf:e19d:0:b0:32c:ea14:89e5 with SMTP id az29-20020adfe19d000000b0032cea1489e5mr19215318wrb.39.1697455062837; Mon, 16 Oct 2023 04:17:42 -0700 (PDT) Received: from localhost.localdomain (cpc91760-watf12-2-0-cust235.15-2.cable.virginm.net. [81.111.69.236]) by smtp.gmail.com with ESMTPSA id o15-20020a056000010f00b0032daf848f68sm3114299wrx.59.2023.10.16.04.17.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 04:17:42 -0700 (PDT) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org Cc: palmer@dabbelt.com, alistair.francis@wdc.com, bin.meng@windriver.com, liweiwei@iscas.ac.cn, dbarboza@ventanamicro.com, zhiwei_liu@linux.alibaba.com, atishp@rivosinc.com, apatel@ventanamicro.com, rkanwal@rivosinc.com Subject: [PATCH v5 2/6] target/riscv: Check for async flag in case of RISCV_EXCP_SEMIHOST. Date: Mon, 16 Oct 2023 12:17:32 +0100 Message-Id: <20231016111736.28721-3-rkanwal@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231016111736.28721-1-rkanwal@rivosinc.com> References: <20231016111736.28721-1-rkanwal@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=rkanwal@rivosinc.com; helo=mail-wr1-x431.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org RISCV_EXCP_SEMIHOST is set to 0x10, which can be a local interrupt id as well. This change moves RISCV_EXCP_SEMIHOST to switch case so that async flag check is performed before invoking semihosting logic. Signed-off-by: Rajnesh Kanwal Reviewed-by: Alistair Francis --- target/riscv/cpu_helper.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 8c28241c18..aaeb1d0d5c 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1605,15 +1605,13 @@ void riscv_cpu_do_interrupt(CPUState *cs) target_ulong htval = 0; target_ulong mtval2 = 0; - if (cause == RISCV_EXCP_SEMIHOST) { - do_common_semihosting(cs); - env->pc += 4; - return; - } - if (!async) { /* set tval to badaddr for traps with address information */ switch (cause) { + case RISCV_EXCP_SEMIHOST: + do_common_semihosting(cs); + env->pc += 4; + return; case RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT: case RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT: case RISCV_EXCP_LOAD_ADDR_MIS: From patchwork Mon Oct 16 11:17:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13423044 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 1105BCDB465 for ; Mon, 16 Oct 2023 11:19:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qsLbr-0002fE-ME; Mon, 16 Oct 2023 07:18:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qsLbn-0002d7-Um for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:03 -0400 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qsLbb-0005bR-Eh for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:03 -0400 Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-405361bb9f7so44316555e9.2 for ; Mon, 16 Oct 2023 04:17:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1697455064; x=1698059864; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=W+F6mdbwIf7VWgRHBUtKQ8tcMl+i/89eXu3BnJbXKMw=; b=TFrneycy72Aha6XCrYo9SRmzy7rB2+kATw51tjLD3UJVH4ZzKr/IYYpi0Gsbn/vEOl rNKsQaqpl6mMt4QLC6cXkidqiZ4YWw/oNcmjXw5DrhqW0ZIF4nI3WpDRGE5rE6ilgnXb VDsML+3Q6Mkv5rDXvC5Nlo85xCReQn6mi4elp2QygD+Ic1Hj2q4Rjpcj/V4pu4GBGVXI wKqnVHUNMwagY0eh6xzxdtuXaQKJ2M+VyMC1iU0WziquW4tpCdQaOl2/UoNmcJs/BIqE p6zBS4TieJM8h6qcMmZVhfQvSV5DjunY/bApR/DmquVZ9wTvvQMSf92ShmWvEML2ziHG ZpcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697455064; x=1698059864; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=W+F6mdbwIf7VWgRHBUtKQ8tcMl+i/89eXu3BnJbXKMw=; b=wxr4SAzksqEphdxKP24dtJC8Q3orLJ7oNWiheHODvuRk9stjCF3xO12tKEXc18Pg/+ 7jM+Lr7SFnhF7BsiYehO1THX/txJxMfhWOCXjQHG3zdpw3H9vpTN12gXiPbLGuWbcmaG FPB8ywQTyo3Aau30PM2uAJpvgPFvL+goRFKgYWSllqizyFaifPJAWOoFqnwcmV82Lw/X 31AIABG4n/1+lPbjxN4XEYbIpp8IxAo+Qxfti2o7XLKEIaFAr3+WiBc4VX4LYpxqhti9 bXrM8rjgCxn9d6fSefL8AsAF9crhdK021uzOzhAk1s/WM8Pt5juCoxI+ctsF4MhuRwpm Atqg== X-Gm-Message-State: AOJu0Yxp6y2sX1E3/Qku4BhVhlVatMdheM9aFR57B8lxlOlJOARtubfN 3DZZ4kAizGY0OAu7uOSLnAumZg== X-Google-Smtp-Source: AGHT+IGjw+yNBUSw2WyVLNbPBUEyBJz1aOhbnaRjRqAfrxdXfvcyKdUHc2HQi/yvn0Dr88vFXCgP1w== X-Received: by 2002:a05:600c:2195:b0:406:53aa:7a5f with SMTP id e21-20020a05600c219500b0040653aa7a5fmr29442993wme.10.1697455063974; Mon, 16 Oct 2023 04:17:43 -0700 (PDT) Received: from localhost.localdomain (cpc91760-watf12-2-0-cust235.15-2.cable.virginm.net. [81.111.69.236]) by smtp.gmail.com with ESMTPSA id o15-20020a056000010f00b0032daf848f68sm3114299wrx.59.2023.10.16.04.17.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 04:17:43 -0700 (PDT) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org Cc: palmer@dabbelt.com, alistair.francis@wdc.com, bin.meng@windriver.com, liweiwei@iscas.ac.cn, dbarboza@ventanamicro.com, zhiwei_liu@linux.alibaba.com, atishp@rivosinc.com, apatel@ventanamicro.com, rkanwal@rivosinc.com Subject: [PATCH v5 3/6] target/riscv: Set VS* bits to one in mideleg when H-Ext is enabled Date: Mon, 16 Oct 2023 12:17:33 +0100 Message-Id: <20231016111736.28721-4-rkanwal@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231016111736.28721-1-rkanwal@rivosinc.com> References: <20231016111736.28721-1-rkanwal@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32b; envelope-from=rkanwal@rivosinc.com; helo=mail-wm1-x32b.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org With H-Ext supported, VS bits are all hardwired to one in MIDELEG denoting always delegated interrupts. This is being done in rmw_mideleg but given mideleg is used in other places when routing interrupts this change initializes it in riscv_cpu_realize to be on the safe side. Signed-off-by: Rajnesh Kanwal Reviewed-by: Alistair Francis --- target/riscv/tcg/tcg-cpu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index 418b040d6d..bbce254ee1 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -618,7 +618,12 @@ static bool tcg_cpu_realize(CPUState *cs, Error **errp) cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, riscv_pmu_timer_cb, cpu); } - } + } + + /* With H-Ext, VSSIP, VSTIP, VSEIP and SGEIP are hardwired to one. */ + if (riscv_has_ext(env, RVH)) { + env->mideleg = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP | MIP_SGEIP; + } #endif return true; From patchwork Mon Oct 16 11:17:34 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13423040 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 1D3C0CDB474 for ; Mon, 16 Oct 2023 11:18:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qsLbm-0002bk-K9; Mon, 16 Oct 2023 07:18:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qsLbj-0002bO-Ln for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:17:59 -0400 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qsLbb-0005bc-FJ for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:17:59 -0400 Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-32799639a2aso3961280f8f.3 for ; Mon, 16 Oct 2023 04:17:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1697455065; x=1698059865; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+SYRUUfZD0yW8fyiOdJqWLzmAtXsCBoAuBwPooPofNs=; b=b2miz+NFXLcI6R6jpYdZFF8Uv4b5bGGHAxJbg8rqvUDpF3XS+o6dvb090R3q0rTZ7k qdjT4T55PazkLi15UvSXqMN6Fgcq7tsw5FQHo89uxBrfmntkFFWDhA6Fn4vNG3vBiWzJ GbMKnUS22haK+8DZcJW4BjM4NyGXJFCE/zr/EPVCHezxDwLS/5SApVmMFOtpySom81Zm jryEQ0iyTP1TFkhRJ8ODTXddEaTeZP2dIXKlE7BCXHjBXUuVWNEPLk/kiBCnU3r8n28M 3hmRSd59qJsYUgpTypM0DHfNF2Rnk6hlpvfyfjbHSNKDz0RRYwAAJITqTF6jrQy6SGt4 Q9pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697455065; x=1698059865; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+SYRUUfZD0yW8fyiOdJqWLzmAtXsCBoAuBwPooPofNs=; b=tpESU3ToamCedfrAUBKU0n7aldvpHqbil0NkKedY6GyFp0FTnkXjFFeMJ5gDGe+VX7 k5GAgS71o3USJCheQS/WIoi+4NNddExUw+B5qsgkDVBehg55JPj1tMvgVv1qlH4nmZGQ nezfz9wBMM1mR+2dJMqDgrXI0ff3Io62M0v5LQM0ED0qzKup0Fo9eA+qlyS5BEoECJIc mgFBGZEhH9YxMtG1L467YUjxs8yc/VPtz8Fr6TDpQ4TQu8dXAz5fweO+mn7tNMENKdXW oLWbUCiKP7L/uTKjgQp/p4Deji/H21ryLWTWPXCILIRz7TRpcL7fBhP3sSTqaYc6YUUB /pWg== X-Gm-Message-State: AOJu0YzO399fHWRJpGkMbHazXRh9bXb/CssYAYy/2amTHx216Kh9f5sJ Vjm4CywUrLTKgIsCe9KK7XMAVw== X-Google-Smtp-Source: AGHT+IGETa2xr2qjsPg/C9znX15emz3SW8P1/CEl8ZE7FsZvHa0mVVWxLcx9ujjOrQ/twD/NLmDXKA== X-Received: by 2002:a5d:4e8b:0:b0:32d:a688:8813 with SMTP id e11-20020a5d4e8b000000b0032da6888813mr4006683wru.32.1697455064974; Mon, 16 Oct 2023 04:17:44 -0700 (PDT) Received: from localhost.localdomain (cpc91760-watf12-2-0-cust235.15-2.cable.virginm.net. [81.111.69.236]) by smtp.gmail.com with ESMTPSA id o15-20020a056000010f00b0032daf848f68sm3114299wrx.59.2023.10.16.04.17.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 04:17:44 -0700 (PDT) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org Cc: palmer@dabbelt.com, alistair.francis@wdc.com, bin.meng@windriver.com, liweiwei@iscas.ac.cn, dbarboza@ventanamicro.com, zhiwei_liu@linux.alibaba.com, atishp@rivosinc.com, apatel@ventanamicro.com, rkanwal@rivosinc.com Subject: [PATCH v5 4/6] target/riscv: Split interrupt logic from riscv_cpu_update_mip. Date: Mon, 16 Oct 2023 12:17:34 +0100 Message-Id: <20231016111736.28721-5-rkanwal@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231016111736.28721-1-rkanwal@rivosinc.com> References: <20231016111736.28721-1-rkanwal@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42f; envelope-from=rkanwal@rivosinc.com; helo=mail-wr1-x42f.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This is to allow virtual interrupts to be inserted into S and VS modes. Given virtual interrupts will be maintained in separate mvip and hvip CSRs, riscv_cpu_update_mip will no longer be in the path and interrupts need to be triggered for these cases from rmw_hvip64 and rmw_mvip64 functions. Signed-off-by: Rajnesh Kanwal Reviewed-by: Alistair Francis --- target/riscv/cpu.h | 1 + target/riscv/cpu_helper.c | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index f8ffa5ee38..6fe32e6b38 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -463,6 +463,7 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env); int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts); uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, uint64_t value); +void riscv_cpu_interrupt(CPURISCVState *env); #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */ void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *), void *arg); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index aaeb1d0d5c..581b8c6380 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -620,11 +620,12 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts) } } -uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, - uint64_t value) +void riscv_cpu_interrupt(CPURISCVState *env) { + uint64_t gein, vsgein = 0, vstip = 0; CPUState *cs = env_cpu(env); - uint64_t gein, vsgein = 0, vstip = 0, old = env->mip; + + QEMU_IOTHREAD_LOCK_GUARD(); if (env->virt_enabled) { gein = get_field(env->hstatus, HSTATUS_VGEIN); @@ -633,15 +634,25 @@ uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, vstip = env->vstime_irq ? MIP_VSTIP : 0; - QEMU_IOTHREAD_LOCK_GUARD(); - - env->mip = (env->mip & ~mask) | (value & mask); - if (env->mip | vsgein | vstip) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); } +} + +uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, uint64_t value) +{ + uint64_t old = env->mip; + + /* No need to update mip for VSTIP */ + mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask; + + QEMU_IOTHREAD_LOCK_GUARD(); + + env->mip = (env->mip & ~mask) | (value & mask); + + riscv_cpu_interrupt(env); return old; } From patchwork Mon Oct 16 11:17:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13423043 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 CB2C8CDB465 for ; Mon, 16 Oct 2023 11:19:15 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qsLbr-0002fC-KE; Mon, 16 Oct 2023 07:18:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qsLbn-0002d1-Td for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:03 -0400 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qsLbb-0005c0-F1 for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:03 -0400 Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-405361bb9f7so44316835e9.2 for ; Mon, 16 Oct 2023 04:17:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1697455066; x=1698059866; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wvpkU7YKN4GijXYl+V9bMedsEKYZb7wYVhBSgsmLiZI=; b=bYhx04Uz0/mK+aM12AS3aM2Qegcdk8NX17FIk5F65E9H0ZqDp2gcV4xKFcSbX0r5/b Y5aIrSgJ1ADW+E3D5Ks4RgDiSL+ypky3VghQ/on/+0aKAEPcckhIJHD0hnBiqbe1X4bJ MTtjqXwVoupOEvflo8gpWihOkgoKkP86nTnP9ueZJAt4VMmNA6eISILaTgwkF/qluVYr bqMod5AME8mAf77BV2y/yx9gPyAUur/6Z9bCtqp8+1s3HYM5nH3pUTZKSJBLzjX7TZeA q4xMVo6JcQpzQfWMqZ0d9Wnaalhq/1ka8LkQxG0qkQhq2rwS7g4IngK+OVz0Pkt+ov57 VTDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697455066; x=1698059866; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wvpkU7YKN4GijXYl+V9bMedsEKYZb7wYVhBSgsmLiZI=; b=hz4XOkmGUPcbZaWg94EYd+4hEjRQMmw5gFFUDpnIb0iGCnQMoHUXRsPyhhkC10gSoO 7lkHxyvWT0+7D5RxCGEhJspr4P+hxSCXDc8udGV6/EE3UjGal6Ytk4HfrpuDgR73B5Ht z+o0o6pq53uWnXotYwN3+V045ew7ZsaYC3lSI0TE5wtjYpd31+xjbhhZYeo4XMZgLX4o E9d6X1EAXxIiXTaniiQzI6uyq4O4BhcMNb+99seh8VXJ30Yp5MVGcsZm7oj/4QVqda4x d/NELwMVUF7/2OXfUCnz5d7FY1aijEFI8DVB/RCNMnTLncUeJOMAS64nWUOkP8zVPyhe kyAw== X-Gm-Message-State: AOJu0YzbVeqFCwiMDEuX61Wyyi3sicBkGTSdffIY2YBGYC2D2dfKAbID EMgOjWCUNeByMMEaecu0grTEHw== X-Google-Smtp-Source: AGHT+IFGi/PZ/pmDjwc6ZxU16fI14nLeMABZa7R9TKXQydAP+NegZ9HJYP9CiNVsfp4cniQbo/YgBw== X-Received: by 2002:a1c:7917:0:b0:401:d803:624f with SMTP id l23-20020a1c7917000000b00401d803624fmr29938037wme.4.1697455066027; Mon, 16 Oct 2023 04:17:46 -0700 (PDT) Received: from localhost.localdomain (cpc91760-watf12-2-0-cust235.15-2.cable.virginm.net. [81.111.69.236]) by smtp.gmail.com with ESMTPSA id o15-20020a056000010f00b0032daf848f68sm3114299wrx.59.2023.10.16.04.17.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 04:17:45 -0700 (PDT) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org Cc: palmer@dabbelt.com, alistair.francis@wdc.com, bin.meng@windriver.com, liweiwei@iscas.ac.cn, dbarboza@ventanamicro.com, zhiwei_liu@linux.alibaba.com, atishp@rivosinc.com, apatel@ventanamicro.com, rkanwal@rivosinc.com Subject: [PATCH v5 5/6] target/riscv: Add M-mode virtual interrupt and IRQ filtering support. Date: Mon, 16 Oct 2023 12:17:35 +0100 Message-Id: <20231016111736.28721-6-rkanwal@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231016111736.28721-1-rkanwal@rivosinc.com> References: <20231016111736.28721-1-rkanwal@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32e; envelope-from=rkanwal@rivosinc.com; helo=mail-wm1-x32e.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This change adds support for inserting virtual interrupts from M-mode into S-mode using mvien and mvip csrs. IRQ filtering is a use case of this change, i-e M-mode can stop delegating an interrupt to S-mode and instead enable it in MIE and receive those interrupts in M-mode and then selectively inject the interrupt using mvien and mvip. Also, the spec doesn't mandate the interrupt to be actually supported in hardware. Which allows M-mode to assert virtual interrupts to S-mode that have no connection to any real interrupt events. This is defined as part of the AIA specification [0], "5.3 Interrupt filtering and virtual interrupts for supervisor level". [0]: https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf Signed-off-by: Rajnesh Kanwal Reviewed-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 3 +- target/riscv/cpu.h | 8 ++ target/riscv/cpu_bits.h | 6 + target/riscv/cpu_helper.c | 26 +++- target/riscv/csr.c | 279 ++++++++++++++++++++++++++++++++++---- target/riscv/machine.c | 7 +- 6 files changed, 291 insertions(+), 38 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index efafc0ba0b..859ac59c6c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -813,7 +813,8 @@ static bool riscv_cpu_has_work(CPUState *cs) * Definition of the WFI instruction requires it to ignore the privilege * mode and delegation registers, but respect individual enables */ - return riscv_cpu_all_pending(env) != 0; + return riscv_cpu_all_pending(env) != 0 || + riscv_cpu_sirq_pending(env) != RISCV_EXCP_NONE; #else return true; #endif diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 6fe32e6b38..30f9481f45 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -202,6 +202,12 @@ struct CPUArchState { uint64_t mie; uint64_t mideleg; + /* + * When mideleg[i]=0 and mvien[i]=1, sie[i] is no more + * alias of mie[i] and needs to be maintained separatly. + */ + uint64_t sie; + target_ulong satp; /* since: priv-1.10.0 */ target_ulong stval; target_ulong medeleg; @@ -222,6 +228,8 @@ struct CPUArchState { /* AIA CSRs */ target_ulong miselect; target_ulong siselect; + uint64_t mvien; + uint64_t mvip; /* Hypervisor CSRs */ target_ulong hstatus; diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 3d6ffaabc7..ebd7917d49 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -735,6 +735,12 @@ typedef enum RISCVException { #define MIE_SSIE (1 << IRQ_S_SOFT) #define MIE_USIE (1 << IRQ_U_SOFT) +/* Machine constants */ +#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)) + /* General PointerMasking CSR bits */ #define PM_ENABLE 0x00000001ULL #define PM_CURRENT 0x00000002ULL diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 581b8c6380..b36161708a 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -376,6 +376,10 @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env, return best_irq; } +/* + * Doesn't report interrupts inserted using mvip from M-mode firmware. Those + * are returned in riscv_cpu_sirq_pending(). + */ uint64_t riscv_cpu_all_pending(CPURISCVState *env) { uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN); @@ -398,9 +402,10 @@ int riscv_cpu_sirq_pending(CPURISCVState *env) { uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); + uint64_t irqs_f = env->mvip & env->mvien & ~env->mideleg & env->sie; return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, - irqs, env->siprio); + irqs | irqs_f, env->siprio); } int riscv_cpu_vsirq_pending(CPURISCVState *env) @@ -414,8 +419,8 @@ int riscv_cpu_vsirq_pending(CPURISCVState *env) static int riscv_cpu_local_irq_pending(CPURISCVState *env) { + uint64_t irqs, pending, mie, hsie, vsie, irqs_f; int virq; - uint64_t irqs, pending, mie, hsie, vsie; /* Determine interrupt enable state of all privilege modes */ if (env->virt_enabled) { @@ -441,8 +446,11 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env) irqs, env->miprio); } + /* Check for virtual S-mode interrupts. */ + irqs_f = env->mvip & (env->mvien & ~env->mideleg) & env->sie; + /* Check HS-mode interrupts */ - irqs = pending & env->mideleg & ~env->hideleg & -hsie; + irqs = ((pending & env->mideleg & ~env->hideleg) | irqs_f) & -hsie; if (irqs) { return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, irqs, env->siprio); @@ -622,7 +630,7 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts) void riscv_cpu_interrupt(CPURISCVState *env) { - uint64_t gein, vsgein = 0, vstip = 0; + uint64_t gein, vsgein = 0, vstip = 0, irqf = 0; CPUState *cs = env_cpu(env); QEMU_IOTHREAD_LOCK_GUARD(); @@ -630,11 +638,13 @@ void riscv_cpu_interrupt(CPURISCVState *env) if (env->virt_enabled) { gein = get_field(env->hstatus, HSTATUS_VGEIN); vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; + } else { + irqf = env->mvien & env->mvip & env->sie; } vstip = env->vstime_irq ? MIP_VSTIP : 0; - if (env->mip | vsgein | vstip) { + if (env->mip | vsgein | vstip | irqf) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); @@ -1611,6 +1621,8 @@ 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; uint64_t deleg = async ? env->mideleg : env->medeleg; + bool s_injected = env->mvip & (1 << cause) & env->mvien && + !(env->mip & (1 << cause)); target_ulong tval = 0; target_ulong tinst = 0; target_ulong htval = 0; @@ -1699,8 +1711,8 @@ void riscv_cpu_do_interrupt(CPUState *cs) __func__, env->mhartid, async, cause, env->pc, tval, riscv_cpu_get_trap_name(cause, async)); - if (env->priv <= PRV_S && - cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) { + if (env->priv <= PRV_S && cause < 64 && + (((deleg >> cause) & 1) || s_injected)) { /* handle the trap in S-mode */ if (riscv_has_ext(env, RVH)) { uint64_t hdeleg = async ? env->hideleg : env->hedeleg; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 4847b47a98..645f30f028 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1117,21 +1117,16 @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } -/* Machine constants */ - -#define M_MODE_INTERRUPTS ((uint64_t)(MIP_MSIP | MIP_MTIP | MIP_MEIP)) -#define S_MODE_INTERRUPTS ((uint64_t)(MIP_SSIP | MIP_STIP | MIP_SEIP | \ - MIP_LCOFIP)) -#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; +#define LOCAL_INTERRUPTS (~0x1FFF) + +static const uint64_t delegable_ints = + S_MODE_INTERRUPTS | VS_MODE_INTERRUPTS | MIP_LCOFIP; +static const uint64_t vs_delegable_ints = + (VS_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & ~MIP_LCOFIP; static const uint64_t all_ints = M_MODE_INTERRUPTS | S_MODE_INTERRUPTS | - HS_MODE_INTERRUPTS; + HS_MODE_INTERRUPTS | LOCAL_INTERRUPTS; #define DELEGABLE_EXCPS ((1ULL << (RISCV_EXCP_INST_ADDR_MIS)) | \ (1ULL << (RISCV_EXCP_INST_ACCESS_FAULT)) | \ (1ULL << (RISCV_EXCP_ILLEGAL_INST)) | \ @@ -1162,12 +1157,30 @@ static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS & static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS; -static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP | - SIP_LCOFIP; + +/* + * Spec allows for bits 13:63 to be either read-only or writable. + * So far we have interrupt LCOFIP in that region which is writable. + * + * Also, spec allows to inject virtual interrupts in this region even + * without any hardware interrupts for that interrupt number. + * + * For now interrupt in 13:63 region are all kept writable. 13 being + * LCOFIP and 14:63 being virtual only. Change this in future if we + * introduce more interrupts that are not writable. + */ + +/* Bit STIP can be an alias of mip.STIP that's why it's writable in mvip. */ +static const target_ulong mvip_writable_mask = MIP_SSIP | MIP_STIP | MIP_SEIP | + LOCAL_INTERRUPTS; +static const target_ulong mvien_writable_mask = MIP_SSIP | MIP_SEIP | + LOCAL_INTERRUPTS; + +static const target_ulong sip_writable_mask = SIP_SSIP | LOCAL_INTERRUPTS; static const target_ulong hip_writable_mask = MIP_VSSIP; static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | - MIP_VSEIP; -static const target_ulong vsip_writable_mask = MIP_VSSIP; + MIP_VSEIP | LOCAL_INTERRUPTS; +static const target_ulong vsip_writable_mask = MIP_VSSIP | LOCAL_INTERRUPTS; const bool valid_vm_1_10_32[16] = { [VM_1_10_MBARE] = true, @@ -1562,6 +1575,52 @@ static RISCVException rmw_mieh(CPURISCVState *env, int csrno, return ret; } +static RISCVException rmw_mvien64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) +{ + uint64_t mask = wr_mask & mvien_writable_mask; + + if (ret_val) { + *ret_val = env->mvien; + } + + env->mvien = (env->mvien & ~mask) | (new_val & mask); + + return RISCV_EXCP_NONE; +} + +static RISCVException rmw_mvien(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_mvien64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; +} + +static RISCVException rmw_mvienh(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_mvien64(env, csrno, &rval, + ((uint64_t)new_val) << 32, ((uint64_t)wr_mask) << 32); + if (ret_val) { + *ret_val = rval >> 32; + } + + return ret; +} + static int read_mtopi(CPURISCVState *env, int csrno, target_ulong *val) { int irq; @@ -1703,6 +1762,11 @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val, priv = PRV_M; break; case CSR_SIREG: + if (env->priv == PRV_S && env->mvien & MIP_SEIP && + env->siselect >= ISELECT_IMSIC_EIDELIVERY && + env->siselect <= ISELECT_IMSIC_EIE63) { + goto done; + } iprio = env->siprio; isel = env->siselect; priv = PRV_S; @@ -1769,6 +1833,9 @@ static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val, priv = PRV_M; break; case CSR_STOPEI: + if (env->mvien & MIP_SEIP && env->priv == PRV_S) { + goto done; + } priv = PRV_S; break; case CSR_VSTOPEI: @@ -2360,6 +2427,143 @@ static RISCVException rmw_miph(CPURISCVState *env, int csrno, return ret; } +/* + * The function is written for two use-cases: + * 1- To access mvip csr as is for m-mode access. + * 2- To access sip as a combination of mip and mvip for s-mode. + * + * Both report bits 1, 5, 9 and 13:63 but with the exception of + * STIP being read-only zero in case of mvip when sstc extension + * is present. + * Also, sip needs to be read-only zero when both mideleg[i] and + * mvien[i] are zero but mvip needs to be an alias of mip. + */ +static RISCVException rmw_mvip64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) +{ + RISCVCPU *cpu = env_archcpu(env); + target_ulong ret_mip = 0; + RISCVException ret; + uint64_t old_mvip; + + /* + * mideleg[i] mvien[i] + * 0 0 No delegation. mvip[i] is alias of mip[i]. + * 0 1 mvip[i] becomes source of interrupt, mip bypassed. + * 1 X mip[i] is source of interrupt and mvip[i] aliases + * mip[i]. + * + * So alias condition would be for bits: + * ((S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & (mideleg | ~mvien)) | + * (!sstc & MIP_STIP) + * + * Non-alias condition will be for bits: + * (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & (~mideleg & mvien) + * + * alias_mask denotes the bits that come from mip nalias_mask denotes bits + * that come from hvip. + */ + uint64_t alias_mask = ((S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & + (env->mideleg | ~env->mvien)) | MIP_STIP; + uint64_t nalias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & + (~env->mideleg & env->mvien); + uint64_t wr_mask_mvip; + uint64_t wr_mask_mip; + + /* + * mideleg[i] mvien[i] + * 0 0 sip[i] read-only zero. + * 0 1 sip[i] alias of mvip[i]. + * 1 X sip[i] alias of mip[i]. + * + * Both alias and non-alias mask remain same for sip except for bits + * which are zero in both mideleg and mvien. + */ + if (csrno == CSR_SIP) { + /* Remove bits that are zero in both mideleg and mvien. */ + alias_mask &= (env->mideleg | env->mvien); + nalias_mask &= (env->mideleg | env->mvien); + } + + /* + * If sstc is present, mvip.STIP is not an alias of mip.STIP so clear + * that our in mip returned value. + */ + if (cpu->cfg.ext_sstc && (env->priv == PRV_M) && + get_field(env->menvcfg, MENVCFG_STCE)) { + alias_mask &= ~MIP_STIP; + } + + wr_mask_mip = wr_mask & alias_mask & mvip_writable_mask; + wr_mask_mvip = wr_mask & nalias_mask & mvip_writable_mask; + + /* + * For bits set in alias_mask, mvip needs to be alias of mip, so forward + * this to rmw_mip. + */ + ret = rmw_mip(env, CSR_MIP, &ret_mip, new_val, wr_mask_mip); + if (ret != RISCV_EXCP_NONE) { + return ret; + } + + old_mvip = env->mvip; + + /* + * Write to mvip. Update only non-alias bits. Alias bits were updated + * in mip in rmw_mip above. + */ + if (wr_mask_mvip) { + env->mvip = (env->mvip & ~wr_mask_mvip) | (new_val & wr_mask_mvip); + + /* + * Given mvip is separate source from mip, we need to trigger interrupt + * from here separately. Normally this happen from riscv_cpu_update_mip. + */ + riscv_cpu_interrupt(env); + } + + if (ret_val) { + ret_mip &= alias_mask; + old_mvip &= nalias_mask; + + *ret_val = old_mvip | ret_mip; + } + + return RISCV_EXCP_NONE; +} + +static RISCVException rmw_mvip(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_mvip64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; +} + +static RISCVException rmw_mviph(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_mvip64(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) @@ -2454,20 +2658,37 @@ static RISCVException rmw_sie64(CPURISCVState *env, int csrno, uint64_t *ret_val, uint64_t new_val, uint64_t wr_mask) { + uint64_t nalias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & + (~env->mideleg & env->mvien); + uint64_t alias_mask = (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS) & env->mideleg; + uint64_t sie_mask = wr_mask & nalias_mask; RISCVException ret; - uint64_t mask = env->mideleg & S_MODE_INTERRUPTS; + /* + * mideleg[i] mvien[i] + * 0 0 sie[i] read-only zero. + * 0 1 sie[i] is a separate writable bit. + * 1 X sie[i] alias of mie[i]. + * + * Both alias and non-alias mask remain same for sip except for bits + * which are zero in both mideleg and mvien. + */ if (env->virt_enabled) { if (env->hvictl & HVICTL_VTI) { return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; } ret = rmw_vsie64(env, CSR_VSIE, ret_val, new_val, wr_mask); + if (ret_val) { + *ret_val &= alias_mask; + } } else { - ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & mask); - } + ret = rmw_mie64(env, csrno, ret_val, new_val, wr_mask & alias_mask); + if (ret_val) { + *ret_val &= alias_mask; + *ret_val |= env->sie & nalias_mask; + } - if (ret_val) { - *ret_val &= mask; + env->sie = (env->sie & ~sie_mask) | (new_val & sie_mask); } return ret; @@ -2665,7 +2886,7 @@ static RISCVException rmw_sip64(CPURISCVState *env, int csrno, uint64_t new_val, uint64_t wr_mask) { RISCVException ret; - uint64_t mask = env->mideleg & sip_writable_mask; + uint64_t mask = (env->mideleg | env->mvien) & sip_writable_mask; if (env->virt_enabled) { if (env->hvictl & HVICTL_VTI) { @@ -2673,11 +2894,12 @@ static RISCVException rmw_sip64(CPURISCVState *env, int csrno, } 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); + ret = rmw_mvip64(env, csrno, ret_val, new_val, wr_mask & mask); } if (ret_val) { - *ret_val &= env->mideleg & S_MODE_INTERRUPTS; + *ret_val &= (env->mideleg | env->mvien) & + (S_MODE_INTERRUPTS | LOCAL_INTERRUPTS); } return ret; @@ -2842,6 +3064,7 @@ static int read_vstopi(CPURISCVState *env, int csrno, target_ulong *val) *val = (iid & TOPI_IID_MASK) << TOPI_IID_SHIFT; *val |= iprio; + return RISCV_EXCP_NONE; } @@ -4165,14 +4388,14 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [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 }, + [CSR_MVIEN] = { "mvien", aia_any, NULL, NULL, rmw_mvien }, + [CSR_MVIP] = { "mvip", aia_any, NULL, NULL, rmw_mvip }, /* 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_MVIENH] = { "mvienh", aia_any32, NULL, NULL, rmw_mvienh }, + [CSR_MVIPH] = { "mviph", aia_any32, NULL, NULL, rmw_mviph }, [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph }, /* Execution environment configuration */ diff --git a/target/riscv/machine.c b/target/riscv/machine.c index c7c862cdd3..f65a95f9e7 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -351,8 +351,8 @@ static const VMStateDescription vmstate_jvt = { const VMStateDescription vmstate_riscv_cpu = { .name = "cpu", - .version_id = 8, - .minimum_version_id = 8, + .version_id = 9, + .minimum_version_id = 9, .post_load = riscv_cpu_post_load, .fields = (VMStateField[]) { VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32), @@ -379,6 +379,9 @@ const VMStateDescription vmstate_riscv_cpu = { VMSTATE_UINT64(env.mip, RISCVCPU), VMSTATE_UINT64(env.miclaim, RISCVCPU), VMSTATE_UINT64(env.mie, RISCVCPU), + VMSTATE_UINT64(env.mvien, RISCVCPU), + VMSTATE_UINT64(env.mvip, RISCVCPU), + VMSTATE_UINT64(env.sie, RISCVCPU), VMSTATE_UINT64(env.mideleg, RISCVCPU), VMSTATE_UINTTL(env.satp, RISCVCPU), VMSTATE_UINTTL(env.stval, RISCVCPU), From patchwork Mon Oct 16 11:17:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13423041 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 3A212CDB485 for ; Mon, 16 Oct 2023 11:18:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qsLbt-0002ge-Op; Mon, 16 Oct 2023 07:18:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qsLbp-0002df-3o for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:05 -0400 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qsLbb-0005cB-Fg for qemu-devel@nongnu.org; Mon, 16 Oct 2023 07:18:04 -0400 Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-32d9552d765so3389868f8f.2 for ; Mon, 16 Oct 2023 04:17:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1697455067; x=1698059867; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YRhiNIc1Kt9dgvfIhL9W4FtSU6f0VIKRrb8ZzW13ahA=; b=QgcaPzxa2trWBxxN47CG4i2Akg/BWMqs6xcOmTd4uCWJkv21tZX+EpQUjI9Q0GMekX lh3zIMDnvVb1cCuI7Hm4A+Y3cu3hWhGeeOd/PQi15EPlplvNWNrQ9rlKSmS1dRBI8O3q f9SRzUF0N3hh+M3/QBvi0LADbw+38QY/xGRr6DMALja1CCi62/Hw4zHE94Vs+TzbllHe zv+lyKWa/JcMvnitsea5oNWJYVuJBgN17nHPsxHl0J8xPEHigfuB4Yu3EM5+OK0uZEWe BuS76sVCvKg4024cfxvJRx1i1vHCTZM0OaKdkx9I7/btThpC+zmVzv22ViuBf/vt+2Uf FUqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697455067; x=1698059867; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YRhiNIc1Kt9dgvfIhL9W4FtSU6f0VIKRrb8ZzW13ahA=; b=Bqdra5hDG5tn6N/jqq2OmnKtlPQHEa2lK3zJHb29QU5QliIYby8o39sCEK8YfQSu3+ eiAIzDdnh+gOzge9Ty9yILJ0oKoAgofP72X7ZRK1jGnYjiu9AVJEIJXpvlytp/kM9GQD y2/d+qgKNb/ZtCE+tF8rR0gTZjRmS8x8Eo3TTR7qnIe/o08c6RSlmvFajpKdL669R6bI VuFU6VgufPRt++4gUS1RF+NMSdWcbByTRp+7pW2BOaJdO+1udygyMk+WE3EuMaUwmmfj RonUv/fFEX6p7GOr43Wf5jds26uAq+OUGhuY+StWWSLBqq+1zPb7iVoxQO87dbT8EFeM Pw4Q== X-Gm-Message-State: AOJu0YzaV4TGN1NbBwiNGCxRTIf9PMfqiW1BKoOj1K9025k+wGMeb1ha 3GqoCSh8P2XeYcjtOR0HnoZ5Ag== X-Google-Smtp-Source: AGHT+IEaDRrnSgnvksyjvnJhFJ8M/rNhQZDNDPogm1y1z8VEN2quJXDtDNTRTcofNj04XsvfZDefgQ== X-Received: by 2002:a5d:5288:0:b0:32d:8469:4f68 with SMTP id c8-20020a5d5288000000b0032d84694f68mr10799854wrv.15.1697455067167; Mon, 16 Oct 2023 04:17:47 -0700 (PDT) Received: from localhost.localdomain (cpc91760-watf12-2-0-cust235.15-2.cable.virginm.net. [81.111.69.236]) by smtp.gmail.com with ESMTPSA id o15-20020a056000010f00b0032daf848f68sm3114299wrx.59.2023.10.16.04.17.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 04:17:46 -0700 (PDT) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org Cc: palmer@dabbelt.com, alistair.francis@wdc.com, bin.meng@windriver.com, liweiwei@iscas.ac.cn, dbarboza@ventanamicro.com, zhiwei_liu@linux.alibaba.com, atishp@rivosinc.com, apatel@ventanamicro.com, rkanwal@rivosinc.com Subject: [PATCH v5 6/6] target/riscv: Add HS-mode virtual interrupt and IRQ filtering support. Date: Mon, 16 Oct 2023 12:17:36 +0100 Message-Id: <20231016111736.28721-7-rkanwal@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231016111736.28721-1-rkanwal@rivosinc.com> References: <20231016111736.28721-1-rkanwal@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::430; envelope-from=rkanwal@rivosinc.com; helo=mail-wr1-x430.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This change adds support for inserting virtual interrupts from HS-mode into VS-mode using hvien and hvip csrs. This also allows for IRQ filtering from HS-mode. Also, the spec doesn't mandate the interrupt to be actually supported in hardware. Which allows HS-mode to assert virtual interrupts to VS-mode that have no connection to any real interrupt events. This is defined as part of the AIA specification [0], "6.3.2 Virtual interrupts for VS level". [0]: https://github.com/riscv/riscv-aia/releases/download/1.0/riscv-interrupts-1.0.pdf Signed-off-by: Rajnesh Kanwal Reviewed-by: Daniel Henrique Barboza --- target/riscv/cpu.c | 3 +- target/riscv/cpu.h | 14 +++ target/riscv/cpu_helper.c | 48 +++++++--- target/riscv/csr.c | 196 ++++++++++++++++++++++++++++++++++---- target/riscv/machine.c | 7 +- 5 files changed, 236 insertions(+), 32 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 859ac59c6c..2f98ce56e0 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -814,7 +814,8 @@ static bool riscv_cpu_has_work(CPUState *cs) * mode and delegation registers, but respect individual enables */ return riscv_cpu_all_pending(env) != 0 || - riscv_cpu_sirq_pending(env) != RISCV_EXCP_NONE; + riscv_cpu_sirq_pending(env) != RISCV_EXCP_NONE || + riscv_cpu_vsirq_pending(env) != RISCV_EXCP_NONE; #else return true; #endif diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 30f9481f45..7f61e17202 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -208,6 +208,12 @@ struct CPUArchState { */ uint64_t sie; + /* + * When hideleg[i]=0 and hvien[i]=1, vsie[i] is no more + * alias of sie[i] (mie[i]) and needs to be maintained separatly. + */ + uint64_t vsie; + target_ulong satp; /* since: priv-1.10.0 */ target_ulong stval; target_ulong medeleg; @@ -242,6 +248,14 @@ struct CPUArchState { target_ulong hgeie; target_ulong hgeip; uint64_t htimedelta; + uint64_t hvien; + + /* + * Bits VSSIP, VSTIP and VSEIP in hvip are maintained in mip. Other bits + * from 0:12 are reserved. Bits 13:63 are not aliased and must be separately + * maintain in hvip. + */ + uint64_t hvip; /* Hypervisor controlled virtual interrupt priorities */ target_ulong hvictl; diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index b36161708a..b7af69de53 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -377,8 +377,9 @@ static int riscv_cpu_pending_to_irq(CPURISCVState *env, } /* - * Doesn't report interrupts inserted using mvip from M-mode firmware. Those - * are returned in riscv_cpu_sirq_pending(). + * Doesn't report interrupts inserted using mvip from M-mode firmware or + * using hvip bits 13:63 from HS-mode. Those are returned in + * riscv_cpu_sirq_pending() and riscv_cpu_vsirq_pending(). */ uint64_t riscv_cpu_all_pending(CPURISCVState *env) { @@ -410,16 +411,23 @@ int riscv_cpu_sirq_pending(CPURISCVState *env) int riscv_cpu_vsirq_pending(CPURISCVState *env) { - uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & - (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); + uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & env->hideleg; + uint64_t irqs_f_vs = env->hvip & env->hvien & ~env->hideleg & env->vsie; + uint64_t vsbits; + + /* Bring VS-level bits to correct position */ + vsbits = irqs & VS_MODE_INTERRUPTS; + irqs &= ~VS_MODE_INTERRUPTS; + irqs |= vsbits >> 1; return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, - irqs >> 1, env->hviprio); + (irqs | irqs_f_vs), env->hviprio); } static int riscv_cpu_local_irq_pending(CPURISCVState *env) { - uint64_t irqs, pending, mie, hsie, vsie, irqs_f; + uint64_t irqs, pending, mie, hsie, vsie, irqs_f, irqs_f_vs; + uint64_t vsbits, irq_delegated; int virq; /* Determine interrupt enable state of all privilege modes */ @@ -456,12 +464,26 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env) irqs, env->siprio); } + /* Check for virtual VS-mode interrupts. */ + irqs_f_vs = env->hvip & env->hvien & ~env->hideleg & env->vsie; + /* Check VS-mode interrupts */ - irqs = pending & env->mideleg & env->hideleg & -vsie; + irq_delegated = pending & env->mideleg & env->hideleg; + + /* Bring VS-level bits to correct position */ + vsbits = irq_delegated & VS_MODE_INTERRUPTS; + irq_delegated &= ~VS_MODE_INTERRUPTS; + irq_delegated |= vsbits >> 1; + + irqs = (irq_delegated | irqs_f_vs) & -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; + irqs, env->hviprio); + if (virq <= 0 || (virq > 12 && virq <= 63)) { + return virq; + } else { + return virq + 1; + } } /* Indicate no pending interrupt */ @@ -638,6 +660,7 @@ void riscv_cpu_interrupt(CPURISCVState *env) if (env->virt_enabled) { gein = get_field(env->hstatus, HSTATUS_VGEIN); vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; + irqf = env->hvien & env->hvip & env->vsie; } else { irqf = env->mvien & env->mvip & env->sie; } @@ -1623,6 +1646,8 @@ void riscv_cpu_do_interrupt(CPUState *cs) uint64_t deleg = async ? env->mideleg : env->medeleg; bool s_injected = env->mvip & (1 << cause) & env->mvien && !(env->mip & (1 << cause)); + bool vs_injected = env->hvip & (1 << cause) & env->hvien && + !(env->mip & (1 << cause)); target_ulong tval = 0; target_ulong tinst = 0; target_ulong htval = 0; @@ -1712,12 +1737,13 @@ void riscv_cpu_do_interrupt(CPUState *cs) riscv_cpu_get_trap_name(cause, async)); if (env->priv <= PRV_S && cause < 64 && - (((deleg >> cause) & 1) || s_injected)) { + (((deleg >> cause) & 1) || s_injected || vs_injected)) { /* handle the trap in S-mode */ if (riscv_has_ext(env, RVH)) { uint64_t hdeleg = async ? env->hideleg : env->hedeleg; - if (env->virt_enabled && ((hdeleg >> cause) & 1)) { + if (env->virt_enabled && + (((hdeleg >> cause) & 1) || vs_injected)) { /* Trap to VS mode */ /* * See if we need to adjust cause. Yes if its VS mode interrupt diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 645f30f028..a5be1c202c 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -30,6 +30,7 @@ #include "qemu/guest-random.h" #include "qapi/error.h" + /* CSR function table public API */ void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops) { @@ -1180,6 +1181,8 @@ static const target_ulong sip_writable_mask = SIP_SSIP | LOCAL_INTERRUPTS; static const target_ulong hip_writable_mask = MIP_VSSIP; static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP | LOCAL_INTERRUPTS; +static const target_ulong hvien_writable_mask = LOCAL_INTERRUPTS; + static const target_ulong vsip_writable_mask = MIP_VSSIP | LOCAL_INTERRUPTS; const bool valid_vm_1_10_32[16] = { @@ -2608,16 +2611,36 @@ static RISCVException rmw_vsie64(CPURISCVState *env, int csrno, uint64_t *ret_val, uint64_t new_val, uint64_t wr_mask) { + uint64_t alias_mask = (LOCAL_INTERRUPTS | VS_MODE_INTERRUPTS) & + env->hideleg; + uint64_t nalias_mask = LOCAL_INTERRUPTS & (~env->hideleg & env->hvien); + uint64_t rval, rval_vs, vsbits; + uint64_t wr_mask_vsie; + uint64_t wr_mask_mie; RISCVException ret; - uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS; /* Bring VS-level bits to correct position */ - new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1; - wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1; + 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; + + wr_mask_mie = wr_mask & alias_mask; + wr_mask_vsie = wr_mask & nalias_mask; + + ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask_mie); + + rval_vs = env->vsie & nalias_mask; + env->vsie = (env->vsie & ~wr_mask_vsie) | (new_val & wr_mask_vsie); - ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask); if (ret_val) { - *ret_val = (rval & mask) >> 1; + rval &= alias_mask; + vsbits = rval & VS_MODE_INTERRUPTS; + rval &= ~VS_MODE_INTERRUPTS; + *ret_val = rval | (vsbits >> 1) | rval_vs; } return ret; @@ -2830,21 +2853,36 @@ static RISCVException write_stval(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +static RISCVException rmw_hvip64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask); + 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, mask = env->hideleg & VS_MODE_INTERRUPTS; + uint64_t vsbits; - /* Bring VS-level bits to correct position */ - new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1; - wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1; + /* Add virtualized bits into vsip mask. */ + mask |= env->hvien & ~env->hideleg; - ret = rmw_mip64(env, csrno, &rval, new_val, - wr_mask & mask & 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_hvip64(env, csrno, &rval, new_val, + wr_mask & mask & vsip_writable_mask); if (ret_val) { - *ret_val = (rval & mask) >> 1; + rval &= mask; + vsbits = rval & VS_MODE_INTERRUPTS; + rval &= ~VS_MODE_INTERRUPTS; + *ret_val = rval | (vsbits >> 1); } return ret; @@ -3136,6 +3174,52 @@ static RISCVException write_hedeleg(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +static RISCVException rmw_hvien64(CPURISCVState *env, int csrno, + uint64_t *ret_val, + uint64_t new_val, uint64_t wr_mask) +{ + uint64_t mask = wr_mask & hvien_writable_mask; + + if (ret_val) { + *ret_val = env->hvien; + } + + env->hvien = (env->hvien & ~mask) | (new_val & mask); + + return RISCV_EXCP_NONE; +} + +static RISCVException rmw_hvien(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_hvien64(env, csrno, &rval, new_val, wr_mask); + if (ret_val) { + *ret_val = rval; + } + + return ret; +} + +static RISCVException rmw_hvienh(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t rval; + RISCVException ret; + + ret = rmw_hvien64(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_hideleg64(CPURISCVState *env, int csrno, uint64_t *ret_val, uint64_t new_val, uint64_t wr_mask) @@ -3181,16 +3265,94 @@ static RISCVException rmw_hidelegh(CPURISCVState *env, int csrno, return ret; } +/* + * The function is written for two use-cases: + * 1- To access hvip csr as is for HS-mode access. + * 2- To access vsip as a combination of hvip, and mip for vs-mode. + * + * Both report bits 2, 6, 10 and 13:63. + * vsip needs to be read-only zero when both hideleg[i] and + * hvien[i] are zero. + */ static RISCVException rmw_hvip64(CPURISCVState *env, int csrno, uint64_t *ret_val, uint64_t new_val, uint64_t wr_mask) { RISCVException ret; + uint64_t old_hvip; + uint64_t ret_mip; + + /* + * For bits 10, 6 and 2, vsip[i] is an alias of hip[i]. These bits are + * present in hip, hvip and mip. Where mip[i] is alias of hip[i] and hvip[i] + * is OR'ed in hip[i] to inject virtual interrupts from hypervisor. These + * bits are actually being maintained in mip so we read them from there. + * This way we have a single source of truth and allows for easier + * implementation. + * + * For bits 13:63 we have: + * + * hideleg[i] hvien[i] + * 0 0 No delegation. vsip[i] readonly zero. + * 0 1 vsip[i] is alias of hvip[i], sip bypassed. + * 1 X vsip[i] is alias of sip[i], hvip bypassed. + * + * alias_mask denotes the bits that come from sip (mip here given we + * maintain all bits there). nalias_mask denotes bits that come from + * hvip. + */ + uint64_t alias_mask = (env->hideleg | ~env->hvien) | VS_MODE_INTERRUPTS; + uint64_t nalias_mask = (~env->hideleg & env->hvien); + uint64_t wr_mask_hvip; + uint64_t wr_mask_mip; + + /* + * Both alias and non-alias mask remain same for vsip except: + * 1- For VS* bits if they are zero in hideleg. + * 2- For 13:63 bits if they are zero in both hideleg and hvien. + */ + if (csrno == CSR_VSIP) { + /* zero-out VS* bits that are not delegated to VS mode. */ + alias_mask &= (env->hideleg | ~VS_MODE_INTERRUPTS); + + /* + * zero-out 13:63 bits that are zero in both hideleg and hvien. + * nalias_mask mask can not contain any VS* bits so only second + * condition applies on it. + */ + nalias_mask &= (env->hideleg | env->hvien); + alias_mask &= (env->hideleg | env->hvien); + } + + wr_mask_hvip = wr_mask & nalias_mask & hvip_writable_mask; + wr_mask_mip = wr_mask & alias_mask & hvip_writable_mask; + + /* Aliased bits, bits 10, 6, 2 need to come from mip. */ + ret = rmw_mip64(env, csrno, &ret_mip, new_val, wr_mask_mip); + if (ret != RISCV_EXCP_NONE) { + return ret; + } + + old_hvip = env->hvip; + + if (wr_mask_hvip) { + env->hvip = (env->hvip & ~wr_mask_hvip) | (new_val & wr_mask_hvip); + + /* + * Given hvip is separate source from mip, we need to trigger interrupt + * from here separately. Normally this happen from riscv_cpu_update_mip. + */ + riscv_cpu_interrupt(env); + } - ret = rmw_mip64(env, csrno, ret_val, new_val, - wr_mask & hvip_writable_mask); if (ret_val) { - *ret_val &= VS_MODE_INTERRUPTS; + /* Only take VS* bits from mip. */ + ret_mip &= alias_mask; + + /* Take in non-delegated 13:63 bits from hvip. */ + old_hvip &= nalias_mask; + + *ret_val = ret_mip | old_hvip; } return ret; @@ -4569,14 +4731,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { .min_priv_ver = PRIV_VERSION_1_12_0 }, /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */ - [CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore }, + [CSR_HVIEN] = { "hvien", aia_hmode, NULL, NULL, rmw_hvien }, [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 }, - /* * VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */ @@ -4591,8 +4752,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* 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_HVIENH] = { "hvienh", aia_hmode32, NULL, NULL, rmw_hvienh }, [CSR_HVIPH] = { "hviph", aia_hmode32, NULL, NULL, rmw_hviph }, [CSR_HVIPRIO1H] = { "hviprio1h", aia_hmode32, read_hviprio1h, write_hviprio1h }, diff --git a/target/riscv/machine.c b/target/riscv/machine.c index f65a95f9e7..14bb2d7819 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -79,8 +79,8 @@ static bool hyper_needed(void *opaque) static const VMStateDescription vmstate_hyper = { .name = "cpu/hyper", - .version_id = 2, - .minimum_version_id = 2, + .version_id = 3, + .minimum_version_id = 3, .needed = hyper_needed, .fields = (VMStateField[]) { VMSTATE_UINTTL(env.hstatus, RISCVCPU), @@ -92,6 +92,8 @@ static const VMStateDescription vmstate_hyper = { VMSTATE_UINTTL(env.hgatp, RISCVCPU), VMSTATE_UINTTL(env.hgeie, RISCVCPU), VMSTATE_UINTTL(env.hgeip, RISCVCPU), + VMSTATE_UINT64(env.hvien, RISCVCPU), + VMSTATE_UINT64(env.hvip, RISCVCPU), VMSTATE_UINT64(env.htimedelta, RISCVCPU), VMSTATE_UINT64(env.vstimecmp, RISCVCPU), @@ -106,6 +108,7 @@ static const VMStateDescription vmstate_hyper = { VMSTATE_UINTTL(env.vstval, RISCVCPU), VMSTATE_UINTTL(env.vsatp, RISCVCPU), VMSTATE_UINTTL(env.vsiselect, RISCVCPU), + VMSTATE_UINT64(env.vsie, RISCVCPU), VMSTATE_UINTTL(env.mtval2, RISCVCPU), VMSTATE_UINTTL(env.mtinst, RISCVCPU),