Refine platform features control
Allow a platform to report its supported features in more details. The new features defined are: * SBI_PLATFORM_HAS_PMP * SBI_PLATFORM_HAS_SCOUNTEREN * SBI_PLATFORM_HAS_MCOUNTEREN In addition, define the macro SBI_PLATFORM_DEFAULT_FEATURES as the set of features that are generally expected to be supported by a Linux capable platform. Operations touching the features controlled with these falgs are not executed if the platform does not set the corresponding feature flags. Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
This commit is contained in:
parent
f003787455
commit
aa68f0252f
|
@ -16,7 +16,7 @@ struct sbi_scratch;
|
||||||
|
|
||||||
int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid);
|
int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid);
|
||||||
|
|
||||||
void sbi_hart_pmp_dump(void);
|
void sbi_hart_pmp_dump(struct sbi_scratch *scratch);
|
||||||
|
|
||||||
void __attribute__((noreturn)) sbi_hart_hang(void);
|
void __attribute__((noreturn)) sbi_hart_hang(void);
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,19 @@
|
||||||
#include <sbi/sbi_scratch.h>
|
#include <sbi/sbi_scratch.h>
|
||||||
|
|
||||||
enum sbi_platform_features {
|
enum sbi_platform_features {
|
||||||
SBI_PLATFORM_HAS_MMIO_TIMER_VALUE = (1 << 0),
|
SBI_PLATFORM_HAS_MMIO_TIMER_VALUE = (1 << 0),
|
||||||
SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1),
|
SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1),
|
||||||
|
SBI_PLATFORM_HAS_PMP = (1 << 2),
|
||||||
|
SBI_PLATFORM_HAS_SCOUNTEREN = (1 << 3),
|
||||||
|
SBI_PLATFORM_HAS_MCOUNTEREN = (1 << 4),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SBI_PLATFORM_DEFAULT_FEATURES \
|
||||||
|
(SBI_PLATFORM_HAS_MMIO_TIMER_VALUE | \
|
||||||
|
SBI_PLATFORM_HAS_PMP | \
|
||||||
|
SBI_PLATFORM_HAS_SCOUNTEREN | \
|
||||||
|
SBI_PLATFORM_HAS_MCOUNTEREN)
|
||||||
|
|
||||||
struct sbi_platform {
|
struct sbi_platform {
|
||||||
char name[64];
|
char name[64];
|
||||||
u64 features;
|
u64 features;
|
||||||
|
@ -48,17 +57,20 @@ struct sbi_platform {
|
||||||
int (*system_shutdown)(u32 type);
|
int (*system_shutdown)(u32 type);
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
#define sbi_platform_ptr(__s) \
|
#define sbi_platform_ptr(__s) \
|
||||||
((struct sbi_platform *)((__s)->platform_addr))
|
((struct sbi_platform *)((__s)->platform_addr))
|
||||||
|
#define sbi_platform_thishart_ptr() \
|
||||||
#define sbi_platform_thishart_ptr() \
|
((struct sbi_platform *)(sbi_scratch_thishart_ptr()->platform_addr))
|
||||||
((struct sbi_platform *)(sbi_scratch_thishart_ptr()->platform_addr))
|
|
||||||
|
|
||||||
#define sbi_platform_has_mmio_timer_value(__p) \
|
#define sbi_platform_has_mmio_timer_value(__p) \
|
||||||
((__p)->features & SBI_PLATFORM_HAS_MMIO_TIMER_VALUE)
|
((__p)->features & SBI_PLATFORM_HAS_MMIO_TIMER_VALUE)
|
||||||
|
|
||||||
#define sbi_platform_has_hart_hotplug(__p) \
|
#define sbi_platform_has_hart_hotplug(__p) \
|
||||||
((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG)
|
((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG)
|
||||||
|
#define sbi_platform_has_pmp(__p) \
|
||||||
|
((__p)->features & SBI_PLATFORM_HAS_PMP)
|
||||||
|
#define sbi_platform_has_scounteren(__p) \
|
||||||
|
((__p)->features & SBI_PLATFORM_HAS_SCOUNTEREN)
|
||||||
|
#define sbi_platform_has_mcounteren(__p) \
|
||||||
|
((__p)->features & SBI_PLATFORM_HAS_MCOUNTEREN)
|
||||||
|
|
||||||
static inline const char *sbi_platform_name(struct sbi_platform *plat)
|
static inline const char *sbi_platform_name(struct sbi_platform *plat)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,16 +17,20 @@
|
||||||
#include <sbi/sbi_hart.h>
|
#include <sbi/sbi_hart.h>
|
||||||
#include <sbi/sbi_platform.h>
|
#include <sbi/sbi_platform.h>
|
||||||
|
|
||||||
static int mstatus_init(u32 hartid)
|
static void mstatus_init(struct sbi_scratch *scratch, u32 hartid)
|
||||||
{
|
{
|
||||||
|
struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||||
|
|
||||||
/* Enable FPU */
|
/* Enable FPU */
|
||||||
if (misa_extension('D') || misa_extension('F'))
|
if (misa_extension('D') || misa_extension('F'))
|
||||||
csr_write(mstatus, MSTATUS_FS);
|
csr_write(mstatus, MSTATUS_FS);
|
||||||
|
|
||||||
/* Enable user/supervisor use of perf counters */
|
/* Enable user/supervisor use of perf counters */
|
||||||
if (misa_extension('S'))
|
if (misa_extension('S') &&
|
||||||
|
sbi_platform_has_scounteren(plat))
|
||||||
csr_write(scounteren, -1);
|
csr_write(scounteren, -1);
|
||||||
csr_write(mcounteren, -1);
|
if (sbi_platform_has_mcounteren(plat))
|
||||||
|
csr_write(mcounteren, -1);
|
||||||
|
|
||||||
/* Disable all interrupts */
|
/* Disable all interrupts */
|
||||||
csr_write(mie, 0);
|
csr_write(mie, 0);
|
||||||
|
@ -34,8 +38,6 @@ static int mstatus_init(u32 hartid)
|
||||||
/* Disable S-mode paging */
|
/* Disable S-mode paging */
|
||||||
if (misa_extension('S'))
|
if (misa_extension('S'))
|
||||||
csr_write(sptbr, 0);
|
csr_write(sptbr, 0);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __riscv_flen
|
#ifdef __riscv_flen
|
||||||
|
@ -111,10 +113,14 @@ unsigned long log2roundup(unsigned long x)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sbi_hart_pmp_dump(void)
|
void sbi_hart_pmp_dump(struct sbi_scratch *scratch)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||||
unsigned long prot, addr, size, l2l;
|
unsigned long prot, addr, size, l2l;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!sbi_platform_has_pmp(plat))
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < PMP_COUNT; i++) {
|
for (i = 0; i < PMP_COUNT; i++) {
|
||||||
pmp_get(i, &prot, &addr, &l2l);
|
pmp_get(i, &prot, &addr, &l2l);
|
||||||
|
@ -149,6 +155,9 @@ static int pmp_init(struct sbi_scratch *scratch, u32 hartid)
|
||||||
ulong prot, addr, log2size;
|
ulong prot, addr, log2size;
|
||||||
struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
||||||
|
|
||||||
|
if (!sbi_platform_has_pmp(plat))
|
||||||
|
return 0;
|
||||||
|
|
||||||
fw_size_log2 = log2roundup(scratch->fw_size);
|
fw_size_log2 = log2roundup(scratch->fw_size);
|
||||||
fw_start = scratch->fw_start & ~((1UL << fw_size_log2) - 1UL);
|
fw_start = scratch->fw_start & ~((1UL << fw_size_log2) - 1UL);
|
||||||
|
|
||||||
|
@ -172,9 +181,7 @@ int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = mstatus_init(hartid);
|
mstatus_init(scratch, hartid);
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = fp_init(hartid);
|
rc = fp_init(hartid);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
|
|
@ -91,7 +91,7 @@ static void __attribute__((noreturn)) init_coldboot(struct sbi_scratch *scratch,
|
||||||
sbi_ecall_version_major(), sbi_ecall_version_minor());
|
sbi_ecall_version_major(), sbi_ecall_version_minor());
|
||||||
sbi_printf("\n");
|
sbi_printf("\n");
|
||||||
|
|
||||||
sbi_hart_pmp_dump();
|
sbi_hart_pmp_dump(scratch);
|
||||||
|
|
||||||
sbi_hart_mark_available(hartid);
|
sbi_hart_mark_available(hartid);
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ static int sifive_u_system_down(u32 type)
|
||||||
|
|
||||||
struct sbi_platform platform = {
|
struct sbi_platform platform = {
|
||||||
.name = STRINGIFY(PLAT_NAME),
|
.name = STRINGIFY(PLAT_NAME),
|
||||||
.features = SBI_PLATFORM_HAS_MMIO_TIMER_VALUE,
|
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||||
.hart_count = PLAT_HART_COUNT,
|
.hart_count = PLAT_HART_COUNT,
|
||||||
.hart_stack_size = PLAT_HART_STACK_SIZE,
|
.hart_stack_size = PLAT_HART_STACK_SIZE,
|
||||||
.pmp_region_count = sifive_u_pmp_region_count,
|
.pmp_region_count = sifive_u_pmp_region_count,
|
||||||
|
|
|
@ -86,7 +86,7 @@ static int virt_system_down(u32 type)
|
||||||
|
|
||||||
struct sbi_platform platform = {
|
struct sbi_platform platform = {
|
||||||
.name = STRINGIFY(PLAT_NAME),
|
.name = STRINGIFY(PLAT_NAME),
|
||||||
.features = SBI_PLATFORM_HAS_MMIO_TIMER_VALUE,
|
.features = SBI_PLATFORM_DEFAULT_FEATURES,
|
||||||
.hart_count = PLAT_HART_COUNT,
|
.hart_count = PLAT_HART_COUNT,
|
||||||
.hart_stack_size = PLAT_HART_STACK_SIZE,
|
.hart_stack_size = PLAT_HART_STACK_SIZE,
|
||||||
.pmp_region_count = virt_pmp_region_count,
|
.pmp_region_count = virt_pmp_region_count,
|
||||||
|
|
|
@ -105,7 +105,7 @@ static int sifive_u_system_down(u32 type)
|
||||||
|
|
||||||
struct sbi_platform platform = {
|
struct sbi_platform platform = {
|
||||||
.name = STRINGIFY(PLAT_NAME),
|
.name = STRINGIFY(PLAT_NAME),
|
||||||
.features = SBI_PLATFORM_HAS_MMIO_TIMER_VALUE,
|
.features = SBI_PLATFORM_DEFAULT_FEATURES;
|
||||||
.hart_count = PLAT_HART_COUNT,
|
.hart_count = PLAT_HART_COUNT,
|
||||||
.hart_stack_size = PLAT_HART_STACK_SIZE,
|
.hart_stack_size = PLAT_HART_STACK_SIZE,
|
||||||
.pmp_region_count = sifive_u_pmp_region_count,
|
.pmp_region_count = sifive_u_pmp_region_count,
|
||||||
|
|
Loading…
Reference in New Issue