mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2026-09-08 18:21:29 +01:00
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:
committed by
Anup Patel
parent
344428d832
commit
4c5d9d9f93
Vendored
+15
-3
@@ -5,8 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sbi/riscv_io.h>
|
#include <sbi/riscv_io.h>
|
||||||
|
#include <sbi/sbi_domain.h>
|
||||||
#include <sbi/sbi_error.h>
|
#include <sbi/sbi_error.h>
|
||||||
|
#include <sbi/sbi_hart.h>
|
||||||
#include <sbi/sbi_heap.h>
|
#include <sbi/sbi_heap.h>
|
||||||
|
#include <sbi/sbi_scratch.h>
|
||||||
#include <sbi_utils/cache/fdt_cache.h>
|
#include <sbi_utils/cache/fdt_cache.h>
|
||||||
#include <sbi_utils/fdt/fdt_driver.h>
|
#include <sbi_utils/fdt/fdt_driver.h>
|
||||||
#include <sbi_utils/hsm/fdt_hsm_andes_atcsmu.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)
|
static int andes_llcache_probe(const void *fdt, int nodeoff, const struct fdt_match *match)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
u64 llcache_base = 0;
|
u64 llcache_base = 0, size;
|
||||||
struct andes_llcache *llcache;
|
struct andes_llcache *llcache;
|
||||||
struct cache_device *dev;
|
struct cache_device *dev;
|
||||||
uint32_t llcache_cfg;
|
uint32_t llcache_cfg;
|
||||||
|
|
||||||
rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &llcache_base, NULL);
|
rc = fdt_get_node_addr_size(fdt, nodeoff, 0, &llcache_base, &size);
|
||||||
if (rc < 0 || !llcache_base)
|
if (rc < 0 || !llcache_base || !size)
|
||||||
return SBI_ENODEV;
|
return SBI_ENODEV;
|
||||||
|
|
||||||
llcache = sbi_zalloc(sizeof(*llcache));
|
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;
|
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 */
|
/* Wait for the hardware initialization done */
|
||||||
while (!andes_llcache_init_done(llcache))
|
while (!andes_llcache_init_done(llcache))
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -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)
|
static int hsm_andes_atcsmu_probe(const void *fdt, int nodeoff, const struct fdt_match *match)
|
||||||
{
|
{
|
||||||
int poff, rc;
|
int poff, rc;
|
||||||
u64 addr;
|
u64 addr, size;
|
||||||
|
|
||||||
/* Need to find the parent for the address property */
|
/* Need to find the parent for the address property */
|
||||||
poff = fdt_parent_offset(fdt, nodeoff);
|
poff = fdt_parent_offset(fdt, nodeoff);
|
||||||
if (poff < 0)
|
if (poff < 0)
|
||||||
return SBI_EINVAL;
|
return SBI_EINVAL;
|
||||||
|
|
||||||
rc = fdt_get_node_addr_size(fdt, poff, 0, &addr, NULL);
|
rc = fdt_get_node_addr_size(fdt, poff, 0, &addr, &size);
|
||||||
if (rc < 0 || !addr)
|
if (rc < 0 || !addr || !size)
|
||||||
return SBI_ENODEV;
|
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);
|
sbi_hsm_set_device(&hsm_andes_atcsmu);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user