From patchwork Thu Oct 19 11:37:09 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: 1851600 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=d5JOis5W; 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 4SB5QR2YFMz20Zj for ; Thu, 19 Oct 2023 22:41:19 +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=ZTtgiqBIXmfdQNF1DBdgl3/zqL3yLG5KT4hcWTIXL84=; b=d5JOis5W0VQmRP z6jyXK48Mx9D2YbEV++cZTDItgGVEfRXHmFCNsrXjGDtf5Uw+fpJtL75uG+Hmugj299lgbw6weNJ5 Rjut9Fzlvl+gYDQh1pbvMLKj0f2EoKAzuTkLtl5iikDmsmccPUrAAxVfv9QkJcjv9Zz9yiFETZjtc VB/cF2q7AOYcbcFSOgL2LvmTFZhRAMw1Uehcs0tkC3PrNeOTCgtf6W8ttmgiwlwlIQY5AmNBe/9BL 6p6E2J0mmbOvlPvmFxAIbUDQ8UGiGNdK3/NcyKvAiPGkZy7gz29OBnzvbc1hBRwqaRm1hXuVXQ/dw Cw0XBg4pnaq+U0yAjmPQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qtROn-00HC9p-0c; Thu, 19 Oct 2023 11:41:09 +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 1qtROj-00HC5Q-0W for opensbi@lists.infradead.org; Thu, 19 Oct 2023 11:41:07 +0000 Received: from mail.andestech.com (ATCPCS16.andestech.com [10.0.1.222]) by Atcsqr.andestech.com with ESMTP id 39JBepim049631; Thu, 19 Oct 2023 19:40:51 +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, 19 Oct 2023 19:40:47 +0800 From: Yu Chien Peter Lin To: CC: , , , , , , , , Yu Chien Peter Lin Subject: [PATCH v2 07/11] lib: utils: fdt_fixup: Add fdt_add_pmu_mappings() helper function Date: Thu, 19 Oct 2023 19:37:09 +0800 Message-ID: <20231019113713.3508153-8-peterlin@andestech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231019113713.3508153-1-peterlin@andestech.com> References: <20231019113713.3508153-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 39JBepim049631 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231019_044105_640240_9A0264CA X-CRM114-Status: GOOD ( 17.47 ) 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: Add fdt_add_pmu_mappings() that creates entries of riscv,*event-to-mhpm* property from arrays right before fdt_pmu_setup() populating the mapping tables (i.e. hw_event_map[] and fdt_pmu_evt_select[]). 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 Add fdt_add_pmu_mappings() that creates entries of riscv,*event-to-mhpm* property from arrays right before fdt_pmu_setup() populating the mapping tables (i.e. hw_event_map[] and fdt_pmu_evt_select[]). The helper function will skip the creation of those properties if a "/pmu" node with "riscv,pmu" compatible string is provided. Signed-off-by: Yu Chien Peter Lin --- Changes v1 -> v2: - New patch --- include/sbi_utils/fdt/fdt_fixup.h | 48 ++++++++++ lib/utils/fdt/fdt_fixup.c | 95 ++++++++++++++++++++ platform/generic/include/platform_override.h | 1 + platform/generic/platform.c | 10 ++- 4 files changed, 153 insertions(+), 1 deletion(-) diff --git a/include/sbi_utils/fdt/fdt_fixup.h b/include/sbi_utils/fdt/fdt_fixup.h index ecd55a7..9b72df8 100644 --- a/include/sbi_utils/fdt/fdt_fixup.h +++ b/include/sbi_utils/fdt/fdt_fixup.h @@ -19,6 +19,54 @@ struct sbi_cpu_idle_state { uint32_t wakeup_latency_us; }; +struct sbi_pmu_event_select_map { + /** + * The description of an entry in + * riscv,event-to-mhpmevent property + */ + uint32_t eidx; + uint64_t select; +}; + +struct sbi_pmu_event_counter_map { + /** + * The description of an entry in + * riscv,event-to-mhpmcounters property + */ + uint32_t eidx_start; + uint32_t eidx_end; + uint32_t ctr_map; +}; + +struct sbi_pmu_raw_event_counter_map { + /** + * The description of an entry in + * riscv,raw-event-to-mhpmcounters property + */ + uint64_t select; + uint64_t select_mask; + uint32_t ctr_map; +}; + +/** + * Add PMU properties in the DT + * + * Add information about event to selector/counter mappings to the + * devicetree. + * + * @param fdt: device tree blob + * @param selects: array of event index to selector value mapping + * descriptions, ending with empty element + * @param counters: array of event indexes to counters mapping + * descriptions, ending with empty element + * @param rcounters: array of raw events to counters mapping + * descriptions, ending with empty element + * @return zero on success and -ve on failure + */ +int fdt_add_pmu_mappings(void *fdt, const struct sbi_pmu_event_select_map *selects, + const struct sbi_pmu_event_counter_map *counters, + const struct sbi_pmu_raw_event_counter_map *rcounters); + /** * Add CPU idle states to cpu nodes in the DT * diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c index e213ded..67e2e2e 100644 --- a/lib/utils/fdt/fdt_fixup.c +++ b/lib/utils/fdt/fdt_fixup.c @@ -20,6 +20,101 @@ #include #include +int fdt_add_pmu_mappings(void *fdt, const struct sbi_pmu_event_select_map *selects, + const struct sbi_pmu_event_counter_map *counters, + const struct sbi_pmu_raw_event_counter_map *rcounters) +{ + int i, err, pmu_noff, root_noff; + const char *comp; + fdt32_t evt_to_mhpmevent[3]; + fdt32_t evt_to_mhpmcounters[3]; + fdt32_t raw_evt_to_mhpmcounters[5]; + + /* Try to locate pmu node */ + pmu_noff = fdt_path_offset(fdt, "/pmu"); + + if (pmu_noff > 0) { + /* + * If compatible string is "riscv,pmu", + * we assume a valid pmu node has been + * provided. + */ + comp = fdt_getprop(fdt, pmu_noff, "compatible", NULL); + if (comp && !strcmp(comp, "riscv,pmu")) + return 0; + else + return -FDT_ERR_BADVALUE; + } + + if (pmu_noff < 0 && pmu_noff != -FDT_ERR_NOTFOUND) + return pmu_noff; + + /* + * If "riscv,event-to-mhpmevent" is present, "riscv,event-to-mhpmcounters" + * must be provided as well, but not vice versa (OpenSBI will direct mapping + * event_idx as selector value). + */ + if (selects && !counters) { + sbi_printf("%s: ERR: riscv,event-to-mhpmcounters is mandatory if" + " riscv,event-to-mhpmevent is present.", __func__); + return SBI_EINVAL; + } + + /* + * Create pmu node based on given @selects, @counters + * and @rcounters. + */ + root_noff = fdt_path_offset(fdt, "/"); + pmu_noff = fdt_add_subnode(fdt, root_noff, "pmu"); + if (pmu_noff < 0) + return pmu_noff; + + err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 1024); + if (err < 0) + return err; + + err = fdt_setprop_string(fdt, pmu_noff, "compatible", "riscv,pmu"); + if (err) + return err; + + /* Add riscv,event-to-mhpmevent */ + for (i = 0; selects && selects[i].eidx; i++) { + evt_to_mhpmevent[0] = cpu_to_fdt32(selects[i].eidx); + evt_to_mhpmevent[1] = cpu_to_fdt32(selects[i].select >> 32); + evt_to_mhpmevent[2] = cpu_to_fdt32(selects[i].select & ~0UL); + err = fdt_appendprop(fdt, pmu_noff, "riscv,event-to-mhpmevent", + evt_to_mhpmevent, 3 * sizeof(fdt32_t)); + if (err) + return err; + } + + /* Add riscv,event-to-mhpmcounters */ + for (i = 0; counters && counters[i].eidx_start; i++) { + evt_to_mhpmcounters[0] = cpu_to_fdt32(counters[i].eidx_start); + evt_to_mhpmcounters[1] = cpu_to_fdt32(counters[i].eidx_end); + evt_to_mhpmcounters[2] = cpu_to_fdt32(counters[i].ctr_map); + err = fdt_appendprop(fdt, pmu_noff, "riscv,event-to-mhpmcounters", + evt_to_mhpmcounters, 3 * sizeof(fdt32_t)); + if (err) + return err; + } + + /* Add riscv,raw-event-to-mhpmcounters */ + for (i = 0; rcounters && rcounters[i].select; i++) { + raw_evt_to_mhpmcounters[0] = cpu_to_fdt32(rcounters[i].select >> 32); + raw_evt_to_mhpmcounters[1] = cpu_to_fdt32(rcounters[i].select & ~0UL); + raw_evt_to_mhpmcounters[2] = cpu_to_fdt32(rcounters[i].select_mask >> 32); + raw_evt_to_mhpmcounters[3] = cpu_to_fdt32(rcounters[i].select_mask & ~0UL); + raw_evt_to_mhpmcounters[4] = cpu_to_fdt32(rcounters[i].ctr_map); + err = fdt_appendprop(fdt, pmu_noff, "riscv,raw-event-to-mhpmcounters", + raw_evt_to_mhpmcounters, 5 * sizeof(fdt32_t)); + if (err) + return err; + } + + return 0; +} + int fdt_add_cpu_idle_states(void *fdt, const struct sbi_cpu_idle_state *state) { int cpu_node, cpus_node, err, idle_states_node; diff --git a/platform/generic/include/platform_override.h b/platform/generic/include/platform_override.h index bf4b112..bd34d2a 100644 --- a/platform/generic/include/platform_override.h +++ b/platform/generic/include/platform_override.h @@ -19,6 +19,7 @@ struct platform_override { u64 (*features)(const struct fdt_match *match); u64 (*tlbr_flush_limit)(const struct fdt_match *match); u32 (*tlb_num_entries)(const struct fdt_match *match); + int (*fdt_add_pmu_mappings)(void *fdt, const struct fdt_match *match); bool (*cold_boot_allowed)(u32 hartid, const struct fdt_match *match); int (*early_init)(bool cold_boot, const struct fdt_match *match); int (*final_init)(bool cold_boot, const struct fdt_match *match); diff --git a/platform/generic/platform.c b/platform/generic/platform.c index cb9270d..a48a8b7 100644 --- a/platform/generic/platform.c +++ b/platform/generic/platform.c @@ -265,9 +265,17 @@ static u32 generic_tlb_num_entries(void) static int generic_pmu_init(void) { + void *fdt = fdt_get_address(); int rc; - rc = fdt_pmu_setup(fdt_get_address()); + if (generic_plat && generic_plat->fdt_add_pmu_mappings) { + rc = generic_plat->fdt_add_pmu_mappings(fdt, + generic_plat_match); + if (rc) + return rc; + } + + rc = fdt_pmu_setup(fdt); if (rc && rc != SBI_ENOENT) return rc;