From patchwork Thu Sep 9 20:40:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 1526312 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: 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=J2qZhlNn; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=wdc.com header.i=@wdc.com header.a=rsa-sha256 header.s=dkim.wdc.com header.b=WJnJv/tP; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4H59rS5g9mz9t0Y for ; Fri, 10 Sep 2021 06:40:56 +1000 (AEST) 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=OjAG2qL8CQ+4ayEaRhORCm5mQsCGOUi8JD4pEnCVmKo=; b=J2qZhlNnIemPV6 1wdf2s/CmhOXfMshuh+zTeVrY+7kLeHYP5+PL+rnfJ6NEA7etPwaTC7LalB8F5Hkhl95QZvugNGhN 7ncS4eFmBOrQ/NWrBCP7XLz/8o9h+SCcS5PJ9PZDY8Xo3hjILQ2VrxerDbAplYC3fVCAYZE5NJ/tt JllmRHc0/fpicl7eb+crZZ/15Kvk4s5yO4R+qSgdCf6XNg4x+OPxRVXb6IfxC46BSb8efZK34RkOr 05fNCTYmF7RWv+lQAlwf8LqaMeDRbp6rmV145EK3S95rSkfvVP+6WS0ffR2TwO1S5O9bTDcx2enME tgnmAFOEM6QyilgeD6Yw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mOQqp-00AqGe-7G; Thu, 09 Sep 2021 20:40:51 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mOQqk-00AqBv-5w for opensbi@lists.infradead.org; Thu, 09 Sep 2021 20:40:47 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1631220046; x=1662756046; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dy1T2fu3FLhlICYuJdVgwZ3vsZRzTGhAvqibv7M8prg=; b=WJnJv/tPWHPG7t9YpsHabsIxmpMUgV7sSEFkB4ijjsqE538THrqWs+k0 DjBsXKCc/BWwc4BN8+Qk0xETKVQLzJkX4if9Q+sgnXq13HrGq/64+gB67 ghuPiDLsk2Ejl+JHk7gvLat/GF11jUkueP8Sq1fxOCZ1dIBuZCJf/SUID UGf1p3iad+Jt6bScqYvU3lfqdT7vwzAwgNvtv8DI5Q9Tr1rxQlL6em9wa kScS9X48bBA442GIfydgp5PJjUlUVTtEVs4Ayk3wx5OSnCPdUwHgSmHxW gZgjh30t1A7nY7qpOJDXN1tFmDz33DGovuHPQbC8p0Gtbaytzbm5zvu3R Q==; X-IronPort-AV: E=Sophos;i="5.85,281,1624291200"; d="scan'208";a="291234516" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 10 Sep 2021 04:40:42 +0800 IronPort-SDR: T0mR18BPuo3D94bxCsntjaFdWh9n6kg9vAuQd+0HxxxbB52yiR4rj1Vv0GJrEOgMMAuijjnrLK a8olii0RjU2VDEhK+VMTjTCFVbN3yGUVuUkaHBAHmsgSF9bnPMZuyJc0Qxo8YUJWifk5Actuku eXH6LnTSuTB+Lx942AVaeSpr5p0NtN2AuxeaxyU0alC8AsGzC0g9m5dIWri2TSLMLABaCAnl8i fWsBvRSgruu0FuMe5RZhDZOKAH1fo0OhBOMvvXRrFGk4nv0ZrVWWd9gp/CkPNYyp5VBnCzmZ5T N81lwTsKLX2z7z51Z5Kc8xQI Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Sep 2021 13:15:37 -0700 IronPort-SDR: 9YJfYDERWIRn+ZqQH3L/0IQFWNLHRL8T8Q9S6xO3ZTFtkc+h9j1rEZuIo/JNMTCkQNiPVPYwKE sanyr5VCoalHXq7rywG2SGPzIHllZt2U4bVR9n1BgG/04WWwNXNe0JbwFYUjrsPO1SsUAhS7ey b+JFKBkTqdXMDwACubn7kGRU+3Jw7lTWUiYJZRPtUkYyLRz4L+laSL9DTW48ac0IWlvASU3mdg WdoyubxOtrPxhFBPc8pvTj1SPehBMXUKXtByEfAHIXc+EKAcccwnGGZvWJBsvQsKcGUch+1AzE 0ys= WDCIronportException: Internal Received: from unknown (HELO hulk.wdc.com) ([10.225.167.73]) by uls-op-cesaip02.wdc.com with ESMTP; 09 Sep 2021 13:40:42 -0700 From: Atish Patra To: opensbi@lists.infradead.org Cc: Atish Patra , anup.patel@wdc.com Subject: [RFC PATCH 5/9] lib:sbi: Support sscof extension in OpenSBI Date: Thu, 9 Sep 2021 13:40:27 -0700 Message-Id: <20210909204031.1239254-6-atish.patra@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210909204031.1239254-1-atish.patra@wdc.com> References: <20210909204031.1239254-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210909_134046_285749_0F44264D X-CRM114-Status: GOOD ( 22.09 ) X-Spam-Score: -2.5 (--) 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: This patch adds sscof extension in pmu module which includes following things. 1. Enable overflow irq when starting a counter. 2. Setting the correct event filters passed from supervisor. 3. Delegating the overflow interrupt to the supervisor. 4. Add RV32 support for sscof. Content analysis details: (-2.5 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] 0.0 SPF_NONE SPF: sender does not publish an SPF Record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 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 This patch adds sscof extension in pmu module which includes following things. 1. Enable overflow irq when starting a counter. 2. Setting the correct event filters passed from supervisor. 3. Delegating the overflow interrupt to the supervisor. 4. Add RV32 support for sscof. Signed-off-by: Atish Patra --- include/sbi/riscv_encoding.h | 19 ++++++++ lib/sbi/sbi_pmu.c | 85 ++++++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 14 deletions(-) diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h index c2cf0f4d69f4..f71412eae563 100644 --- a/include/sbi/riscv_encoding.h +++ b/include/sbi/riscv_encoding.h @@ -173,6 +173,25 @@ #define HGATP_MODE_SHIFT HGATP32_MODE_SHIFT #endif +#if __riscv_xlen == 64 +#define MHPMEVENT_OF (_UL(1) << 63) +#define MHPMEVENT_MINH (_UL(1) << 62) +#define MHPMEVENT_SINH (_UL(1) << 61) +#define MHPMEVENT_UINH (_UL(1) << 60) +#define MHPMEVENT_VSINH (_UL(1) << 59) +#define MHPMEVENT_VUINH (_UL(1) << 58) +#else +#define MHPMEVENT_OF (_ULL(1) << 63) +#define MHPMEVENT_MINH (_ULL(1) << 62) +#define MHPMEVENT_SINH (_ULL(1) << 61) +#define MHPMEVENT_UINH (_ULL(1) << 60) +#define MHPMEVENT_VSINH (_ULL(1) << 59) +#define MHPMEVENT_VUINH (_ULL(1) << 58) + +#define MHPMEVENTH_OF (_UL(1) << 31) +#endif + +#define MHPMEVENT_SSCOF_MASK _ULL(0xFFFF000000000000) /* ===== User-level CSRs ===== */ /* User Trap Setup (N-extension) */ diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c index c276a46e2876..bbbd033b4cfe 100644 --- a/lib/sbi/sbi_pmu.c +++ b/lib/sbi/sbi_pmu.c @@ -226,11 +226,47 @@ int sbi_pmu_add_raw_event_counter_map(uint64_t select, u32 cmap) SBI_PMU_EVENT_RAW_IDX, cmap, select); } +static int pmu_ctr_enable_irq_hw(int ctr_idx) +{ + unsigned long mhpmevent_csr; + unsigned long mhpmevent_curr; + unsigned long mip_val; + unsigned long of_mask; + + if (ctr_idx < 3 || ctr_idx >= SBI_PMU_HW_CTR_MAX) + return SBI_EFAIL; + +#if __riscv_xlen == 32 + mhpmevent_csr = CSR_MHPMEVENT3H + ctr_idx - 3; + of_mask = ~MHPMEVENTH_OF; +#else + mhpmevent_csr = CSR_MCOUNTINHIBIT + ctr_idx; + of_mask = ~MHPMEVENT_OF; +#endif + + mhpmevent_curr = csr_read_num(mhpmevent_csr); + mip_val = csr_read(CSR_MIP); + /** + * Clear out the OF bit so that next interrupt can be enabled. + * This should be done only when the corresponding overflow interrupt + * bit is cleared. That indicates that software has already handled the + * previous interrupts or the hardware yet to set an overflow interrupt. + * Otherwise, there will be race conditions where we may clear the bit + * the software is yet to handle the interrupt. + */ + if (!(mip_val & MIP_LCOFIP)) { + mhpmevent_curr &= of_mask; + csr_write_num(mhpmevent_csr, mhpmevent_curr); + } + + return 0; +} + static void pmu_ctr_write_hw(uint32_t cidx, uint64_t ival) { #if __riscv_xlen == 32 csr_write_num(CSR_MCYCLE + cidx, 0); - csr_write_num(CSR_MCYCLE + cidx, ival & 0xFFFF); + csr_write_num(CSR_MCYCLE + cidx, ival & 0xFFFFFFFF); csr_write_num(CSR_MCYCLEH + cidx, ival >> BITS_PER_LONG); #else csr_write_num(CSR_MCYCLE + cidx, ival); @@ -252,12 +288,14 @@ static int pmu_ctr_start_hw(uint32_t cidx, uint64_t ival, bool ival_update) __set_bit(cidx, &mctr_en); __clear_bit(cidx, &mctr_inhbt); - if (ival_update) - pmu_ctr_write_hw(cidx, ival); - + if (sbi_hart_has_feature(scratch, SBI_HART_HAS_SSCOF)) + pmu_ctr_enable_irq_hw(cidx); csr_write(CSR_MCOUNTEREN, mctr_en); csr_write(CSR_MCOUNTINHIBIT, mctr_inhbt); + if (ival_update) + pmu_ctr_write_hw(cidx, ival); + return 0; } @@ -326,7 +364,6 @@ static int pmu_ctr_stop_hw(uint32_t cidx) static int pmu_ctr_stop_fw(uint32_t cidx, uint32_t fw_evt_code) { u32 hartid = current_hartid(); - fw_event_map[hartid][fw_evt_code].bStarted = FALSE; return 0; @@ -362,8 +399,21 @@ int sbi_pmu_ctr_stop(unsigned long cbase, unsigned long cmask, return ret; } +static void pmu_update_inhibit_flags(unsigned long flags, uint64_t *mhpmevent_val) +{ + if (flags & SBI_PMU_CFG_FLAG_SET_VUINH) + *mhpmevent_val |= MHPMEVENT_VUINH; + if (flags & SBI_PMU_CFG_FLAG_SET_VSINH) + *mhpmevent_val |= MHPMEVENT_VSINH; + if (flags & SBI_PMU_CFG_FLAG_SET_UINH) + *mhpmevent_val |= MHPMEVENT_UINH; + if (flags & SBI_PMU_CFG_FLAG_SET_SINH) + *mhpmevent_val |= MHPMEVENT_SINH; +} + static int pmu_update_hw_mhpmevent(struct sbi_pmu_hw_event *hw_evt, int ctr_idx, - unsigned long eindex, uint64_t data) + unsigned long flags, unsigned long eindex, + uint64_t data) { struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); const struct sbi_platform *plat = sbi_platform_ptr(scratch); @@ -375,17 +425,23 @@ static int pmu_update_hw_mhpmevent(struct sbi_pmu_hw_event *hw_evt, int ctr_idx, if (!mhpmevent_val || ctr_idx < 3 || ctr_idx >= SBI_PMU_HW_CTR_MAX) return SBI_EFAIL; - /* TODO: The upper 16 bits of mhpmevent is reserved by sscofpmf extension. - * Update those bits based on the flags received from supervisor. - * The OVF bit also should be cleared here in case it was not cleared - * during event stop. - */ + /* Always clear the OVF bit and inhibit countin of events in M-mode */ + mhpmevent_val = (mhpmevent_val & ~MHPMEVENT_SSCOF_MASK) | MHPMEVENT_MINH; + + /* Update the inhibit flags based on inhibit flags received from supervisor */ + pmu_update_inhibit_flags(flags, &mhpmevent_val); + +#if __riscv_xlen == 32 + csr_write_num(CSR_MCOUNTINHIBIT + ctr_idx, mhpmevent_val & 0xFFFFFFFF); + csr_write_num(CSR_MHPMEVENT3H + ctr_idx - 3, mhpmevent_val >> BITS_PER_LONG); +#else csr_write_num(CSR_MCOUNTINHIBIT + ctr_idx, mhpmevent_val); +#endif return 0; } -static int pmu_ctr_find_hw(unsigned long cbase, unsigned long cmask, +static int pmu_ctr_find_hw(unsigned long cbase, unsigned long cmask, unsigned long flags, unsigned long event_idx, uint64_t data) { unsigned long ctr_mask; @@ -427,7 +483,7 @@ static int pmu_ctr_find_hw(unsigned long cbase, unsigned long cmask, if (ctr_idx == SBI_ENOTSUPP) return SBI_EFAIL; - ret = pmu_update_hw_mhpmevent(temp, ctr_idx, event_idx, data); + ret = pmu_update_hw_mhpmevent(temp, ctr_idx, flags, event_idx, data); if (!ret) ret = ctr_idx; @@ -490,7 +546,8 @@ int sbi_pmu_ctr_cfg_match(unsigned long cidx_base, unsigned long cidx_mask, /* Any firmware counter can be used track any firmware event */ ctr_idx = pmu_ctr_find_fw(cidx_base, cidx_mask, hartid); } else { - ctr_idx = pmu_ctr_find_hw(cidx_base, cidx_mask, event_idx, event_data); + ctr_idx = pmu_ctr_find_hw(cidx_base, cidx_mask, flags, event_idx, + event_data); } if (ctr_idx < 0)