From patchwork Tue Jul 23 07:57:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Zong-You Xie X-Patchwork-Id: 1963644 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=pP493Yv3; 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 4WSqJP1bJfz1yXp for ; Tue, 23 Jul 2024 17:57:57 +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=6GsYRtcfUNLf5Sil6+oqLZXIIIBGEue1PTYuM0pAKmk=; b=pP493Yv34o4VwA azw8fDNeLepQxPV1IQk5IMxVV8zvuO0C2koPQC1HxRwxsm1u68YUGxlYZ9VwVOtQWPz1+0tGvimR4 tsHPi84u0k88EO62xKHCz7jJRoWSC6doZdLa53nJUGfIEuPeIokjxRwO3sYHtw/GvazkowrwRdubV oIL09hdpH7//rvggnoXTdN855V44erPL6sgySK/GoUoqS+9P4GceijogTmgF8RwirORNgSWROfPwb MSJrQ8ipBtToSsr5RpYNXLXnIzumvmSxkSYRFTyclhXzih1ty4jntlpGI6vXQ1oL6IsRgucT2q0B3 Szu3BXlW6AJ1yWo83Tbw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sWAP7-0000000BmXn-1Je3; Tue, 23 Jul 2024 07:57:49 +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.97.1 #2 (Red Hat Linux)) id 1sWAP3-0000000BmUO-3njo for opensbi@lists.infradead.org; Tue, 23 Jul 2024 07:57:48 +0000 Received: from mail.andestech.com (ATCPCS31.andestech.com [10.0.1.89]) by Atcsqr.andestech.com with ESMTPS id 46N7vZSp035910 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 23 Jul 2024 15:57:35 +0800 (+08) (envelope-from ben717@andestech.com) Received: from atctrx.andestech.com (10.0.15.190) by ATCPCS31.andestech.com (10.0.1.89) with Microsoft SMTP Server id 14.3.498.0; Tue, 23 Jul 2024 15:57:35 +0800 From: Ben Zong-You Xie To: CC: Ben Zong-You Xie Subject: [PATCH 3/4] platform: generic: andes: add a new Andes SBI call to set up a PMA entry Date: Tue, 23 Jul 2024 15:57:27 +0800 Message-ID: <20240723075728.587110-4-ben717@andestech.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240723075728.587110-1-ben717@andestech.com> References: <20240723075728.587110-1-ben717@andestech.com> MIME-Version: 1.0 X-Originating-IP: [10.0.15.190] X-DNSRBL: X-SPAM-SOURCE-CHECK: pass X-MAIL: Atcsqr.andestech.com 46N7vZSp035910 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240723_005746_247852_6F5676A9 X-CRM114-Status: GOOD ( 18.50 ) X-Spam-Score: -0.9 (/) 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: Implement a new Andes SBI call, which is to set up a NAPOT region with given memory attributes. Signed-off-by: Ben Zong-You Xie --- platform/generic/andes/andes_pma.c | 110 +++++++++++++++++++++ platform/generic/andes/andes_sbi.c | 9 +- platform/generic/include/andes/andes [...] Content analysis details: (-0.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.0 TVD_RCVD_IP Message was received from an IP address 1.0 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 Implement a new Andes SBI call, which is to set up a NAPOT region with given memory attributes. Signed-off-by: Ben Zong-You Xie Reviewed-by: Anup Patel --- platform/generic/andes/andes_pma.c | 110 +++++++++++++++++++++ platform/generic/andes/andes_sbi.c | 9 +- platform/generic/include/andes/andes_pma.h | 22 ++++- 3 files changed, 137 insertions(+), 4 deletions(-) diff --git a/platform/generic/andes/andes_pma.c b/platform/generic/andes/andes_pma.c index a884bf7..70039ca 100644 --- a/platform/generic/andes/andes_pma.c +++ b/platform/generic/andes/andes_pma.c @@ -94,6 +94,74 @@ static inline bool not_napot(unsigned long addr, unsigned long size) return ((size & (size - 1)) || (addr & (size - 1))); } +static inline bool is_pma_entry_disable(char pmaxcfg) +{ + return (pmaxcfg & ANDES_PMACFG_ETYP_MASK) == ANDES_PMACFG_ETYP_OFF ? + true : false; +} + +static char get_pmaxcfg(int entry_id) +{ + unsigned int pmacfg_addr; + unsigned long pmacfg_val; + char *pmaxcfg; + +#if __riscv_xlen == 64 + pmacfg_addr = CSR_PMACFG0 + ((entry_id / 8) ? 2 : 0); + pmacfg_val = andes_pma_read_num(pmacfg_addr); + pmaxcfg = (char *)&pmacfg_val + (entry_id % 8); +#elif __riscv_xlen == 32 + pmacfg_addr = CSR_PMACFG0 + (entry_id / 4); + pmacfg_val = andes_pma_read_num(pmacfg_addr); + pmaxcfg = (char *)&pmacfg_val + (entry_id % 4); +#else +#error "Unexpected __riscv_xlen" +#endif + return *pmaxcfg; +} + +static void decode_pmaaddrx(int entry_id, unsigned long *start, + unsigned long *size) +{ + unsigned long pmaaddr; + int k; + + /** + * Given $pmaaddr, let k = # of trailing 1s of $pmaaddr + * size = 2 ^ (k + 3) + * start = 4 * ($pmaaddr - (size / 8) + 1) + */ + pmaaddr = andes_pma_read_num(CSR_PMAADDR0 + entry_id); + k = sbi_ffz(pmaaddr); + *size = 1 << (k + 3); + *start = (pmaaddr - (1 << k) + 1) << 2; +} + +static bool has_pma_region_overlap(unsigned long start, unsigned long size) +{ + unsigned long _start, _size, _end, end; + char pmaxcfg; + + end = start + size - 1; + for (int i = 0; i < ANDES_MAX_PMA_REGIONS; i++) { + pmaxcfg = get_pmaxcfg(i); + if (is_pma_entry_disable(pmaxcfg)) + continue; + + decode_pmaaddrx(i, &_start, &_size); + _end = _start + _size - 1; + + if (MAX(start, _start) <= MIN(end, _end)) { + sbi_printf( + "ERROR %s(): %#lx ~ %#lx overlaps with PMA%d: %#lx ~ %#lx\n", + __func__, start, end, i, _start, _end); + return true; + } + } + + return false; +} + static unsigned long andes_pma_setup(const struct andes_pma_region *pma_region, unsigned int entry_id) { @@ -294,3 +362,45 @@ bool andes_sbi_probe_pma(void) { return (csr_read(CSR_MMSC_CFG) & MMSC_CFG_PPMA_MASK) ? true : false; } + +int andes_sbi_set_pma(unsigned long pa, unsigned long size, u8 flags) +{ + unsigned int entry_id; + unsigned long rc; + char pmaxcfg; + struct andes_pma_region region; + + if (!andes_sbi_probe_pma()) { + sbi_printf("ERROR %s(): Platform does not support PPMA.\n", + __func__); + return SBI_ERR_NOT_SUPPORTED; + } + + if (has_pma_region_overlap(pa, size)) + return SBI_ERR_INVALID_PARAM; + + for (entry_id = 0; entry_id < ANDES_MAX_PMA_REGIONS; entry_id++) { + pmaxcfg = get_pmaxcfg(entry_id); + if (is_pma_entry_disable(pmaxcfg)) { + region.pa = pa; + region.size = size; + region.flags = flags; + break; + } + } + + if (entry_id == ANDES_MAX_PMA_REGIONS) { + sbi_printf("ERROR %s(): All PMA entries have run out\n", + __func__); + return SBI_ERR_FAILED; + } + + rc = andes_pma_setup(®ion, entry_id); + if (rc == SBI_EINVAL) { + sbi_printf("ERROR %s(): Failed to set PMAADDR%d\n", + __func__, entry_id); + return SBI_ERR_FAILED; + } + + return SBI_SUCCESS; +} diff --git a/platform/generic/andes/andes_sbi.c b/platform/generic/andes/andes_sbi.c index a7ca4a5..0e4a43d 100644 --- a/platform/generic/andes/andes_sbi.c +++ b/platform/generic/andes/andes_sbi.c @@ -13,6 +13,7 @@ enum sbi_ext_andes_fid { SBI_EXT_ANDES_FID0 = 0, /* Reserved for future use */ SBI_EXT_ANDES_IOCP_SW_WORKAROUND, SBI_EXT_ANDES_PMA_PROBE, + SBI_EXT_ANDES_PMA_SET, }; static bool andes_cache_controllable(void) @@ -39,6 +40,7 @@ int andes_sbi_vendor_ext_provider(long funcid, struct sbi_ecall_return *out, const struct fdt_match *match) { + int ret = 0; switch (funcid) { case SBI_EXT_ANDES_IOCP_SW_WORKAROUND: out->value = andes_apply_iocp_sw_workaround(); @@ -46,10 +48,13 @@ int andes_sbi_vendor_ext_provider(long funcid, case SBI_EXT_ANDES_PMA_PROBE: out->value = andes_sbi_probe_pma(); break; + case SBI_EXT_ANDES_PMA_SET: + ret = andes_sbi_set_pma(regs->a0, regs->a1, regs->a2); + break; default: - return SBI_EINVAL; + ret = SBI_ENOTSUPP; } - return 0; + return ret; } diff --git a/platform/generic/include/andes/andes_pma.h b/platform/generic/include/andes/andes_pma.h index 147dca1..487d9bf 100644 --- a/platform/generic/include/andes/andes_pma.h +++ b/platform/generic/include/andes/andes_pma.h @@ -12,11 +12,15 @@ #define ANDES_PMA_GRANULARITY (1 << 12) +#define ANDES_PMACFG_ETYP_OFFSET 0 +#define ANDES_PMACFG_ETYP_MASK (3 << ANDES_PMACFG_ETYP_OFFSET) +#define ANDES_PMACFG_ETYP_OFF (0 << ANDES_PMACFG_ETYP_OFFSET) /* Naturally aligned power of 2 region */ -#define ANDES_PMACFG_ETYP_NAPOT 3 +#define ANDES_PMACFG_ETYP_NAPOT (3 << ANDES_PMACFG_ETYP_OFFSET) +#define ANDES_PMACFG_MTYP_OFFSET 2 /* Memory, Non-cacheable, Bufferable */ -#define ANDES_PMACFG_MTYP_MEM_NON_CACHE_BUF (3 << 2) +#define ANDES_PMACFG_MTYP_MEM_NON_CACHE_BUF (3 << ANDES_PMACFG_MTYP_OFFSET) /** * struct andes_pma_region - Describes PMA regions @@ -59,4 +63,18 @@ int andes_pma_setup_regions(const struct andes_pma_region *pma_regions, */ bool andes_sbi_probe_pma(void); +/** + * Set a NAPOT region with given memory attributes + * @param pa: Start address of the NAPOT region + * @param size: Size of the NAPOT region + * @param flags: Memory attributes set to the NAPOT region + * + * @return SBI_SUCCESS on success + * @return SBI_ERR_NOT_SUPPORTED if hardware does not support PPMA features + * @return SBI_ERR_INVALID_PARAM if the given region is overlapped with the + * region that has been set already + * @return SBI_ERR_FAILED if available entries have run out or setup fails + */ +int andes_sbi_set_pma(unsigned long pa, unsigned long size, u8 flags); + #endif /* _ANDES_PMA_H_ */