From patchwork Thu Nov 30 12:42:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yu-Chien Peter Lin X-Patchwork-Id: 1870113 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=u+Y8JdIe; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Sgwpx6MnXz1ySd for ; Thu, 30 Nov 2023 23:43:37 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Ww/FikBnjDO7tjgzy3mMLzm6KC0vxMe6cEFXWa3sBaQ=; b=u+Y8JdIeeCyFNN 2SU1J88AAm/pGVG05CB7ULuwNv8ecWnMOEyL0f0FSv0k1dDUlzpeayWXaTHxNFGTv2Kvme8FgMPII gFWekqA70xxXg0JZQA6h3EuxY4o86n4DbWHwa5itTruNjGiArO02TOeCl1Hf8DdWk7I28b94IFjNH Z0swMDyT/bRKUMvez6NjT8gcQ8+5v2Yo/tmW+7A+l9nr337qBmdZ7D7CD2+htzSG/56MosRnrktOR NoqB50YvFrerPU+DPnYAAseeOdwo3weGjqLqm/65yTdX7MhWL9HvXTSj2CZQrGEkAuY+ro1VSw4Af OQplNlvtg810mElR2RNg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1r8gO6-00AtSX-0J; Thu, 30 Nov 2023 12:43:26 +0000 Received: from 60-248-80-70.hinet-ip.hinet.net ([60.248.80.70] helo=Atcsqr.andestech.com) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1r8gO2-00AtQY-2o for opensbi@lists.infradead.org; Thu, 30 Nov 2023 12:43:24 +0000 Received: from mail.andestech.com (ATCPCS16.andestech.com [10.0.1.222]) by Atcsqr.andestech.com with ESMTP id 3AUCgxVw056076; Thu, 30 Nov 2023 20:42:59 +0800 (+08) (envelope-from peterlin@andestech.com) Received: from swlinux02.andestech.com (10.0.15.183) by ATCPCS16.andestech.com (10.0.1.222) with Microsoft SMTP Server id 14.3.498.0; Thu, 30 Nov 2023 20:42:54 +0800 From: Yu Chien Peter Lin To: CC: , , , , , , , , , Yu Chien Peter Lin Subject: [PATCH v4 07/15] platform: andes: Add Andes custom PMU support Date: Thu, 30 Nov 2023 20:42:05 +0800 Message-ID: <20231130124213.2590640-8-peterlin@andestech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231130124213.2590640-1-peterlin@andestech.com> References: <20231130124213.2590640-1-peterlin@andestech.com> MIME-Version: 1.0 X-Originating-IP: [10.0.15.183] X-DNSRBL: X-SPAM-SOURCE-CHECK: pass X-MAIL: Atcsqr.andestech.com 3AUCgxVw056076 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231130_044323_372116_0D1DE744 X-CRM114-Status: GOOD ( 22.52 ) X-Spam-Score: 0.4 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Before the ratification of Sscofpmf, the Andes PMU extension was designed to support the sampling and filtering with hardware performance counters (zihpm), it works with the current SBI PMU extension [...] Content analysis details: (0.4 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 TVD_RCVD_IP Message was received from an IP address -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.4 RDNS_DYNAMIC Delivered to internal network by host with dynamic-looking rDNS X-BeenThere: opensbi@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "opensbi" Errors-To: opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Before the ratification of Sscofpmf, the Andes PMU extension was designed to support the sampling and filtering with hardware performance counters (zihpm), it works with the current SBI PMU extension and Linux SBI PMU driver. We implement 1) the PMU device callbacks that update the corresponding bits on custom CSRs, 2) extentions_init() to detect the hardware support of Andes PMU and initialize the per-hart PMU related CSR, and 3) pmu_init() to register PMU device and populate event mappings. Also define a andes_pmu_setup() function which is in preparation for adding default PMU mappings in andes_hpm.h Signed-off-by: Yu Chien Peter Lin Reviewed-by: Leo Yu-Chi Liang Reviewed-by: Anup Patel --- Changes v1 -> v2: - Fix mode filtering in andes_hw_counter_filter_mode() - Return early if pmu is not supported in andes_pmu_init() (suggested by Prabhakar) - Don't grant write permissions via CSR_MCOUNTERWEN as not needed Changes v2 -> v3: - Drop Anup's RB tag as we add andes_pmu_extensions_init() to initialize per-hart extension on scratch and move andes_pmu_init() to new added platform override pmu_init() Changes v3 -> v4: (suggested by Samuel) - Add andes_hpm.h as an placeholder for andes_pmu_setup() to avoid compile failure - Do not call fdt_pmu_setup() in andes_pmu_init() as it will be done in generic_pmu_init() --- platform/generic/andes/Kconfig | 8 ++ platform/generic/andes/andes_pmu.c | 105 +++++++++++++++++++++ platform/generic/andes/objects.mk | 1 + platform/generic/include/andes/andes_hpm.h | 12 +++ platform/generic/include/andes/andes_pmu.h | 34 +++++++ 5 files changed, 160 insertions(+) create mode 100644 platform/generic/andes/andes_pmu.c create mode 100644 platform/generic/include/andes/andes_hpm.h create mode 100644 platform/generic/include/andes/andes_pmu.h diff --git a/platform/generic/andes/Kconfig b/platform/generic/andes/Kconfig index a91fb9c..3665b33 100644 --- a/platform/generic/andes/Kconfig +++ b/platform/generic/andes/Kconfig @@ -7,3 +7,11 @@ config ANDES45_PMA config ANDES_SBI bool "Andes SBI support" default n + +config ANDES_PMU + bool "Andes PMU extension (XAndesPMU) support" + default n + help + Andes PMU extension supports the event counter overflow + interrupt and mode filtering, similar to the standard + Sscofpmf and Smcntrpmf. diff --git a/platform/generic/andes/andes_pmu.c b/platform/generic/andes/andes_pmu.c new file mode 100644 index 0000000..4b2d45b --- /dev/null +++ b/platform/generic/andes/andes_pmu.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * andes_pmu.c - Andes PMU device callbacks and platform overrides + * + * Copyright (C) 2023 Andes Technology Corporation + */ + +#include +#include +#include +#include +#include +#include +#include + +static void andes_hw_counter_enable_irq(uint32_t ctr_idx) +{ + unsigned long mip_val; + + if (ctr_idx >= SBI_PMU_HW_CTR_MAX) + return; + + mip_val = csr_read(CSR_MIP); + if (!(mip_val & MIP_PMOVI)) + csr_clear(CSR_MCOUNTEROVF, BIT(ctr_idx)); + + csr_set(CSR_MCOUNTERINTEN, BIT(ctr_idx)); +} + +static void andes_hw_counter_disable_irq(uint32_t ctr_idx) +{ + csr_clear(CSR_MCOUNTERINTEN, BIT(ctr_idx)); +} + +static void andes_hw_counter_filter_mode(unsigned long flags, int ctr_idx) +{ + if (flags & SBI_PMU_CFG_FLAG_SET_UINH) + csr_set(CSR_MCOUNTERMASK_U, BIT(ctr_idx)); + else + csr_clear(CSR_MCOUNTERMASK_U, BIT(ctr_idx)); + + if (flags & SBI_PMU_CFG_FLAG_SET_SINH) + csr_set(CSR_MCOUNTERMASK_S, BIT(ctr_idx)); + else + csr_clear(CSR_MCOUNTERMASK_S, BIT(ctr_idx)); +} + +static struct sbi_pmu_device andes_pmu = { + .name = "andes_pmu", + .hw_counter_enable_irq = andes_hw_counter_enable_irq, + .hw_counter_disable_irq = andes_hw_counter_disable_irq, + /* + * We set delegation of supervisor local interrupts via + * 18th bit on mslideleg instead of mideleg, so leave + * hw_counter_irq_bit() callback unimplemented. + */ + .hw_counter_irq_bit = NULL, + .hw_counter_filter_mode = andes_hw_counter_filter_mode +}; + +int andes_pmu_extensions_init(const struct fdt_match *match, + struct sbi_hart_features *hfeatures) +{ + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + + if (!has_andes_pmu()) + return 0; + + /* + * Don't expect both Andes PMU and standard Sscofpmf/Smcntrpmf, + * are supported as they serve the same purpose. + */ + if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCOFPMF) || + sbi_hart_has_extension(scratch, SBI_HART_EXT_SMCNTRPMF)) + return SBI_EINVAL; + sbi_hart_update_extension(scratch, SBI_HART_EXT_XANDESPMU, true); + + /* Inhibit all HPM counters in M-mode */ + csr_write(CSR_MCOUNTERMASK_M, 0xfffffffd); + /* Delegate counter overflow interrupt to S-mode */ + csr_write(CSR_MSLIDELEG, MIP_PMOVI); + + return 0; +} + +int andes_pmu_init(const struct fdt_match *match) +{ + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + void *fdt = fdt_get_address(); + int pmu_offset; + + if (sbi_hart_has_extension(scratch, SBI_HART_EXT_XANDESPMU)) + sbi_pmu_set_device(&andes_pmu); + + /* + * Populate default mappings if device-tree doesn't + * provide a valid pmu node. + */ + pmu_offset = fdt_node_offset_by_compatible(fdt, -1, "riscv,pmu"); + if (pmu_offset < 0) + return (pmu_offset == -FDT_ERR_NOTFOUND) ? andes_pmu_setup() + : SBI_EFAIL; + + return 0; +} diff --git a/platform/generic/andes/objects.mk b/platform/generic/andes/objects.mk index e8f86ea..6a8c66c 100644 --- a/platform/generic/andes/objects.mk +++ b/platform/generic/andes/objects.mk @@ -7,3 +7,4 @@ platform-objs-$(CONFIG_PLATFORM_ANDES_AE350) += andes/ae350.o andes/sleep.o platform-objs-$(CONFIG_ANDES45_PMA) += andes/andes45-pma.o platform-objs-$(CONFIG_ANDES_SBI) += andes/andes_sbi.o +platform-objs-$(CONFIG_ANDES_PMU) += andes/andes_pmu.o diff --git a/platform/generic/include/andes/andes_hpm.h b/platform/generic/include/andes/andes_hpm.h new file mode 100644 index 0000000..b4d71b9 --- /dev/null +++ b/platform/generic/include/andes/andes_hpm.h @@ -0,0 +1,12 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Andes Technology Corporation + */ + +#ifndef _ANDES_HPM_H_ +#define _ANDES_HPM_H_ + +static inline int andes_pmu_setup(void) { return 0; } + +#endif /* _ANDES_HPM_H_ */ diff --git a/platform/generic/include/andes/andes_pmu.h b/platform/generic/include/andes/andes_pmu.h new file mode 100644 index 0000000..f355324 --- /dev/null +++ b/platform/generic/include/andes/andes_pmu.h @@ -0,0 +1,34 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) Copyright (c) 2023 Andes Technology Corporation + */ + +#ifndef _RISCV_ANDES_PMU_H +#define _RISCV_ANDES_PMU_H + +#include +#include +#include + +#ifdef CONFIG_ANDES_PMU + +int andes_pmu_init(const struct fdt_match *match); +int andes_pmu_extensions_init(const struct fdt_match *match, + struct sbi_hart_features *hfeatures); + +#else + +static inline int andes_pmu_init(const struct fdt_match *match) +{ + return 0; +} +static inline int andes_pmu_extensions_init(const struct fdt_match *match, + struct sbi_hart_features *hfeatures) +{ + return 0; +} + +#endif /* CONFIG_ANDES_PMU */ + +#endif /* _RISCV_ANDES_PMU_H */