From patchwork Mon Nov 4 21:51:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13862146 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 069F6D1CA01 for ; Mon, 4 Nov 2024 21:55:07 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t850y-0007we-Nx; Mon, 04 Nov 2024 16:53:36 -0500 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 1t850w-0007w6-Hx for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:34 -0500 Received: from mail-wm1-x32f.google.com ([2a00:1450:4864:20::32f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t850u-00011J-Qt for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:34 -0500 Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-43193678216so41073095e9.0 for ; Mon, 04 Nov 2024 13:53:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1730757211; x=1731362011; 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=YeHKxz4SCr4FLt1UY4Xd40xGZa8n9dG3guDv0GCCUpY=; b=XacK+/OX3KaIRTXOcEDHrlcRDnlhniYAi2U+imH5UFKkPo00rLMcozFw2a95nSbACR Jhxv15lsIuHc1v41YFpSaHrSJWoJh29LV/giD8ZlTI7X8DjpD4zkwV3UPHDPCuX2e9Vm xgvtChy7SQg/e1A27YBxwOjRxpWW4Or9wByhLX3CMcNsmbIRItXdY/Ysfgr4AJbYYmsC 7iBb/cn+uWdGwzMhDZ7r1oULswkvyTnZQdhDGVaTuYYBa4w2CkmTOnS28YbrspUhYxRz AiNJZkQCiQPpfSq9dD0Siovac6fmvF0QNc3TzAN4sRe5eSl1+rjuHZ+Mh4aKYQ6SHR0Y 6ojg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730757211; x=1731362011; 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=YeHKxz4SCr4FLt1UY4Xd40xGZa8n9dG3guDv0GCCUpY=; b=VKwTIEs0oHvwnBpuDt0RQnTM0QAHbu4uKYfSmgw3X3JkIga1qmPVGkOgLL2kQIQmfK 95oaMwAq7th7CmFOOT97Mrq9ocAknMQv8Hxii7Dy1k3NuwZRdcndBa1KQZ9nf49sDyhW eA+eET/D6v99p1l13ZEOgn9IscgCPbTyOtDswDPJ+toCqmLHAcp3FN3dOqHAhluNwczX 7X3K7XSQr2sZJirPozQNp2a3LVR2HJdkQ5g3AgPyx9iRQlzLxMM2fuhSo9CNFYDPecjB dB24aXaKahIlzj2r2ucuE7cRrfzY+ATB6xZaeY8ttNXvZty2dPhHfQQpWaB2qFvvidiB Km0g== X-Forwarded-Encrypted: i=1; AJvYcCW3Y1QCrb+9HgvH1VYFMjFyr7pTNBPwhNRdqlj79ukBk2e0oSxStF/h4U/9UVQVKvOREi15wvv9FyY7@nongnu.org X-Gm-Message-State: AOJu0Yx3+UYGopRsu/lPW5gDATuuYyrHUpamATOERhMTXlxOhsx0b1Ab M4ChDZZcZkEcxexTs9oPsP8e0O0Sw+GaZRzmvpqP1uuMDMajAbLlyg3R0RGE/OA= X-Google-Smtp-Source: AGHT+IEDAB4JiWUfOOLrAOH3vnBiXDdHQRpqO6/W6ZnbzylQR9wQ5CSu/0HddtrbcxglZw5mPLyLGA== X-Received: by 2002:a05:600c:154d:b0:431:44f6:566f with SMTP id 5b1f17b1804b1-4319ac9d21amr301220465e9.13.1730757211404; Mon, 04 Nov 2024 13:53:31 -0800 (PST) Received: from rkanwal-XPS-15-9520.Home ([2a02:c7c:7527:ee00:8a3a:7719:aa26:21cb]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432a26a6da1sm1537595e9.0.2024.11.04.13.53.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Nov 2024 13:53:31 -0800 (PST) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Rajnesh Kanwal Cc: 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, beeman@rivosinc.com, tech-control-transfer-records@lists.riscv.org, jason.chien@sifive.com, frank.chang@sifive.com Subject: [PATCH v3 1/6] target/riscv: Remove obsolete sfence.vm instruction Date: Mon, 4 Nov 2024 21:51:05 +0000 Message-Id: <20241104-b4-ctr_upstream_v3-v3-1-32fd3c48205f@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> References: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> MIME-Version: 1.0 X-Mailer: b4 0.14.2 Received-SPF: pass client-ip=2a00:1450:4864:20::32f; envelope-from=rkanwal@rivosinc.com; helo=mail-wm1-x32f.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 Signed-off-by: Rajnesh Kanwal Reviewed-by: Alistair Francis Reviewed-by: Jason Chien --- target/riscv/insn32.decode | 1 - target/riscv/insn_trans/trans_privileged.c.inc | 5 ----- 2 files changed, 6 deletions(-) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index c45b8fa1d80279f79f70be0531dd88b28208c206..66353a66786a1e2482dc248b7a4c480b17884808 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -119,7 +119,6 @@ sret 0001000 00010 00000 000 00000 1110011 mret 0011000 00010 00000 000 00000 1110011 wfi 0001000 00101 00000 000 00000 1110011 sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma -sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm # *** RV32I Base Instruction Set *** lui .................... ..... 0110111 @u diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc index bc5263a4e0f1f1853f2152e11ae2a60c31c4f39c..4eccdddeaaf0c242cf3b2c268bae3230126dbc7c 100644 --- a/target/riscv/insn_trans/trans_privileged.c.inc +++ b/target/riscv/insn_trans/trans_privileged.c.inc @@ -127,8 +127,3 @@ static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a) #endif return false; } - -static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a) -{ - return false; -} From patchwork Mon Nov 4 21:51:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13862144 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 3BE3FD1CA00 for ; Mon, 4 Nov 2024 21:54:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t8510-0007y1-3f; Mon, 04 Nov 2024 16:53:38 -0500 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 1t850y-0007wm-Dy for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:36 -0500 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t850w-00011b-I3 for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:36 -0500 Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-431688d5127so37872125e9.0 for ; Mon, 04 Nov 2024 13:53:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1730757213; x=1731362013; 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=DDLRcwzr6VXqmP37s1Pho6urX1riE8cy6cAg2/tgJpY=; b=RAjzHsusYMoy27fDB4VD7bhSIk6cUMKF4bi5HZeyEAdu3MaZy228oQ7uy+PMXpb0hK 2v6b5Xg2EFUxiGxeuEc2N19cDNHw4kR40t+NY+YpUKoX/7QGfUX62KGJDrssjHByav3p HcVNcnlTT11OgasmAD3/ODHP6a5pWRFaYY5NixinoIAnBymwC6Dfyg3yN4poy6SxaGSV dn9gNIvMwlGs5fry0pLk8pdB92wk9wEm3PmQjBoUP03l2iYKpYrRcBVKLat9TGuB/Uay G30If5mVn6qKWDChss4j1S3B1y8+kwgN9C83lFksrRUkvFVpIdzDH9Kkt8tP6JsUWniX Q48Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730757213; x=1731362013; 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=DDLRcwzr6VXqmP37s1Pho6urX1riE8cy6cAg2/tgJpY=; b=t8vXa1fPVYYNwQDPZGaqLYgopKK4r/gK1Hhxdrx0Wm3VrOOa7j83N7wI/2OtwVJOtf W4z8A6jzWMh807WoqJokoz/OidVGO+pGuVkEiYSDkv/Sb0OQHD/EskXKCn9Nk5ruo+7i h4EJdzmWffASQth3MI7ls4ZJOO5LVXfkii/Zt8i/ZMvbFF2UVtLXt8cXTi9gHMS7clwV 7wdB5GoqkxkZR5u4CAdLgh+t7hd1N9+yy+cKZ5VvWKyJLsqLcOvTXHaUf7NnibkPZ08I qIyZs0UIqRzt0hnobLFcGBPSe9tFtVrR6ApXPqJycUvex3YHJeBO+UwBtya4hJ2vjYaw piGw== X-Forwarded-Encrypted: i=1; AJvYcCVpRd68x6yVfM1Y/ZRC5SXwA9AG1UL8GyoRIhT7H3AJmq3J3WBnf0S427h6Xgo1QfLZBi9enulN2mSY@nongnu.org X-Gm-Message-State: AOJu0YwihdTgxL4ghIA/RwNqsp1399eEWqU/8dNiGGG+ZQXe2lpuUrZX Cg9O1+/1rguOyxIbxbAXA6nZkFdFRCzXfSmqHSlT2iQJbkhojdADAUBsPtR4voA= X-Google-Smtp-Source: AGHT+IH0j0Vi/qSiZDgsGcDbn5IlYo5sOrt8UbtrpyIgIwHrsHwPZPKcF0o3GMUeKh+VCsI9D526Uw== X-Received: by 2002:a05:600c:19c8:b0:430:54a4:5b03 with SMTP id 5b1f17b1804b1-4319ac6fad6mr265297895e9.6.1730757212883; Mon, 04 Nov 2024 13:53:32 -0800 (PST) Received: from rkanwal-XPS-15-9520.Home ([2a02:c7c:7527:ee00:8a3a:7719:aa26:21cb]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432a26a6da1sm1537595e9.0.2024.11.04.13.53.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Nov 2024 13:53:32 -0800 (PST) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Rajnesh Kanwal Cc: 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, beeman@rivosinc.com, tech-control-transfer-records@lists.riscv.org, jason.chien@sifive.com, frank.chang@sifive.com Subject: [PATCH v3 2/6] target/riscv: Add Control Transfer Records CSR definitions. Date: Mon, 4 Nov 2024 21:51:06 +0000 Message-Id: <20241104-b4-ctr_upstream_v3-v3-2-32fd3c48205f@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> References: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> MIME-Version: 1.0 X-Mailer: b4 0.14.2 Received-SPF: pass client-ip=2a00:1450:4864:20::330; envelope-from=rkanwal@rivosinc.com; helo=mail-wm1-x330.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, UPPERCASE_50_75=0.008 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: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The Control Transfer Records (CTR) extension provides a method to record a limited branch history in register-accessible internal chip storage. This extension is similar to Arch LBR in x86 and BRBE in ARM. The Extension has been stable and the latest release can be found here https://github.com/riscv/riscv-control-transfer-records/releases/tag/v1.0_rc5 Signed-off-by: Rajnesh Kanwal Acked-by: Alistair Francis --- target/riscv/cpu_bits.h | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index d20468412dca8fef9623dd968bb93e1e6dddc529..0d7571c61de9c49d9c6581fe956ba28beb59bdc5 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -244,6 +244,17 @@ #define CSR_SIEH 0x114 #define CSR_SIPH 0x154 +/* Machine-Level Control transfer records CSRs */ +#define CSR_MCTRCTL 0x34e + +/* Supervisor-Level Control transfer records CSRs */ +#define CSR_SCTRCTL 0x14e +#define CSR_SCTRSTATUS 0x14f +#define CSR_SCTRDEPTH 0x15f + +/* VS-Level Control transfer records CSRs */ +#define CSR_VSCTRCTL 0x24e + /* Hpervisor CSRs */ #define CSR_HSTATUS 0x600 #define CSR_HEDELEG 0x602 @@ -341,6 +352,7 @@ #define SMSTATEEN0_CS (1ULL << 0) #define SMSTATEEN0_FCSR (1ULL << 1) #define SMSTATEEN0_JVT (1ULL << 2) +#define SMSTATEEN0_CTR (1ULL << 54) #define SMSTATEEN0_P1P13 (1ULL << 56) #define SMSTATEEN0_HSCONTXT (1ULL << 57) #define SMSTATEEN0_IMSIC (1ULL << 58) @@ -860,6 +872,88 @@ 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) +/* CTR control register commom fields */ +#define XCTRCTL_U BIT_ULL(0) +#define XCTRCTL_S BIT_ULL(1) +#define XCTRCTL_RASEMU BIT_ULL(7) +#define XCTRCTL_STE BIT_ULL(8) +#define XCTRCTL_BPFRZ BIT_ULL(11) +#define XCTRCTL_LCOFIFRZ BIT_ULL(12) +#define XCTRCTL_EXCINH BIT_ULL(33) +#define XCTRCTL_INTRINH BIT_ULL(34) +#define XCTRCTL_TRETINH BIT_ULL(35) +#define XCTRCTL_NTBREN BIT_ULL(36) +#define XCTRCTL_TKBRINH BIT_ULL(37) +#define XCTRCTL_INDCALLINH BIT_ULL(40) +#define XCTRCTL_DIRCALLINH BIT_ULL(41) +#define XCTRCTL_INDJMPINH BIT_ULL(42) +#define XCTRCTL_DIRJMPINH BIT_ULL(43) +#define XCTRCTL_CORSWAPINH BIT_ULL(44) +#define XCTRCTL_RETINH BIT_ULL(45) +#define XCTRCTL_INDLJMPINH BIT_ULL(46) +#define XCTRCTL_DIRLJMPINH BIT_ULL(47) + +#define XCTRCTL_MASK (XCTRCTL_U | XCTRCTL_S | XCTRCTL_RASEMU | \ + XCTRCTL_STE | XCTRCTL_BPFRZ | XCTRCTL_LCOFIFRZ | \ + XCTRCTL_EXCINH | XCTRCTL_INTRINH | XCTRCTL_TRETINH | \ + XCTRCTL_NTBREN | XCTRCTL_TKBRINH | XCTRCTL_INDCALLINH | \ + XCTRCTL_DIRCALLINH | XCTRCTL_INDJMPINH | \ + XCTRCTL_DIRJMPINH | XCTRCTL_CORSWAPINH | \ + XCTRCTL_RETINH | XCTRCTL_INDLJMPINH | XCTRCTL_DIRLJMPINH) + +#define XCTRCTL_INH_START 32U + +/* CTR mctrctl bits */ +#define MCTRCTL_M BIT_ULL(2) +#define MCTRCTL_MTE BIT_ULL(9) + +#define MCTRCTL_MASK (XCTRCTL_MASK | MCTRCTL_M | MCTRCTL_MTE) +#define SCTRCTL_MASK XCTRCTL_MASK +#define VSCTRCTL_MASK XCTRCTL_MASK + +/* sctrstatus CSR bits. */ +#define SCTRSTATUS_WRPTR_MASK 0xFF +#define SCTRSTATUS_FROZEN BIT(31) +#define SCTRSTATUS_MASK (SCTRSTATUS_WRPTR_MASK | SCTRSTATUS_FROZEN) + +/* sctrdepth CSR bits. */ +#define SCTRDEPTH_MASK 0x7 +#define SCTRDEPTH_MIN 0U /* 16 Entries. */ +#define SCTRDEPTH_MAX 4U /* 256 Entries. */ + +#define CTR_ENTRIES_FIRST 0x200 +#define CTR_ENTRIES_LAST 0x2ff + +#define CTRSOURCE_VALID BIT(0) +#define CTRTARGET_MISP BIT(0) + +#define CTRDATA_TYPE_MASK 0xF +#define CTRDATA_CCV BIT(15) +#define CTRDATA_CCM_MASK 0xFFF0000 +#define CTRDATA_CCE_MASK 0xF0000000 + +#define CTRDATA_MASK (CTRDATA_TYPE_MASK | CTRDATA_CCV | \ + CTRDATA_CCM_MASK | CTRDATA_CCE_MASK) + +typedef enum CTRType { + CTRDATA_TYPE_NONE = 0, + CTRDATA_TYPE_EXCEPTION = 1, + CTRDATA_TYPE_INTERRUPT = 2, + CTRDATA_TYPE_EXCEP_INT_RET = 3, + CTRDATA_TYPE_NONTAKEN_BRANCH = 4, + CTRDATA_TYPE_TAKEN_BRANCH = 5, + CTRDATA_TYPE_RESERVED_0 = 6, + CTRDATA_TYPE_RESERVED_1 = 7, + CTRDATA_TYPE_INDIRECT_CALL = 8, + CTRDATA_TYPE_DIRECT_CALL = 9, + CTRDATA_TYPE_INDIRECT_JUMP = 10, + CTRDATA_TYPE_DIRECT_JUMP = 11, + CTRDATA_TYPE_CO_ROUTINE_SWAP = 12, + CTRDATA_TYPE_RETURN = 13, + CTRDATA_TYPE_OTHER_INDIRECT_JUMP = 14, + CTRDATA_TYPE_OTHER_DIRECT_JUMP = 15, +} CTRType; + /* MISELECT, SISELECT, and VSISELECT bits (AIA) */ #define ISELECT_IPRIO0 0x30 #define ISELECT_IPRIO15 0x3f From patchwork Mon Nov 4 21:51:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13862145 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 A2A4DD1CA01 for ; Mon, 4 Nov 2024 21:54:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t8511-0007z3-OD; Mon, 04 Nov 2024 16:53:39 -0500 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 1t850z-0007xZ-KZ for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:37 -0500 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t850x-00011v-Ie for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:37 -0500 Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-43161e7bb25so36529365e9.2 for ; Mon, 04 Nov 2024 13:53:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1730757214; x=1731362014; 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=8z6Ab+BZTXvK83/PrI7caQyTTgNBxBb4DeqJpSZpkaU=; b=cdVuO35M/sOpU7FXkcXJx+qwFO/lZpgLa7Y5pb5ppjNZhvqPVa7/VUVksKwjw5wy92 9Ax+2rkt4gzMWrhzPKmdi53XwyOmQyTzhspI1i1JlZgY+OlweZ73kOzWfWeGkMtpVq4P j2wOAhzvfzLNI7wH/zoTK26R2RdwcbvWNOmALm6i7R5LyD0dMxuPwZjSJlECFkHQxCNe DjLItmdSqdfEHyyEEuIEcPUQkocBUZ/gE2YubVIMl2ZsYlgwTcvgtf8lGxAo1XIvR9Ah 3Cc2gc0N6C69vB8Xlg1lVLixH1U9W3nIEMgEbd9jL/OUW+p9BwFt2XoLpB9sWH1Vo7pX JAPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730757214; x=1731362014; 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=8z6Ab+BZTXvK83/PrI7caQyTTgNBxBb4DeqJpSZpkaU=; b=CTU1Dr1Rp3e9hELVzZZfQJ7FeKu4VZponno0dbdYDob+rVHEt1hUEwMKbDHNJJNjbW c2oqO9lVg/5cIcxBr8/JvwioxSf4Ql/wst7ELEllY+Wpvlo2NcQ57kOvt7mj4vGNUeSv M6hv1vR8Ggu4x8UKRmYVmqVE593MgSDP4tjg03CmWXm176iUgg04bKsrqHOQVDESluCg lqurWoSjON9rt+0t3rOF0FmzbAPOrJW3V7pBpiUVDSGuGpYtIougQetHRY0dcpj7IZob X8LiOB04gHP1lnAcUQzwIGoP8olhOv65EaGATCKXvn+gYPG0DpHz5ZyrAIDPJFSKokus XUJQ== X-Forwarded-Encrypted: i=1; AJvYcCVnDMhw/oKgpDXcEnWeJcyjq3rcLVR39QL9lmLP3GK9JsssVsdUZ0/EL6MNTvL8wYmU7HCVCwmaLXGa@nongnu.org X-Gm-Message-State: AOJu0Yz1zUtm2DzLvQ2rhlYDSsOVofuEBDovJMHe/kYSFnSP512k/8o7 ACptIzXx2SoX68YLjYNdI5jb+zqlK6eIDDGGNTL4NKEL4I7EdPo6ksdwOG7E35Q= X-Google-Smtp-Source: AGHT+IFtjSqQP8/WY2Dp92GVLIBTG22Di6wD9FbUn+UgVoH3c8uhVE/yvPwVepEWVx3sglPkYrKQ7w== X-Received: by 2002:a05:600c:4215:b0:431:55af:a230 with SMTP id 5b1f17b1804b1-431bb9e6031mr183295245e9.33.1730757214135; Mon, 04 Nov 2024 13:53:34 -0800 (PST) Received: from rkanwal-XPS-15-9520.Home ([2a02:c7c:7527:ee00:8a3a:7719:aa26:21cb]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432a26a6da1sm1537595e9.0.2024.11.04.13.53.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Nov 2024 13:53:33 -0800 (PST) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Rajnesh Kanwal Cc: 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, beeman@rivosinc.com, tech-control-transfer-records@lists.riscv.org, jason.chien@sifive.com, frank.chang@sifive.com Subject: [PATCH v3 3/6] target/riscv: Add support for Control Transfer Records extension CSRs. Date: Mon, 4 Nov 2024 21:51:07 +0000 Message-Id: <20241104-b4-ctr_upstream_v3-v3-3-32fd3c48205f@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> References: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> MIME-Version: 1.0 X-Mailer: b4 0.14.2 Received-SPF: pass client-ip=2a00:1450:4864:20::331; envelope-from=rkanwal@rivosinc.com; helo=mail-wm1-x331.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 commit adds support for [m|s|vs]ctrcontrol, sctrstatus and sctrdepth CSRs handling. Signed-off-by: Rajnesh Kanwal --- target/riscv/cpu.h | 5 ++ target/riscv/cpu_cfg.h | 2 + target/riscv/csr.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d775866344f5cc3dda5c4050660a4b87d7444756..0ffe0d5a74aa699fc34453e072bed27001819a5e 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -305,6 +305,11 @@ struct CPUArchState { target_ulong mcause; target_ulong mtval; /* since: priv-1.10.0 */ + uint64_t mctrctl; + uint32_t sctrdepth; + uint32_t sctrstatus; + uint64_t vsctrctl; + /* Machine and Supervisor interrupt priorities */ uint8_t miprio[64]; uint8_t siprio[64]; diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h index b2be3d47c7a35b177b4d6517af9257973bd5d3b0..91625d6a6bea425446f0ce2bd271c951b104136b 100644 --- a/target/riscv/cpu_cfg.h +++ b/target/riscv/cpu_cfg.h @@ -127,6 +127,8 @@ struct RISCVCPUConfig { bool ext_zvfhmin; bool ext_smaia; bool ext_ssaia; + bool ext_smctr; + bool ext_ssctr; bool ext_sscofpmf; bool ext_smepmp; bool rvv_ta_all_1s; diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 2369a746a28511c6d7d1214ebabe5af61f4c1a90..0805b8afc05bd8fcd75ed1c1ad669efbb180800d 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -632,6 +632,48 @@ static RISCVException pointer_masking(CPURISCVState *env, int csrno) return RISCV_EXCP_ILLEGAL_INST; } +/* + * M-mode: + * Without ext_smctr raise illegal inst excep. + * Otherwise everything is accessible to m-mode. + * + * S-mode: + * Without ext_ssctr or mstateen.ctr raise illegal inst excep. + * Otherwise everything other than mctrctl is accessible. + * + * VS-mode: + * Without ext_ssctr or mstateen.ctr raise illegal inst excep. + * Without hstateen.ctr raise virtual illegal inst excep. + * Otherwise allow sctrctl (vsctrctl), sctrstatus, 0x200-0x2ff entry range. + * Always raise illegal instruction exception for sctrdepth. + */ +static RISCVException ctr_mmode(CPURISCVState *env, int csrno) +{ + /* Check if smctr-ext is present */ + if (riscv_cpu_cfg(env)->ext_smctr) { + return RISCV_EXCP_NONE; + } + + return RISCV_EXCP_ILLEGAL_INST; +} + +static RISCVException ctr_smode(CPURISCVState *env, int csrno) +{ + const RISCVCPUConfig *cfg = riscv_cpu_cfg(env); + + if (!cfg->ext_smctr && !cfg->ext_ssctr) { + return RISCV_EXCP_ILLEGAL_INST; + } + + RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_CTR); + if (ret == RISCV_EXCP_NONE && csrno == CSR_SCTRDEPTH && + env->virt_enabled) { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } + + return ret; +} + static RISCVException aia_hmode(CPURISCVState *env, int csrno) { int ret; @@ -3096,6 +3138,10 @@ static RISCVException write_mstateen0(CPURISCVState *env, int csrno, wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC); } + if (riscv_cpu_cfg(env)->ext_ssctr) { + wr_mask |= SMSTATEEN0_CTR; + } + return write_mstateen(env, csrno, wr_mask, new_val); } @@ -3135,6 +3181,10 @@ static RISCVException write_mstateen0h(CPURISCVState *env, int csrno, wr_mask |= SMSTATEEN0_P1P13; } + if (riscv_cpu_cfg(env)->ext_ssctr) { + wr_mask |= SMSTATEEN0_CTR; + } + return write_mstateenh(env, csrno, wr_mask, new_val); } @@ -3189,6 +3239,10 @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno, wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC); } + if (riscv_cpu_cfg(env)->ext_ssctr) { + wr_mask |= SMSTATEEN0_CTR; + } + return write_hstateen(env, csrno, wr_mask, new_val); } @@ -3228,6 +3282,10 @@ static RISCVException write_hstateen0h(CPURISCVState *env, int csrno, { uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG; + if (riscv_cpu_cfg(env)->ext_ssctr) { + wr_mask |= SMSTATEEN0_CTR; + } + return write_hstateenh(env, csrno, wr_mask, new_val); } @@ -3927,6 +3985,86 @@ static RISCVException write_satp(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +static RISCVException rmw_sctrdepth(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t mask = wr_mask & SCTRDEPTH_MASK; + + if (ret_val) { + *ret_val = env->sctrdepth; + } + + env->sctrdepth = (env->sctrdepth & ~mask) | (new_val & mask); + + /* Correct depth. */ + if (mask) { + uint64_t depth = get_field(env->sctrdepth, SCTRDEPTH_MASK); + + if (depth > SCTRDEPTH_MAX) { + depth = SCTRDEPTH_MAX; + env->sctrdepth = set_field(env->sctrdepth, SCTRDEPTH_MASK, depth); + } + + /* Update sctrstatus.WRPTR with a legal value */ + depth = 16 << depth; + env->sctrstatus = + env->sctrstatus & (~SCTRSTATUS_WRPTR_MASK | (depth - 1)); + } + + return RISCV_EXCP_NONE; +} + +static RISCVException rmw_sctrstatus(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint32_t depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK); + uint32_t mask = wr_mask & SCTRSTATUS_MASK; + + if (ret_val) { + *ret_val = env->sctrstatus; + } + + env->sctrstatus = (env->sctrstatus & ~mask) | (new_val & mask); + + /* Update sctrstatus.WRPTR with a legal value */ + env->sctrstatus = env->sctrstatus & (~SCTRSTATUS_WRPTR_MASK | (depth - 1)); + + return RISCV_EXCP_NONE; +} + +static RISCVException rmw_xctrctl(CPURISCVState *env, int csrno, + target_ulong *ret_val, + target_ulong new_val, target_ulong wr_mask) +{ + uint64_t csr_mask, mask = wr_mask; + uint64_t *ctl_ptr = &env->mctrctl; + + if (csrno == CSR_MCTRCTL) { + csr_mask = MCTRCTL_MASK; + } else if (csrno == CSR_SCTRCTL && !env->virt_enabled) { + csr_mask = SCTRCTL_MASK; + } else { + /* + * This is for csrno == CSR_SCTRCTL and env->virt_enabled == true + * or csrno == CSR_VSCTRCTL. + */ + csr_mask = VSCTRCTL_MASK; + ctl_ptr = &env->vsctrctl; + } + + mask &= csr_mask; + + if (ret_val) { + *ret_val = *ctl_ptr & csr_mask; + } + + *ctl_ptr = (*ctl_ptr & ~mask) | (new_val & mask); + + return RISCV_EXCP_NONE; +} + static RISCVException read_vstopi(CPURISCVState *env, int csrno, target_ulong *val) { @@ -5903,6 +6041,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, write_spmbase }, + [CSR_MCTRCTL] = { "mctrctl", ctr_mmode, NULL, NULL, rmw_xctrctl }, + [CSR_SCTRCTL] = { "sctrctl", ctr_smode, NULL, NULL, rmw_xctrctl }, + [CSR_VSCTRCTL] = { "vsctrctl", ctr_smode, NULL, NULL, rmw_xctrctl }, + [CSR_SCTRDEPTH] = { "sctrdepth", ctr_smode, NULL, NULL, rmw_sctrdepth }, + [CSR_SCTRSTATUS] = { "sctrstatus", ctr_smode, NULL, NULL, rmw_sctrstatus }, + /* Performance Counters */ [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter }, [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_hpmcounter }, From patchwork Mon Nov 4 21:51:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13862148 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 9D4A6D1CA00 for ; Mon, 4 Nov 2024 21:56:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t8513-0007zd-4R; Mon, 04 Nov 2024 16:53:41 -0500 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 1t8511-0007z4-UH for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:40 -0500 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t850z-00012F-0x for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:39 -0500 Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-4314fa33a35so36592685e9.1 for ; Mon, 04 Nov 2024 13:53:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1730757215; x=1731362015; 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=ZHwsFZxETiNjwBNjmwptneTUnx3dt1KbN2JfirKHJnM=; b=zudVh+052XRmyRCl6orFaV4Ssqh4Nk1uQEfSOPNdc6fYl+bGwUX6Q6XsXjadi4f5SP 4vwdNPjL3hbCZPxDwDqQun4/MYXckDzU9HJmm2GUKAXDCGubDsTtwyUYUBb2d9Gfw4GU j8JlD0kURczUNI4Keo+VhxSsO/KMsFD2Zt2n8Kf4QfkVero3hOpRqWnHGbfriYErsL/1 4espdJGq+LxFbWFrGSmN5cgtnh9AQWqXl/BnxXBUtlyhs5itTSg41/6KyPkMT+bmyVgu L/RyxCXn9rnsFhJIzV0rZXLP+nvbWBKebfJYjt+W/O2KTdN4MiyNRc1Qp7qefqO58t9/ ToBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730757215; x=1731362015; 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=ZHwsFZxETiNjwBNjmwptneTUnx3dt1KbN2JfirKHJnM=; b=W8N1gWdDgDXiZotA6H1vp7CJML9CRrAPv/lnlxV3G2Td47T8GJKE8PwTbvtToHvp7+ lArAvIkB1RB4RM9h+BhUMsbaawAYm1u5drGvv5zFBwj3uI/vGg/KnAu8XHZuMIYVI8Mm bO1XegA5HnYQ8tKGW7rvVQGRTtC2GwbC5XyzNkKvkM39G7kR9D3yFsrOoKpMfKzYAyFI VCmlq3bVqW2UPsWce5sWiVCog5tT58irCzw+kpagSEydVQrD0yLlfUA/xuRAk98TJY/B +9UwoTPcMDUrchjHkTMQ2cL4iacbBzoSVb+8MrjejNPQIu6ySyHpi4w8MFiZcaw/7+L6 D53Q== X-Forwarded-Encrypted: i=1; AJvYcCUaZ8Cya+jWVOLSD06vqIj8vBawShI/ug3/Fx4p83g75rvBKWNpQpVoMxv0+YUhgnt7j2ryyVSJ1J51@nongnu.org X-Gm-Message-State: AOJu0YwfhALFHKfN2JzXuVQ66e0UKJJlw9qUMHWREjmk0PKtbx1T+kIu evqDadLGLbrOnJSY9z6xJVa8kHfZWeN3K+8Ek4/w3GykYxFPkMCcrY6hOrs3fuY2YDuymkJ8TNb m X-Google-Smtp-Source: AGHT+IE2LwiobvJusw3xtA6h3tq+3IrdBe7nu+QeSR37K06ZCAFibE2a15zexFV8nte+GmOq6N/FPA== X-Received: by 2002:a05:600c:4753:b0:431:5632:4497 with SMTP id 5b1f17b1804b1-431bb9d1122mr207573645e9.26.1730757215406; Mon, 04 Nov 2024 13:53:35 -0800 (PST) Received: from rkanwal-XPS-15-9520.Home ([2a02:c7c:7527:ee00:8a3a:7719:aa26:21cb]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432a26a6da1sm1537595e9.0.2024.11.04.13.53.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Nov 2024 13:53:35 -0800 (PST) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Rajnesh Kanwal Cc: 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, beeman@rivosinc.com, tech-control-transfer-records@lists.riscv.org, jason.chien@sifive.com, frank.chang@sifive.com Subject: [PATCH v3 4/6] target/riscv: Add support to record CTR entries. Date: Mon, 4 Nov 2024 21:51:08 +0000 Message-Id: <20241104-b4-ctr_upstream_v3-v3-4-32fd3c48205f@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> References: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> MIME-Version: 1.0 X-Mailer: b4 0.14.2 Received-SPF: pass client-ip=2a00:1450:4864:20::335; envelope-from=rkanwal@rivosinc.com; helo=mail-wm1-x335.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 commit adds logic to records CTR entries of different types and adds required hooks in TCG and interrupt/Exception logic to record events. This commit also adds support to invoke freeze CTR logic for breakpoint exceptions and counter overflow interrupts. Signed-off-by: Rajnesh Kanwal --- target/riscv/cpu.h | 7 + target/riscv/cpu_helper.c | 259 +++++++++++++++++++++++++ target/riscv/helper.h | 8 +- target/riscv/insn_trans/trans_privileged.c.inc | 6 +- target/riscv/insn_trans/trans_rvi.c.inc | 31 +++ target/riscv/insn_trans/trans_rvzce.c.inc | 20 ++ target/riscv/op_helper.c | 126 +++++++++++- target/riscv/translate.c | 10 + 8 files changed, 461 insertions(+), 6 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 0ffe0d5a74aa699fc34453e072bed27001819a5e..189dba78970c414bff8aa252507c4585844bd846 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -310,6 +310,10 @@ struct CPUArchState { uint32_t sctrstatus; uint64_t vsctrctl; + uint64_t ctr_src[16 << SCTRDEPTH_MAX]; + uint64_t ctr_dst[16 << SCTRDEPTH_MAX]; + uint64_t ctr_data[16 << SCTRDEPTH_MAX]; + /* Machine and Supervisor interrupt priorities */ uint8_t miprio[64]; uint8_t siprio[64]; @@ -608,6 +612,9 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit); void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en); +void riscv_ctr_add_entry(CPURISCVState *env, target_long src, target_long dst, + enum CTRType type, target_ulong prev_priv, bool prev_virt); + void riscv_translate_init(void); G_NORETURN void riscv_raise_exception(CPURISCVState *env, uint32_t exception, uintptr_t pc); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 395a1d9140615d697408054ed680ad1f9b26a83e..06defc870cf85ed7c646ca6b066ce556bab1e757 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -691,6 +691,247 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv, } } +static void riscv_ctr_freeze(CPURISCVState *env, uint64_t freeze_mask, + bool virt) +{ + uint64_t ctl = virt ? env->vsctrctl : env->mctrctl; + + assert((freeze_mask & (~(XCTRCTL_BPFRZ | XCTRCTL_LCOFIFRZ))) == 0); + + if (ctl & freeze_mask) { + env->sctrstatus |= SCTRSTATUS_FROZEN; + } +} + +static uint64_t riscv_ctr_priv_to_mask(target_ulong priv, bool virt) +{ + switch (priv) { + case PRV_M: + return MCTRCTL_M; + case PRV_S: + if (virt) { + return XCTRCTL_S; + } + return XCTRCTL_S; + case PRV_U: + if (virt) { + return XCTRCTL_U; + } + return XCTRCTL_U; + } + + g_assert_not_reached(); +} + +static uint64_t riscv_ctr_get_control(CPURISCVState *env, target_long priv, + bool virt) +{ + switch (priv) { + case PRV_M: + return env->mctrctl; + case PRV_S: + case PRV_U: + if (virt) { + return env->vsctrctl; + } + return env->mctrctl; + } + + g_assert_not_reached(); +} + +/* + * This function assumes that src privilege and target privilege are not same + * and src privilege is less than target privilege. This includes the virtual + * state as well. + */ +static bool riscv_ctr_check_xte(CPURISCVState *env, target_long src_prv, + bool src_virt) +{ + target_long tgt_prv = env->priv; + bool res = true; + + /* + * VS and U mode are same in terms of xTE bits required to record an + * external trap. See 6.1.2. External Traps, table 8 External Trap Enable + * Requirements. This changes VS to U to simplify the logic a bit. + */ + if (src_virt && src_prv == PRV_S) { + src_prv = PRV_U; + } else if (env->virt_enabled && tgt_prv == PRV_S) { + tgt_prv = PRV_U; + } + + /* VU mode is an outlier here. */ + if (src_virt && src_prv == PRV_U) { + res &= !!(env->vsctrctl & XCTRCTL_STE); + } + + switch (src_prv) { + case PRV_U: + if (tgt_prv == PRV_U) { + break; + } + res &= !!(env->mctrctl & XCTRCTL_STE); + /* fall-through */ + case PRV_S: + if (tgt_prv == PRV_S) { + break; + } + res &= !!(env->mctrctl & MCTRCTL_MTE); + /* fall-through */ + case PRV_M: + break; + } + + return res; +} + +/* + * Special cases for traps and trap returns: + * + * 1- Traps, and trap returns, between enabled modes are recorded as normal. + * 2- Traps from an inhibited mode to an enabled mode, and trap returns from an + * enabled mode back to an inhibited mode, are partially recorded. In such + * cases, the PC from the inhibited mode (source PC for traps, and target PC + * for trap returns) is 0. + * + * 3- Trap returns from an inhibited mode to an enabled mode are not recorded. + * Traps from an enabled mode to an inhibited mode, known as external traps, + * receive special handling. + * By default external traps are not recorded, but a handshake mechanism exists + * to allow partial recording. Software running in the target mode of the trap + * can opt-in to allowing CTR to record traps into that mode even when the mode + * is inhibited. The MTE, STE, and VSTE bits allow M-mode, S-mode, and VS-mode, + * respectively, to opt-in. When an External Trap occurs, and xTE=1, such that + * x is the target privilege mode of the trap, will CTR record the trap. In such + * cases, the target PC is 0. + */ +/* + * CTR arrays are implemented as circular buffers and new entry is stored at + * sctrstatus.WRPTR, but they are presented to software as moving circular + * buffers. Which means, software get's the illusion that whenever a new entry + * is added the whole buffer is moved by one place and the new entry is added at + * the start keeping new entry at idx 0 and older ones follow. + * + * Depth = 16. + * + * buffer [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F] + * WRPTR W + * entry 7 6 5 4 3 2 1 0 F E D C B A 9 8 + * + * When a new entry is added: + * buffer [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F] + * WRPTR W + * entry 8 7 6 5 4 3 2 1 0 F E D C B A 9 + * + * entry here denotes the logical entry number that software can access + * using ctrsource, ctrtarget and ctrdata registers. So xiselect 0x200 + * will return entry 0 i-e buffer[8] and 0x201 will return entry 1 i-e + * buffer[7]. Here is how we convert entry to buffer idx. + * + * entry = isel - CTR_ENTRIES_FIRST; + * idx = (sctrstatus.WRPTR - entry - 1) & (depth - 1); + */ +void riscv_ctr_add_entry(CPURISCVState *env, target_long src, target_long dst, + enum CTRType type, target_ulong src_priv, bool src_virt) +{ + bool tgt_virt = env->virt_enabled; + uint64_t src_mask = riscv_ctr_priv_to_mask(src_priv, src_virt); + uint64_t tgt_mask = riscv_ctr_priv_to_mask(env->priv, tgt_virt); + uint64_t src_ctrl = riscv_ctr_get_control(env, src_priv, src_virt); + uint64_t tgt_ctrl = riscv_ctr_get_control(env, env->priv, tgt_virt); + uint64_t depth, head; + bool ext_trap = false; + + /* + * Return immediately if both target and src recording is disabled or if + * CTR is in frozen state. + */ + if ((!(src_ctrl & src_mask) && !(tgt_ctrl & tgt_mask)) || + env->sctrstatus & SCTRSTATUS_FROZEN) { + return; + } + + /* + * With RAS Emul enabled, only allow Indirect, direct calls, Function + * returns and Co-routine swap types. + */ + if (tgt_ctrl & XCTRCTL_RASEMU && + type != CTRDATA_TYPE_INDIRECT_CALL && + type != CTRDATA_TYPE_DIRECT_CALL && + type != CTRDATA_TYPE_RETURN && + type != CTRDATA_TYPE_CO_ROUTINE_SWAP) { + return; + } + + if (type == CTRDATA_TYPE_EXCEPTION || type == CTRDATA_TYPE_INTERRUPT) { + /* Case 2 for traps. */ + if (!(src_ctrl & src_mask)) { + src = 0; + } else if (!(tgt_ctrl & tgt_mask)) { + /* Check if target priv-mode has allowed external trap recording. */ + if (!riscv_ctr_check_xte(env, src_priv, src_virt)) { + return; + } + + ext_trap = true; + dst = 0; + } + } else if (type == CTRDATA_TYPE_EXCEP_INT_RET) { + /* + * Case 3 for trap returns. Trap returns from inhibited mode are not + * recorded. + */ + if (!(src_ctrl & src_mask)) { + return; + } + + /* Case 2 for trap returns. */ + if (!(tgt_ctrl & tgt_mask)) { + dst = 0; + } + } + + /* Ignore filters in case of RASEMU mode or External trap. */ + if (!(tgt_ctrl & XCTRCTL_RASEMU) && !ext_trap) { + /* + * Check if the specific type is inhibited. Not taken branch filter is + * an enable bit and needs to be checked separatly. + */ + bool check = tgt_ctrl & BIT_ULL(type + XCTRCTL_INH_START); + if ((type == CTRDATA_TYPE_NONTAKEN_BRANCH && !check) || + (type != CTRDATA_TYPE_NONTAKEN_BRANCH && check)) { + return; + } + } + + head = get_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK); + + depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK); + if (tgt_ctrl & XCTRCTL_RASEMU && type == CTRDATA_TYPE_RETURN) { + head = (head - 1) & (depth - 1); + + env->ctr_src[head] &= ~CTRSOURCE_VALID; + env->sctrstatus = + set_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK, head); + return; + } + + /* In case of Co-routine SWAP we overwrite latest entry. */ + if (tgt_ctrl & XCTRCTL_RASEMU && type == CTRDATA_TYPE_CO_ROUTINE_SWAP) { + head = (head - 1) & (depth - 1); + } + + env->ctr_src[head] = src | CTRSOURCE_VALID; + env->ctr_dst[head] = dst & ~CTRTARGET_MISP; + env->ctr_data[head] = set_field(0, CTRDATA_TYPE_MASK, type); + + head = (head + 1) & (depth - 1); + + env->sctrstatus = set_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK, head); +} + void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en) { g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED); @@ -1666,10 +1907,13 @@ void riscv_cpu_do_interrupt(CPUState *cs) !(env->mip & (1 << cause)); bool vs_injected = env->hvip & (1 << cause) & env->hvien && !(env->mip & (1 << cause)); + const bool prev_virt = env->virt_enabled; + const target_ulong prev_priv = env->priv; target_ulong tval = 0; target_ulong tinst = 0; target_ulong htval = 0; target_ulong mtval2 = 0; + target_ulong src; if (!async) { /* set tval to badaddr for traps with address information */ @@ -1804,6 +2048,8 @@ void riscv_cpu_do_interrupt(CPUState *cs) env->pc = (env->stvec >> 2 << 2) + ((async && (env->stvec & 3) == 1) ? cause * 4 : 0); riscv_cpu_set_mode(env, PRV_S, virt); + + src = env->sepc; } else { /* handle the trap in M-mode */ if (riscv_has_ext(env, RVH)) { @@ -1835,6 +2081,19 @@ void riscv_cpu_do_interrupt(CPUState *cs) env->pc = (env->mtvec >> 2 << 2) + ((async && (env->mtvec & 3) == 1) ? cause * 4 : 0); riscv_cpu_set_mode(env, PRV_M, virt); + src = env->mepc; + } + + if (riscv_cpu_cfg(env)->ext_smctr || riscv_cpu_cfg(env)->ext_ssctr) { + if (async && cause == IRQ_PMU_OVF) { + riscv_ctr_freeze(env, XCTRCTL_LCOFIFRZ, virt); + } else if (!async && cause == RISCV_EXCP_BREAKPOINT) { + riscv_ctr_freeze(env, XCTRCTL_BPFRZ, virt); + } + + riscv_ctr_add_entry(env, src, env->pc, + async ? CTRDATA_TYPE_INTERRUPT : CTRDATA_TYPE_EXCEPTION, + prev_priv, prev_virt); } /* diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 451261ce5a4f6138a06afb1e4abc0c838acb283e..b8fb7c87348d1f850628ab3769afda08158739be 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -129,12 +129,16 @@ DEF_HELPER_2(csrr_i128, tl, env, int) DEF_HELPER_4(csrw_i128, void, env, int, tl, tl) DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl) #ifndef CONFIG_USER_ONLY -DEF_HELPER_1(sret, tl, env) -DEF_HELPER_1(mret, tl, env) +DEF_HELPER_2(sret, tl, env, tl) +DEF_HELPER_2(mret, tl, env, tl) DEF_HELPER_1(wfi, void, env) DEF_HELPER_1(wrs_nto, void, env) DEF_HELPER_1(tlb_flush, void, env) DEF_HELPER_1(tlb_flush_all, void, env) +DEF_HELPER_4(ctr_branch, void, env, tl, tl, tl) +DEF_HELPER_4(ctr_jal, void, env, tl, tl, tl) +DEF_HELPER_5(ctr_jalr, void, env, tl, tl, tl, tl) +DEF_HELPER_3(ctr_popret, void, env, tl, tl) /* Native Debug */ DEF_HELPER_1(itrigger_match, void, env) #endif diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc index 4eccdddeaaf0c242cf3b2c268bae3230126dbc7c..339d65915173482507849ad36ff4eb3d1403c148 100644 --- a/target/riscv/insn_trans/trans_privileged.c.inc +++ b/target/riscv/insn_trans/trans_privileged.c.inc @@ -78,9 +78,10 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a) { #ifndef CONFIG_USER_ONLY if (has_ext(ctx, RVS)) { + TCGv src = tcg_constant_tl(ctx->base.pc_next); decode_save_opc(ctx); translator_io_start(&ctx->base); - gen_helper_sret(cpu_pc, tcg_env); + gen_helper_sret(cpu_pc, tcg_env, src); exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; } else { @@ -95,9 +96,10 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a) static bool trans_mret(DisasContext *ctx, arg_mret *a) { #ifndef CONFIG_USER_ONLY + TCGv src = tcg_constant_tl(ctx->base.pc_next); decode_save_opc(ctx); translator_io_start(&ctx->base); - gen_helper_mret(cpu_pc, tcg_env); + gen_helper_mret(cpu_pc, tcg_env, src); exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; return true; diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index 98e3806d5e5a31715981244ba48acf770e2b894b..54c304c63aececba4d5166a3e2ad3c6aa4d6ea8f 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -75,6 +75,14 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) gen_set_gpr(ctx, a->rd, succ_pc); tcg_gen_mov_tl(cpu_pc, target_pc); +#ifndef CONFIG_USER_ONLY + if (ctx->cfg_ptr->ext_smctr || ctx->cfg_ptr->ext_ssctr) { + TCGv src = tcg_constant_tl(ctx->base.pc_next); + TCGv rs1 = tcg_constant_tl(a->rs1); + TCGv rd = tcg_constant_tl(a->rd); + gen_helper_ctr_jalr(tcg_env, src, cpu_pc, rd, rs1); + } +#endif lookup_and_goto_ptr(ctx); if (misaligned) { @@ -164,6 +172,11 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) TCGv src1 = get_gpr(ctx, a->rs1, EXT_SIGN); TCGv src2 = get_gpr(ctx, a->rs2, EXT_SIGN); target_ulong orig_pc_save = ctx->pc_save; +#ifndef CONFIG_USER_ONLY + TCGv src = tcg_constant_tl(ctx->base.pc_next); + TCGv taken; + TCGv dest; +#endif if (get_xl(ctx) == MXL_RV128) { TCGv src1h = get_gprh(ctx, a->rs1); @@ -176,6 +189,16 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) } else { tcg_gen_brcond_tl(cond, src1, src2, l); } + +#ifndef CONFIG_USER_ONLY + if (ctx->cfg_ptr->ext_smctr || ctx->cfg_ptr->ext_ssctr) { + dest = tcg_constant_tl(ctx->base.pc_next + ctx->cur_insn_len); + taken = tcg_constant_tl(0); + + gen_helper_ctr_branch(tcg_env, src, dest, taken); + } +#endif + gen_goto_tb(ctx, 1, ctx->cur_insn_len); ctx->pc_save = orig_pc_save; @@ -188,6 +211,14 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) gen_pc_plus_diff(target_pc, ctx, a->imm); gen_exception_inst_addr_mis(ctx, target_pc); } else { +#ifndef CONFIG_USER_ONLY + if (ctx->cfg_ptr->ext_smctr || ctx->cfg_ptr->ext_ssctr) { + dest = tcg_constant_tl(ctx->base.pc_next + a->imm); + taken = tcg_constant_tl(1); + + gen_helper_ctr_branch(tcg_env, src, dest, taken); + } +#endif gen_goto_tb(ctx, 0, a->imm); } ctx->pc_save = -1; diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc b/target/riscv/insn_trans/trans_rvzce.c.inc index cd234ad960724c936b92afb6fd1f3c7c2a37cb80..377d3fff70bcbd21199e485161d51c6ef31593c5 100644 --- a/target/riscv/insn_trans/trans_rvzce.c.inc +++ b/target/riscv/insn_trans/trans_rvzce.c.inc @@ -204,6 +204,12 @@ static bool gen_pop(DisasContext *ctx, arg_cmpp *a, bool ret, bool ret_val) if (ret) { TCGv ret_addr = get_gpr(ctx, xRA, EXT_SIGN); tcg_gen_mov_tl(cpu_pc, ret_addr); +#ifndef CONFIG_USER_ONLY + if (ctx->cfg_ptr->ext_smctr || ctx->cfg_ptr->ext_ssctr) { + TCGv src = tcg_constant_tl(ctx->base.pc_next); + gen_helper_ctr_popret(tcg_env, src, cpu_pc); + } +#endif tcg_gen_lookup_and_goto_ptr(); ctx->base.is_jmp = DISAS_NORETURN; } @@ -309,6 +315,20 @@ static bool trans_cm_jalt(DisasContext *ctx, arg_cm_jalt *a) gen_set_gpr(ctx, xRA, succ_pc); } +#ifndef CONFIG_USER_ONLY + if (ctx->cfg_ptr->ext_smctr || ctx->cfg_ptr->ext_ssctr) { + /* + * We are reusing helper_ctr_jal() here. If rd is x1 or x5, + * this will record a direct call (cm.jalt) and if it's x0 + * then this will record a direct jump (cm.jt). + */ + TCGv rd = tcg_constant_tl(a->index >= 32 ? 1 : 0); + TCGv src = tcg_constant_tl(ctx->base.pc_next); + gen_helper_ctr_jal(tcg_env, src, addr, rd); + } +#endif + + tcg_gen_mov_tl(cpu_pc, addr); tcg_gen_lookup_and_goto_ptr(); diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 25a5263573b94c064fea7b6ee71549db9777b59f..5a1e92c45ed108d038ad30f5c7031b05855ac110 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -259,10 +259,12 @@ void helper_cbo_inval(CPURISCVState *env, target_ulong address) #ifndef CONFIG_USER_ONLY -target_ulong helper_sret(CPURISCVState *env) +target_ulong helper_sret(CPURISCVState *env, target_ulong curr_pc) { uint64_t mstatus; target_ulong prev_priv, prev_virt = env->virt_enabled; + const target_ulong src_priv = env->priv; + const bool src_virt = env->virt_enabled; if (!(env->priv >= PRV_S)) { riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); @@ -309,10 +311,15 @@ target_ulong helper_sret(CPURISCVState *env) riscv_cpu_set_mode(env, prev_priv, prev_virt); + if (riscv_cpu_cfg(env)->ext_smctr || riscv_cpu_cfg(env)->ext_ssctr) { + riscv_ctr_add_entry(env, curr_pc, retpc, CTRDATA_TYPE_EXCEP_INT_RET, + src_priv, src_virt); + } + return retpc; } -target_ulong helper_mret(CPURISCVState *env) +target_ulong helper_mret(CPURISCVState *env, target_ulong curr_pc) { if (!(env->priv >= PRV_M)) { riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); @@ -350,9 +357,124 @@ target_ulong helper_mret(CPURISCVState *env) riscv_cpu_set_mode(env, prev_priv, prev_virt); + if (riscv_cpu_cfg(env)->ext_smctr || riscv_cpu_cfg(env)->ext_ssctr) { + riscv_ctr_add_entry(env, curr_pc, retpc, CTRDATA_TYPE_EXCEP_INT_RET, + PRV_M, false); + } + return retpc; } +/* + * Indirect calls + * - jalr x1, rs where rs != x5; + * - jalr x5, rs where rs != x1; + * - c.jalr rs1 where rs1 != x5; + * + * Indirect jumps + * - jalr x0, rs where rs != x1 and rs != x5; + * - c.jr rs1 where rs1 != x1 and rs1 != x5. + * + * Returns + * - jalr rd, rs where (rs == x1 or rs == x5) and rd != x1 and rd != x5; + * - c.jr rs1 where rs1 == x1 or rs1 == x5. + * + * Co-routine swap + * - jalr x1, x5; + * - jalr x5, x1; + * - c.jalr x5. + * + * Other indirect jumps + * - jalr rd, rs where rs != x1, rs != x5, rd != x0, rd != x1 and rd != x5. + */ +void helper_ctr_jalr(CPURISCVState *env, target_ulong src, target_ulong dest, + target_ulong rd, target_ulong rs1) +{ + target_ulong curr_priv = env->priv; + bool curr_virt = env->virt_enabled; + + if ((rd == 1 && rs1 != 5) || (rd == 5 && rs1 != 1)) { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_INDIRECT_CALL, + curr_priv, curr_virt); + } else if (rd == 0 && rs1 != 1 && rs1 != 5) { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_INDIRECT_JUMP, + curr_priv, curr_virt); + } else if ((rs1 == 1 || rs1 == 5) && (rd != 1 && rd != 5)) { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_RETURN, + curr_priv, curr_virt); + } else if ((rs1 == 1 && rd == 5) || (rs1 == 5 && rd == 1)) { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_CO_ROUTINE_SWAP, + curr_priv, curr_virt); + } else { + riscv_ctr_add_entry(env, src, dest, + CTRDATA_TYPE_OTHER_INDIRECT_JUMP, curr_priv, + curr_virt); + } +} + +/* + * Direct calls + * - jal x1; + * - jal x5; + * - c.jal. + * - cm.jalt. + * + * Direct jumps + * - jal x0; + * - c.j; + * - cm.jt. + * + * Other direct jumps + * - jal rd where rd != x1 and rd != x5 and rd != x0; + */ +void helper_ctr_jal(CPURISCVState *env, target_ulong src, target_ulong dest, + target_ulong rd) +{ + target_ulong priv = env->priv; + bool virt = env->virt_enabled; + + /* + * If rd is x1 or x5 link registers, treat this as direct call otherwise + * its a direct jump. + */ + if (rd == 1 || rd == 5) { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_DIRECT_CALL, priv, + virt); + } else if (rd == 0) { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_DIRECT_JUMP, priv, + virt); + } else { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_OTHER_DIRECT_JUMP, + priv, virt); + } +} + +/* + * Returns + * - cm.popret + * - cm.popretz + */ +void helper_ctr_popret(CPURISCVState *env, target_ulong src, target_ulong dest) +{ + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_RETURN, + env->priv, env->virt_enabled); +} + +void helper_ctr_branch(CPURISCVState *env, target_ulong src, target_ulong dest, + target_ulong branch_taken) +{ + target_ulong curr_priv = env->priv; + bool curr_virt = env->virt_enabled; + + if (branch_taken) { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_TAKEN_BRANCH, + curr_priv, curr_virt); + } else { + riscv_ctr_add_entry(env, src, dest, CTRDATA_TYPE_NONTAKEN_BRANCH, + curr_priv, curr_virt); + } +} + void helper_wfi(CPURISCVState *env) { CPUState *cs = env_cpu(env); diff --git a/target/riscv/translate.c b/target/riscv/translate.c index acba90f170257cec428bb117652f7ccbb6800c4d..f3ab07755cbcc2db7d225513d96353a6c179a985 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -569,6 +569,16 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) } } +#ifndef CONFIG_USER_ONLY + if (ctx->cfg_ptr->ext_smctr || ctx->cfg_ptr->ext_ssctr) { + TCGv dest = tcg_constant_tl(ctx->base.pc_next + imm); + TCGv src = tcg_constant_tl(ctx->base.pc_next); + TCGv tcg_rd = tcg_constant_tl((target_ulong)rd); + + gen_helper_ctr_jal(tcg_env, src, dest, tcg_rd); + } +#endif + gen_pc_plus_diff(succ_pc, ctx, ctx->cur_insn_len); gen_set_gpr(ctx, rd, succ_pc); From patchwork Mon Nov 4 21:51:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13862143 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 64183D1CA01 for ; Mon, 4 Nov 2024 21:54:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t8515-000813-0T; Mon, 04 Nov 2024 16:53:43 -0500 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 1t8512-0007z6-1L for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:40 -0500 Received: from mail-wm1-x333.google.com ([2a00:1450:4864:20::333]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t8510-00012d-9M for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:39 -0500 Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-43161e7bb25so36529515e9.2 for ; Mon, 04 Nov 2024 13:53:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1730757216; x=1731362016; 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=rDpnK5746mg3pjW3oSgbbU+MRLj1bqe861uk/Dra88A=; b=LbX2Mx6w6/AV7OAnirsa0a8kPSYbSSyriitnFID+KWW8Eo3eLIO0xxfDdVYddngcVo 9tMa7p/5eJUayXYmThpvbCl7bJE7T1VZ7d8FWOrfbLrwsQIwa+mtBRmvFO+vnGH9KH/7 7TwvxwJvZ+DHk3bC3WmC7Ln0D38rhMWmWK8kEJ2mMvZOPiWlaV7/KhSKWBjwkD2+sL/K rfMXAjE74YVJynF9QLuCNIg3uF+iqz2e8Zf4RHmJOmTSq4t/J0GEusozg6KhecbE7R8F UQRTi5i7Y9Bn5U6uc4iABjaU9lr9NDnlU7rVwkvdOXHHe89YqgxExZPwlIr9FJC11Bii xZCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730757216; x=1731362016; 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=rDpnK5746mg3pjW3oSgbbU+MRLj1bqe861uk/Dra88A=; b=LRhf3r/B6ZbeOQq+9Lx6WOy3K1YnQKbgVxwreBtYlw6//JnjVe3CkycTp+AvIO3Zfm EWqnnh3dEqDoHDeXXjBeWU+CQIu3Mz2YoB5qxaixTdOe4KqGwzc6nMF1l2rFeFX7Rp6e 9flAxqXsUKnwlu/RUoE/uFJCjejj8wUjmfqTog1iYZaFbcAT7gbsOBtMsaRmBYPlHw31 uHOq5xgukRc5lLk1RVtsHHkE8g0OSeu6HN+3yPk8B0u1pLaPWKqrKFwsaQ65Fpg52boR MmXjteCmygoH03GpvPY39Kb4NeX0uKwW3BtqFVoi+lynRfgTkm3ql09eNE8GAHiUntI3 MTbw== X-Forwarded-Encrypted: i=1; AJvYcCVmqqRsC/x/DyfYXy8JA/7xutoku09gjR737WU6T+Gcyq/dRFWFk53gn2k0TWKoeoc6X96Zyav95ztd@nongnu.org X-Gm-Message-State: AOJu0Yx3weGnLCstKMsrRUn7BCqFLYji2Pkf+LxDQxJ/r1zUGh2kkIbe dvQtF55aY4mw5ikQcraAxOFqOBf3XXxpCKX7TajFGS+sKGobXZXXu6U1MNYpNaM= X-Google-Smtp-Source: AGHT+IH/BSEqe5aKeYOZzd9yo/AGuOXcWgpygwDW/xhq7SsP0df/6CfnbK5wTDRUwKH/Z5G2Ne9htg== X-Received: by 2002:a05:600c:a04:b0:42c:b80e:5e50 with SMTP id 5b1f17b1804b1-431bb8a01dfmr199827505e9.0.1730757216637; Mon, 04 Nov 2024 13:53:36 -0800 (PST) Received: from rkanwal-XPS-15-9520.Home ([2a02:c7c:7527:ee00:8a3a:7719:aa26:21cb]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432a26a6da1sm1537595e9.0.2024.11.04.13.53.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Nov 2024 13:53:36 -0800 (PST) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Rajnesh Kanwal Cc: 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, beeman@rivosinc.com, tech-control-transfer-records@lists.riscv.org, jason.chien@sifive.com, frank.chang@sifive.com Subject: [PATCH v3 5/6] target/riscv: Add CTR sctrclr instruction. Date: Mon, 4 Nov 2024 21:51:09 +0000 Message-Id: <20241104-b4-ctr_upstream_v3-v3-5-32fd3c48205f@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> References: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> MIME-Version: 1.0 X-Mailer: b4 0.14.2 Received-SPF: pass client-ip=2a00:1450:4864:20::333; envelope-from=rkanwal@rivosinc.com; helo=mail-wm1-x333.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 CTR extension adds a new instruction sctrclr to quickly clear the recorded entries buffer. Signed-off-by: Rajnesh Kanwal --- target/riscv/cpu.h | 1 + target/riscv/cpu_helper.c | 7 +++++++ target/riscv/helper.h | 1 + target/riscv/insn32.decode | 1 + target/riscv/insn_trans/trans_privileged.c.inc | 11 ++++++++++ target/riscv/op_helper.c | 29 ++++++++++++++++++++++++++ 6 files changed, 50 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 189dba78970c414bff8aa252507c4585844bd846..21147e0d1d96e6dd6b15867bc5975772a9dd4858 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -614,6 +614,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en); void riscv_ctr_add_entry(CPURISCVState *env, target_long src, target_long dst, enum CTRType type, target_ulong prev_priv, bool prev_virt); +void riscv_ctr_clear(CPURISCVState *env); void riscv_translate_init(void); G_NORETURN void riscv_raise_exception(CPURISCVState *env, diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 06defc870cf85ed7c646ca6b066ce556bab1e757..9324a5da6ac6a4ebac0446f7c4b7090731fa1bec 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -703,6 +703,13 @@ static void riscv_ctr_freeze(CPURISCVState *env, uint64_t freeze_mask, } } +void riscv_ctr_clear(CPURISCVState *env) +{ + memset(env->ctr_src, 0x0, sizeof(env->ctr_src)); + memset(env->ctr_dst, 0x0, sizeof(env->ctr_dst)); + memset(env->ctr_data, 0x0, sizeof(env->ctr_data)); +} + static uint64_t riscv_ctr_priv_to_mask(target_ulong priv, bool virt) { switch (priv) { diff --git a/target/riscv/helper.h b/target/riscv/helper.h index b8fb7c87348d1f850628ab3769afda08158739be..a3b2d875276c3a0a4706716a8650d23cca0ff693 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -131,6 +131,7 @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl) #ifndef CONFIG_USER_ONLY DEF_HELPER_2(sret, tl, env, tl) DEF_HELPER_2(mret, tl, env, tl) +DEF_HELPER_1(ctr_clear, void, env) DEF_HELPER_1(wfi, void, env) DEF_HELPER_1(wrs_nto, void, env) DEF_HELPER_1(tlb_flush, void, env) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 66353a66786a1e2482dc248b7a4c480b17884808..728e1e272f4a0831313b7fcb76014e7efdd900ac 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -114,6 +114,7 @@ # *** Privileged Instructions *** ecall 000000000000 00000 000 00000 1110011 ebreak 000000000001 00000 000 00000 1110011 +sctrclr 000100000100 00000 000 00000 1110011 uret 0000000 00010 00000 000 00000 1110011 sret 0001000 00010 00000 000 00000 1110011 mret 0011000 00010 00000 000 00000 1110011 diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc index 339d65915173482507849ad36ff4eb3d1403c148..d16aa7139a24421ba7df94c5aab02103320343c9 100644 --- a/target/riscv/insn_trans/trans_privileged.c.inc +++ b/target/riscv/insn_trans/trans_privileged.c.inc @@ -69,6 +69,17 @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a) return true; } +static bool trans_sctrclr(DisasContext *ctx, arg_sctrclr *a) +{ +#ifndef CONFIG_USER_ONLY + if (ctx->cfg_ptr->ext_smctr || ctx->cfg_ptr->ext_ssctr) { + gen_helper_ctr_clear(tcg_env); + return true; + } +#endif + return false; +} + static bool trans_uret(DisasContext *ctx, arg_uret *a) { return false; diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 5a1e92c45ed108d038ad30f5c7031b05855ac110..9b70d423092e5798af1eb2883b8fab8b025cf023 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -475,6 +475,35 @@ void helper_ctr_branch(CPURISCVState *env, target_ulong src, target_ulong dest, } } +void helper_ctr_clear(CPURISCVState *env) +{ + /* + * It's safe to call smstateen_acc_ok() for umode access regardless of the + * state of bit 54 (CTR bit in case of m/hstateen) of sstateen. If the bit + * is zero, smstateen_acc_ok() will return the correct exception code and + * if it's one, smstateen_acc_ok() will return RISCV_EXCP_NONE. In that + * scenario the U-mode check below will handle that case. + */ + RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_CTR); + if (ret != RISCV_EXCP_NONE) { + riscv_raise_exception(env, ret, GETPC()); + } + + if (env->priv == PRV_U) { + /* + * One corner case is when sctrclr is executed from VU-mode and + * mstateen.CTR = 0, in which case we are supposed to raise + * RISCV_EXCP_ILLEGAL_INST. This case is already handled in + * smstateen_acc_ok(). + */ + uint32_t excep = env->virt_enabled ? RISCV_EXCP_VIRT_INSTRUCTION_FAULT : + RISCV_EXCP_ILLEGAL_INST; + riscv_raise_exception(env, excep, GETPC()); + } + + riscv_ctr_clear(env); +} + void helper_wfi(CPURISCVState *env) { CPUState *cs = env_cpu(env); From patchwork Mon Nov 4 21:51:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajnesh Kanwal X-Patchwork-Id: 13862147 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 BAAA2D1CA00 for ; Mon, 4 Nov 2024 21:55:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t8516-00081n-7e; Mon, 04 Nov 2024 16:53:44 -0500 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 1t8513-00080E-Li for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:41 -0500 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t8511-00012v-D8 for qemu-devel@nongnu.org; Mon, 04 Nov 2024 16:53:41 -0500 Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-37d51055097so3036406f8f.3 for ; Mon, 04 Nov 2024 13:53:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1730757218; x=1731362018; 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=SoJqCHBKHZ5pf1oJgAkZeA664i/MtGZFnSvDjiQjKW0=; b=YM3tOCADvv9tWsf5K1g6CXjTWLVAJ4H4mGuVTQ3Y/qdTecc76z6OcJ5rvDl1KNVumI DJ4PQ23UvNsRpJRvaoq+xDFGm6A7+TGOBaBPgC+XtUGwapTHUO3uDjbMz0GGillmoPLI jd9VuqsjOvVEy6pc+W2gxaQ/Zjojur0VfuTZaSxCiZqa8GUQEi0yZapxqDHjOpA47fhA 4uPtN/gshUPSJZLd1F+d2y7NoheijdejEbgSGhnhAJKhI1e/f+5iGZXU9M9G0J0E3CT/ xzt43TPqYwg4DCKQzjbUqXuy+PllMy6nEnDUx3IHBEBYhYk8mNZs7paGxZAmuej9SRq9 ymoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730757218; x=1731362018; 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=SoJqCHBKHZ5pf1oJgAkZeA664i/MtGZFnSvDjiQjKW0=; b=ID/eVSPRVsmZwpXtGLfQ50GVyZHAjdNzk+ULyXbWBplZdSP95yBSXx4W6xg8Isnof9 RhJ9o+Ue6HhU+CxXN3LDAVspLcdAoyN5x9EgEsbovksf+Wa1la6ysxJybiR1FabtcXF+ Zn9dAhmLZec2vLsSvs3VgiB9FxTO/loabGCyxmWICEMFnJcqiUQxrCVONLaFoSlkvTqF e29rkZ8JiVNIpcy1H+u2hPy91z8E5X16Aj7hLV4VSLNy8ZZsKRgMQq0TQjoEMNDFkebJ SmnCa0SefCnM7pyC9I3gruEnhiMkjaTXaySongwWHohU2nTbIzAbGEH/5yumgW5Vb3+O nMAQ== X-Forwarded-Encrypted: i=1; AJvYcCW02/2Cls/znbslJdpeQwFwh2mNesOR/KLsO5Z0KcL+eDzKjRNYs8GboGe/vyr0xXvm8nTBR7PE0Tkx@nongnu.org X-Gm-Message-State: AOJu0YypshJ8J8JNtovN6JvMHvIROY1/ee9Vu5nJKFteVFr67Wm64nV3 DM9XE8XLpVddmfYXXhxPBOuyTEKjIsHCdOZDsTCNQskKZaWqpGrZmMnf8xNxHKI= X-Google-Smtp-Source: AGHT+IEnL/8jnUmou+DZBPY7riS9uY55DwZZ9uaIomocK6wj6of45a6ul1/TjJkPcT0GLTMOx1i6wQ== X-Received: by 2002:a5d:64cc:0:b0:374:bd48:fae9 with SMTP id ffacd0b85a97d-381c7a4c99bmr10634870f8f.20.1730757217832; Mon, 04 Nov 2024 13:53:37 -0800 (PST) Received: from rkanwal-XPS-15-9520.Home ([2a02:c7c:7527:ee00:8a3a:7719:aa26:21cb]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432a26a6da1sm1537595e9.0.2024.11.04.13.53.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Nov 2024 13:53:37 -0800 (PST) From: Rajnesh Kanwal To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org, Rajnesh Kanwal Cc: 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, beeman@rivosinc.com, tech-control-transfer-records@lists.riscv.org, jason.chien@sifive.com, frank.chang@sifive.com Subject: [PATCH v3 6/6] target/riscv: Add support to access ctrsource, ctrtarget, ctrdata regs. Date: Mon, 4 Nov 2024 21:51:10 +0000 Message-Id: <20241104-b4-ctr_upstream_v3-v3-6-32fd3c48205f@rivosinc.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> References: <20241104-b4-ctr_upstream_v3-v3-0-32fd3c48205f@rivosinc.com> MIME-Version: 1.0 X-Mailer: b4 0.14.2 Received-SPF: pass client-ip=2a00:1450:4864:20::42a; envelope-from=rkanwal@rivosinc.com; helo=mail-wr1-x42a.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 CTR entries are accessed using ctrsource, ctrtarget and ctrdata registers using smcsrind/sscsrind extension. This commits extends the csrind extension to support CTR registers. ctrsource is accessible through xireg CSR, ctrtarget is accessible through xireg1 and ctrdata is accessible through xireg2 CSR. CTR supports maximum depth of 256 entries which are accessed using xiselect range 0x200 to 0x2ff. This commits also adds properties to enable CTR extension. CTR can be enabled using smctr=true and ssctr=true now. Signed-off-by: Rajnesh Kanwal --- target/riscv/cpu.c | 26 +++++++- target/riscv/csr.c | 150 ++++++++++++++++++++++++++++++++++++++++++++- target/riscv/tcg/tcg-cpu.c | 11 ++++ 3 files changed, 185 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index abebfcc46dea045ba5a97a68c66d39dc99276fcd..7be31ad507c078d48e2d8375eee52bfefed9f378 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -197,6 +197,8 @@ const RISCVIsaExtData isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12), ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12), ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade), + ISA_EXT_DATA_ENTRY(smctr, PRIV_VERSION_1_12_0, ext_smctr), + ISA_EXT_DATA_ENTRY(ssctr, PRIV_VERSION_1_12_0, ext_ssctr), ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu), ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval), ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot), @@ -1482,6 +1484,8 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { MULTI_EXT_CFG_BOOL("smcdeleg", ext_smcdeleg, false), MULTI_EXT_CFG_BOOL("sscsrind", ext_sscsrind, false), MULTI_EXT_CFG_BOOL("ssccfg", ext_ssccfg, false), + MULTI_EXT_CFG_BOOL("smctr", ext_smctr, false), + MULTI_EXT_CFG_BOOL("ssctr", ext_ssctr, false), MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true), MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true), MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true), @@ -2644,6 +2648,26 @@ static RISCVCPUImpliedExtsRule ZVKSG_IMPLIED = { }, }; +static RISCVCPUImpliedExtsRule SMCTR_IMPLIED = { + .ext = CPU_CFG_OFFSET(ext_smctr), + .implied_misa_exts = RVS, + .implied_multi_exts = { + CPU_CFG_OFFSET(ext_sscsrind), + + RISCV_IMPLIED_EXTS_RULE_END + }, +}; + +static RISCVCPUImpliedExtsRule SSCTR_IMPLIED = { + .ext = CPU_CFG_OFFSET(ext_ssctr), + .implied_misa_exts = RVS, + .implied_multi_exts = { + CPU_CFG_OFFSET(ext_sscsrind), + + RISCV_IMPLIED_EXTS_RULE_END + }, +}; + RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = { &RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED, &RVM_IMPLIED, &RVV_IMPLIED, NULL @@ -2662,7 +2686,7 @@ RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = { &ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED, &ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED, &ZVKS_IMPLIED, &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, - NULL + &SMCTR_IMPLIED, &SSCTR_IMPLIED, NULL }; static RISCVCPUPreferredExtsRule SSCCFG_PREFERRED = { diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 0805b8afc05bd8fcd75ed1c1ad669efbb180800d..eeb086e989662a889bcdd54744462ee73fcb151d 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -2363,6 +2363,13 @@ static bool xiselect_cd_range(target_ulong isel) return (ISELECT_CD_FIRST <= isel && isel <= ISELECT_CD_LAST); } +static bool xiselect_ctr_range(int csrno, target_ulong isel) +{ + /* MIREG-MIREG6 for the range 0x200-0x2ff are not used by CTR. */ + return CTR_ENTRIES_FIRST <= isel && isel <= CTR_ENTRIES_LAST && + csrno < CSR_MIREG; +} + static int rmw_iprio(target_ulong xlen, target_ulong iselect, uint8_t *iprio, target_ulong *val, target_ulong new_val, @@ -2408,6 +2415,124 @@ static int rmw_iprio(target_ulong xlen, return 0; } +static int rmw_ctrsource(CPURISCVState *env, int isel, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + /* + * CTR arrays are treated as circular buffers and TOS always points to next + * empty slot, keeping TOS - 1 always pointing to latest entry. Given entry + * 0 is always the latest one, traversal is a bit different here. See the + * below example. + * + * Depth = 16. + * + * idx [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F] + * TOS H + * entry 6 5 4 3 2 1 0 F E D C B A 9 8 7 + */ + const uint64_t entry = isel - CTR_ENTRIES_FIRST; + const uint64_t depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK); + uint64_t idx; + + /* Entry greater than depth-1 is read-only zero */ + if (entry >= depth) { + if (val) { + *val = 0; + } + return 0; + } + + idx = get_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK); + idx = (idx - entry - 1) & (depth - 1); + + if (val) { + *val = env->ctr_src[idx]; + } + + env->ctr_src[idx] = (env->ctr_src[idx] & ~wr_mask) | (new_val & wr_mask); + + return 0; +} + +static int rmw_ctrtarget(CPURISCVState *env, int isel, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + /* + * CTR arrays are treated as circular buffers and TOS always points to next + * empty slot, keeping TOS - 1 always pointing to latest entry. Given entry + * 0 is always the latest one, traversal is a bit different here. See the + * below example. + * + * Depth = 16. + * + * idx [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F] + * head H + * entry 6 5 4 3 2 1 0 F E D C B A 9 8 7 + */ + const uint64_t entry = isel - CTR_ENTRIES_FIRST; + const uint64_t depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK); + uint64_t idx; + + /* Entry greater than depth-1 is read-only zero */ + if (entry >= depth) { + if (val) { + *val = 0; + } + return 0; + } + + idx = get_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK); + idx = (idx - entry - 1) & (depth - 1); + + if (val) { + *val = env->ctr_dst[idx]; + } + + env->ctr_dst[idx] = (env->ctr_dst[idx] & ~wr_mask) | (new_val & wr_mask); + + return 0; +} + +static int rmw_ctrdata(CPURISCVState *env, int isel, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + /* + * CTR arrays are treated as circular buffers and TOS always points to next + * empty slot, keeping TOS - 1 always pointing to latest entry. Given entry + * 0 is always the latest one, traversal is a bit different here. See the + * below example. + * + * Depth = 16. + * + * idx [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [A] [B] [C] [D] [E] [F] + * head H + * entry 6 5 4 3 2 1 0 F E D C B A 9 8 7 + */ + const uint64_t entry = isel - CTR_ENTRIES_FIRST; + const uint64_t mask = wr_mask & CTRDATA_MASK; + const uint64_t depth = 16 << get_field(env->sctrdepth, SCTRDEPTH_MASK); + uint64_t idx; + + /* Entry greater than depth-1 is read-only zero */ + if (entry >= depth) { + if (val) { + *val = 0; + } + return 0; + } + + idx = get_field(env->sctrstatus, SCTRSTATUS_WRPTR_MASK); + idx = (idx - entry - 1) & (depth - 1); + + if (val) { + *val = env->ctr_data[idx]; + } + + env->ctr_data[idx] = (env->ctr_data[idx] & ~mask) | (new_val & mask); + + return 0; +} + static RISCVException rmw_xireg_aia(CPURISCVState *env, int csrno, target_ulong isel, target_ulong *val, target_ulong new_val, target_ulong wr_mask) @@ -2558,6 +2683,27 @@ done: return ret; } +static int rmw_xireg_ctr(CPURISCVState *env, int csrno, + target_ulong isel, target_ulong *val, + target_ulong new_val, target_ulong wr_mask) +{ + if (!riscv_cpu_cfg(env)->ext_smctr && !riscv_cpu_cfg(env)->ext_ssctr) { + return -EINVAL; + } + + if (csrno == CSR_SIREG || csrno == CSR_VSIREG) { + return rmw_ctrsource(env, isel, val, new_val, wr_mask); + } else if (csrno == CSR_SIREG2 || csrno == CSR_VSIREG2) { + return rmw_ctrtarget(env, isel, val, new_val, wr_mask); + } else if (csrno == CSR_SIREG3 || csrno == CSR_VSIREG3) { + return rmw_ctrdata(env, isel, val, new_val, wr_mask); + } else if (val) { + *val = 0; + } + + return 0; +} + /* * rmw_xireg_csrind: Perform indirect access to xireg and xireg2-xireg6 * @@ -2569,11 +2715,13 @@ static int rmw_xireg_csrind(CPURISCVState *env, int csrno, target_ulong isel, target_ulong *val, target_ulong new_val, target_ulong wr_mask) { - int ret = -EINVAL; bool virt = csrno == CSR_VSIREG ? true : false; + int ret = -EINVAL; if (xiselect_cd_range(isel)) { ret = rmw_xireg_cd(env, csrno, isel, val, new_val, wr_mask); + } else if (xiselect_ctr_range(csrno, isel)) { + ret = rmw_xireg_ctr(env, csrno, isel, val, new_val, wr_mask); } else { /* * As per the specification, access to unimplented region is undefined diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c index d8f74720815addd455ee8883f33dd7095b6b9cd2..8c1520f2aaab738ce109e783a8f7120f405a3df5 100644 --- a/target/riscv/tcg/tcg-cpu.c +++ b/target/riscv/tcg/tcg-cpu.c @@ -624,6 +624,17 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) cpu->pmu_avail_ctrs = 0; } + if ((cpu->cfg.ext_smctr || cpu->cfg.ext_ssctr) && + (!riscv_has_ext(env, RVS) || !cpu->cfg.ext_sscsrind)) { + if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_smctr)) || + cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_ssctr))) { + error_setg(errp, "Smctr and Ssctr require S-mode and Sscsrind"); + return; + } + cpu->cfg.ext_smctr = false; + cpu->cfg.ext_ssctr = false; + } + /* * Disable isa extensions based on priv spec after we * validated and set everything we need.