From 27332e63faaf6d3220a9d56bcfb280921114f012 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Fri, 21 Dec 2018 19:19:54 +0900 Subject: [PATCH] Introduce HAS_MFAULTS_DELEGATION feature Conditionnally delegate page fault exceptions from M mode to S mode based on the platform features. Signed-off-by: Damien Le Moal --- include/sbi/sbi_platform.h | 6 +++++- lib/sbi_hart.c | 12 +++++++----- platform/sifive/hifive_u540/platform.c | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h index 39dfb499..6de52f63 100644 --- a/include/sbi/sbi_platform.h +++ b/include/sbi/sbi_platform.h @@ -18,13 +18,15 @@ enum sbi_platform_features { SBI_PLATFORM_HAS_PMP = (1 << 2), SBI_PLATFORM_HAS_SCOUNTEREN = (1 << 3), SBI_PLATFORM_HAS_MCOUNTEREN = (1 << 4), + SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 5), }; #define SBI_PLATFORM_DEFAULT_FEATURES \ (SBI_PLATFORM_HAS_MMIO_TIMER_VALUE | \ SBI_PLATFORM_HAS_PMP | \ SBI_PLATFORM_HAS_SCOUNTEREN | \ - SBI_PLATFORM_HAS_MCOUNTEREN) + SBI_PLATFORM_HAS_MCOUNTEREN | \ + SBI_PLATFORM_HAS_MFAULTS_DELEGATION) struct sbi_platform { char name[64]; @@ -71,6 +73,8 @@ struct sbi_platform { ((__p)->features & SBI_PLATFORM_HAS_SCOUNTEREN) #define sbi_platform_has_mcounteren(__p) \ ((__p)->features & SBI_PLATFORM_HAS_MCOUNTEREN) +#define sbi_platform_has_mfaults_delegation(__p) \ + ((__p)->features & SBI_PLATFORM_HAS_MFAULTS_DELEGATION) static inline const char *sbi_platform_name(struct sbi_platform *plat) { diff --git a/lib/sbi_hart.c b/lib/sbi_hart.c index 01362dd7..be114d69 100644 --- a/lib/sbi_hart.c +++ b/lib/sbi_hart.c @@ -83,8 +83,9 @@ static int fp_init(u32 hartid) return 0; } -static int delegate_traps(u32 hartid) +static int delegate_traps(struct sbi_scratch *scratch, u32 hartid) { + struct sbi_platform *plat = sbi_platform_ptr(scratch); unsigned long interrupts, exceptions; if (!misa_extension('S')) { @@ -95,11 +96,12 @@ static int delegate_traps(u32 hartid) /* Send M-mode interrupts and most exceptions to S-mode */ interrupts = MIP_SSIP | MIP_STIP | MIP_SEIP; exceptions = (1U << CAUSE_MISALIGNED_FETCH) | - (1U << CAUSE_FETCH_PAGE_FAULT) | (1U << CAUSE_BREAKPOINT) | - (1U << CAUSE_LOAD_PAGE_FAULT) | - (1U << CAUSE_STORE_PAGE_FAULT) | (1U << CAUSE_USER_ECALL); + if (sbi_platform_has_mfaults_delegation(plat)) + exceptions |= (1U << CAUSE_FETCH_PAGE_FAULT) | + (1U << CAUSE_LOAD_PAGE_FAULT) | + (1U << CAUSE_STORE_PAGE_FAULT); } csr_write(mideleg, interrupts); @@ -200,7 +202,7 @@ int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid) if (rc) return rc; - rc = delegate_traps(hartid); + rc = delegate_traps(scratch, hartid); if (rc) return rc; diff --git a/platform/sifive/hifive_u540/platform.c b/platform/sifive/hifive_u540/platform.c index 46613e60..338cc2cc 100644 --- a/platform/sifive/hifive_u540/platform.c +++ b/platform/sifive/hifive_u540/platform.c @@ -105,7 +105,7 @@ static int sifive_u_system_down(u32 type) struct sbi_platform platform = { .name = STRINGIFY(PLAT_NAME), - .features = SBI_PLATFORM_DEFAULT_FEATURES; + .features = SBI_PLATFORM_DEFAULT_FEATURES, .hart_count = PLAT_HART_COUNT, .hart_stack_size = PLAT_HART_STACK_SIZE, .pmp_region_count = sifive_u_pmp_region_count,