From: Bo Gan <ganboing@gmail.com>
To: opensbi@lists.infradead.org
Cc: linmin@eswincomputing.com, pinkesh.vaghela@einfochips.com,
gaohan@iscas.ac.cn, samuel@sholland.org, wangxiang@iscas.ac.cn
Subject: [PATCH v2 2/5] lib: sbi: Add __pmp_set_tor for setting TOR regions
Date: Sun, 16 Nov 2025 21:48:43 -0800 [thread overview]
Message-ID: <20251117054846.1335-3-ganboing@gmail.com> (raw)
In-Reply-To: <20251117054846.1335-1-ganboing@gmail.com>
TOR can be utilized to cover memory regions that are not aligned with
their sizes. Given that the address matching is formed bt 2 consecutive
pmpaddr, i.e., pmpaddr(i-1) and pmpaddr(i), TOR should not be used
generically to avoid pmpaddr conflict with other NA4/NAPOT regions.
Only use them in platform PMP (un)configure override code where the
caller can ensure the index and order of every pmp region especially when
there's a mixture of TOR/NA4/NAPOT. Don't use TOR in lib/ code. For lib/
code, maintain the 1:1 PMP entry <-> memory region correspondence.
Signed-off-by: Bo Gan <ganboing@gmail.com>
---
include/sbi/riscv_asm.h | 7 ++++
lib/sbi/riscv_asm.c | 75 +++++++++++++++++++++++++++++++----------
2 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h
index ef48dc89..04ecf5c1 100644
--- a/include/sbi/riscv_asm.h
+++ b/include/sbi/riscv_asm.h
@@ -215,6 +215,13 @@ int pmp_disable(unsigned int n);
/* Check if the matching field is set */
int is_pmp_entry_mapped(unsigned long entry);
+/**
+ * Top of range (TOR) matching mode. pmpaddr(n-1) will also be changed.
+ * Use it *very* carefully.
+ */
+int __pmp_set_tor(unsigned int n, unsigned long prot, unsigned long addr,
+ unsigned long size);
+
int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
unsigned long log2len);
diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c
index 3e44320f..557e1c82 100644
--- a/lib/sbi/riscv_asm.c
+++ b/lib/sbi/riscv_asm.c
@@ -330,16 +330,10 @@ int is_pmp_entry_mapped(unsigned long entry)
return false;
}
-int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
- unsigned long log2len)
+static void pmp_set_prot(unsigned int n, unsigned long prot)
{
- int pmpcfg_csr, pmpcfg_shift, pmpaddr_csr;
+ int pmpcfg_csr, pmpcfg_shift;
unsigned long cfgmask, pmpcfg;
- unsigned long addrmask, pmpaddr;
-
- /* check parameters */
- if (n >= PMP_COUNT || log2len > __riscv_xlen || log2len < PMP_SHIFT)
- return SBI_EINVAL;
/* calculate PMP register and offset */
#if __riscv_xlen == 32
@@ -351,15 +345,29 @@ int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
#else
# error "Unexpected __riscv_xlen"
#endif
- pmpaddr_csr = CSR_PMPADDR0 + n;
-
- /* encode PMP config */
- prot &= ~PMP_A;
- prot |= (log2len == PMP_SHIFT) ? PMP_A_NA4 : PMP_A_NAPOT;
cfgmask = ~(0xffUL << pmpcfg_shift);
pmpcfg = (csr_read_num(pmpcfg_csr) & cfgmask);
pmpcfg |= ((prot << pmpcfg_shift) & ~cfgmask);
+ csr_write_num(pmpcfg_csr, pmpcfg);
+}
+
+static void pmp_set_addr(unsigned int n, unsigned long pmpaddr)
+{
+ int pmpaddr_csr = CSR_PMPADDR0 + n;
+
+ csr_write_num(pmpaddr_csr, pmpaddr);
+}
+
+int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
+ unsigned long log2len)
+{
+ unsigned long addrmask, pmpaddr;
+
+ /* check parameters */
+ if (n >= PMP_COUNT || log2len > __riscv_xlen || log2len < PMP_SHIFT)
+ return SBI_EINVAL;
+
/* encode PMP address */
if (log2len == PMP_SHIFT) {
pmpaddr = (addr >> PMP_SHIFT);
@@ -373,10 +381,41 @@ int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
}
}
+ /* encode PMP config */
+ prot &= ~PMP_A;
+ prot |= (log2len == PMP_SHIFT) ? PMP_A_NA4 : PMP_A_NAPOT;
+
/* write csrs */
- csr_write_num(pmpaddr_csr, pmpaddr);
- csr_write_num(pmpcfg_csr, pmpcfg);
+ pmp_set_addr(n, pmpaddr);
+ pmp_set_prot(n, prot);
+ return 0;
+}
+
+int __pmp_set_tor(unsigned int n, unsigned long prot, unsigned long addr,
+ unsigned long size)
+{
+ unsigned long pmpaddr, pmpaddrp;
+
+ /* check parameters */
+ if (n >= PMP_COUNT)
+ return SBI_EINVAL;
+
+ if (n == 0 && addr != 0)
+ return SBI_EINVAL;
+
+ /* encode PMP address */
+ pmpaddrp = addr >> PMP_SHIFT;
+ pmpaddr = (addr + size) >> PMP_SHIFT;
+ /* encode PMP config */
+ prot &= ~PMP_A;
+ prot |= PMP_A_TOR;
+
+ /* write csrs */
+ if (n)
+ pmp_set_addr(n - 1, pmpaddrp);
+ pmp_set_addr(n, pmpaddr);
+ pmp_set_prot(n, prot);
return 0;
}
@@ -420,10 +459,12 @@ int pmp_get(unsigned int n, unsigned long *prot_out, unsigned long *addr_out,
addr = (addr & ~((1UL << t1) - 1)) << PMP_SHIFT;
len = (t1 + PMP_SHIFT + 1);
}
- } else {
+ } else if ((prot & PMP_A) == PMP_A_NA4) {
addr = csr_read_num(pmpaddr_csr) << PMP_SHIFT;
len = PMP_SHIFT;
- }
+ } else
+ /* Error out for TOR region */
+ return SBI_EINVAL;
/* return details */
*prot_out = prot;
--
2.34.1
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
next prev parent reply other threads:[~2025-11-17 5:50 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-17 5:48 [PATCH v2 0/5] Initial ESWIN/EIC7700 support Bo Gan
2025-11-17 5:48 ` [PATCH v2 1/5] lib: sbi: allow platform to override PMP (un)configuration Bo Gan
2025-11-17 5:48 ` Bo Gan [this message]
2025-11-17 5:48 ` [PATCH v2 3/5] firmware: add CONFIG_FIRMWARE_PACKED_RXRW Bo Gan
2025-11-17 5:48 ` [PATCH v2 4/5] include: sbi: Add helpers for sbi_domain_memregion Bo Gan
2025-11-17 5:48 ` [PATCH v2 5/5] platform: generic: eswin: add EIC7700 Bo Gan
2025-11-17 8:04 ` [PATCH v2 0/5] Initial ESWIN/EIC7700 support Anup Patel
2025-11-17 9:29 ` Bo Gan
2025-11-17 15:09 ` Anup Patel
2025-11-18 7:03 ` Bo Gan
2025-11-18 17:23 ` Anup Patel
2025-11-20 9:39 ` Bo Gan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251117054846.1335-3-ganboing@gmail.com \
--to=ganboing@gmail.com \
--cc=gaohan@iscas.ac.cn \
--cc=linmin@eswincomputing.com \
--cc=opensbi@lists.infradead.org \
--cc=pinkesh.vaghela@einfochips.com \
--cc=samuel@sholland.org \
--cc=wangxiang@iscas.ac.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.