blob: 579d46516bbdcadf06b7814ca78a7a1eb873c71a [file]
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2026 SiFive Inc.
*/
#include <platform_override.h>
#include <sbi/sbi_hart.h>
#include <sbi/sbi_scratch.h>
/*
* Instead of allocating individual PMP entries for each M-mode
* MMIO driver, configure SMEPMP regions to grant R/W permission
* to peripheral and system ports for all privilege modes.
* Finer-grained access control is enforced by wgChecker rules.
*/
static int sifive_smepmp_setup(void)
{
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
int rc;
if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMEPMP))
return 0;
/* Peripheral port region: 0 to 2GiB */
rc = sbi_domain_root_add_memrange(0x0, 0x80000000, 0x80000000,
SBI_DOMAIN_MEMREGION_MMIO |
SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW);
if (rc)
return rc;
#if __riscv_xlen > 32
/* System port region: 512GiB to 1TiB */
rc = sbi_domain_root_add_memrange(0x8000000000ULL, 0x8000000000ULL, 0x8000000000ULL,
SBI_DOMAIN_MEMREGION_MMIO |
SBI_DOMAIN_MEMREGION_SHARED_SURW_MRW);
if (rc)
return rc;
#endif
return 0;
}
static int sifive_early_init(bool cold_boot)
{
int rc;
if (cold_boot) {
rc = sifive_smepmp_setup();
if (rc)
return rc;
}
return generic_early_init(cold_boot);
}
static int sifive_platform_init(const void *fdt, int nodeoff,
const struct fdt_match *match)
{
generic_platform_ops.early_init = sifive_early_init;
return 0;
}
static const struct fdt_match sifive_dev_platform_match[] = {
{ .compatible = "sifive-dev" },
{ },
};
const struct fdt_driver sifive_dev_platform = {
.match_table = sifive_dev_platform_match,
.init = sifive_platform_init,
};