diff options
author | Himanshu Chauhan <hchauhan@ventanamicro.com> | 2023-07-12 10:04:35 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2023-07-13 12:44:02 +0530 |
commit | 6e44ef686a9b329d837c61d7f121541abfcfed90 (patch) | |
tree | b42e9899749b974eec6d9ca7193f2c9eaa5e1f77 /lib/sbi/sbi_hart.c | |
parent | 5dd8db5b10fc03aeded76407aecb731a8a9f1cfa (diff) | |
download | opensbi-6e44ef686a9b329d837c61d7f121541abfcfed90.zip opensbi-6e44ef686a9b329d837c61d7f121541abfcfed90.tar.gz opensbi-6e44ef686a9b329d837c61d7f121541abfcfed90.tar.bz2 |
lib: sbi: Add functions to map/unmap shared memory
When Smepmp is enabled, M-mode will need to map/unmap the
shared memory before it can read/write to it. This patch
adds functions to create dynamic short-lived mappings.
Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'lib/sbi/sbi_hart.c')
-rw-r--r-- | lib/sbi/sbi_hart.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index 12f9c7e..7b5f380 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -347,6 +347,48 @@ unsigned int sbi_hart_get_smepmp_flags(struct sbi_scratch *scratch, return pmp_flags; } +int sbi_hart_map_saddr(unsigned long addr, unsigned long size) +{ + /* shared R/W access for M and S/U mode */ + unsigned int pmp_flags = (PMP_W | PMP_X); + unsigned long order, base = 0; + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + + /* If Smepmp is not supported no special mapping is required */ + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMEPMP)) + return SBI_OK; + + if (is_pmp_entry_mapped(SBI_SMEPMP_RESV_ENTRY)) + return SBI_ENOSPC; + + for (order = log2roundup(size) ; order <= __riscv_xlen; order++) { + if (order < __riscv_xlen) { + base = addr & ~((1UL << order) - 1UL); + if ((base <= addr) && + (addr < (base + (1UL << order))) && + (base <= (addr + size - 1UL)) && + ((addr + size - 1UL) < (base + (1UL << order)))) + break; + } else { + return SBI_EFAIL; + } + } + + pmp_set(SBI_SMEPMP_RESV_ENTRY, pmp_flags, base, order); + + return SBI_OK; +} + +int sbi_hart_unmap_saddr(void) +{ + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); + + if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMEPMP)) + return SBI_OK; + + return pmp_disable(SBI_SMEPMP_RESV_ENTRY); +} + int sbi_hart_pmp_configure(struct sbi_scratch *scratch) { struct sbi_domain_memregion *reg; |