lib: utils/andes: add the SMU and LLC registers to the root domain

When a hart implements Smepmp, S-mode and U-mode cannot reach either
device unless its region is shared explicitly. Suspend and resume then
take an access violation as soon as the supervisor touches the SMU or
the LLC.

Share both regions, and take their sizes from the DT nodes rather than
ignoring them.

Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260728081041.2724668-3-ben717@andestech.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Ben Zong-You Xie
2026-09-01 10:46:23 +05:30
committed by Anup Patel
parent 344428d832
commit 4c5d9d9f93
2 changed files with 28 additions and 7 deletions
+15 -3
View File
@@ -5,8 +5,11 @@
*/
#include <sbi/riscv_io.h>
#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_hart.h>
#include <sbi/sbi_heap.h>
#include <sbi/sbi_scratch.h>
#include <sbi_utils/cache/fdt_cache.h>
#include <sbi_utils/fdt/fdt_driver.h>
#include <sbi_utils/hsm/fdt_hsm_andes_atcsmu.h>
@@ -116,13 +119,13 @@ static struct cache_ops andes_llcache_ops = {
static int andes_llcache_probe(const void *fdt, int nodeoff, const struct fdt_match *match)
{
int rc;
u64 llcache_base = 0;
u64 llcache_base = 0, size;
struct andes_llcache *llcache;
struct cache_device *dev;
uint32_t llcache_cfg;
rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &llcache_base, NULL);
if (rc < 0 || !llcache_base)
rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &llcache_base, &size);
if (rc < 0 || !llcache_base || !size)
return SBI_ENODEV;
llcache = sbi_zalloc(sizeof(*llcache));
@@ -151,6 +154,15 @@ static int andes_llcache_probe(const void *fdt, int nodeoff, const struct fdt_ma
llcache->status_core_stride = 4;
}
if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SMEPMP)) {
rc = sbi_domain_root_add_memrange(
(unsigned long)llcache->base, (unsigned long)size, PAGE_SIZE,
SBI_DOMAIN_MEMREGION_MMIO |
SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW);
if (rc)
return rc;
}
/* Wait for the hardware initialization done */
while (!andes_llcache_init_done(llcache))
;
+13 -4
View File
@@ -184,18 +184,27 @@ static const struct sbi_hsm_device hsm_andes_atcsmu = {
static int hsm_andes_atcsmu_probe(const void *fdt, int nodeoff, const struct fdt_match *match)
{
int poff, rc;
u64 addr;
u64 addr, size;
/* Need to find the parent for the address property */
poff = fdt_parent_offset(fdt, nodeoff);
if (poff < 0)
return SBI_EINVAL;
rc = fdt_get_node_addr_size(fdt, poff, 0, &addr, NULL);
if (rc < 0 || !addr)
rc = fdt_get_node_addr_size(fdt, poff, 0, &addr, &size);
if (rc < 0 || !addr || !size)
return SBI_ENODEV;
atcsmu_base = addr;
if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(), SBI_HART_EXT_SMEPMP)) {
rc = sbi_domain_root_add_memrange(
(unsigned long)addr, (unsigned long)size, PAGE_SIZE,
SBI_DOMAIN_MEMREGION_MMIO |
SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW);
if (rc)
return rc;
}
atcsmu_base = addr;
sbi_hsm_set_device(&hsm_andes_atcsmu);
return 0;
}