diff options
author | Mayuresh Chitale <mchitale@ventanamicro.com> | 2022-04-11 06:04:10 +0300 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2022-04-11 06:04:10 +0300 |
commit | d44568a0f2e6301d3ad77a48370b0bfef4bfe5a0 (patch) | |
tree | e8d11a4bc4516db5f3a0537d438c1e160bdc4657 | |
parent | 499601a4fff98ff258076c010c980c5dbcc0c24d (diff) | |
download | opensbi-d44568a0f2e6301d3ad77a48370b0bfef4bfe5a0.tar.xz |
lib: sbi: Detect Smstateen CSRs at boot-time
Extend HART feature detection to discover Smstateen CSRs at boot-time
and configure mstateen envcfg bit depending on availability of
menvcfg CSR.
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
-rw-r--r-- | include/sbi/sbi_hart.h | 4 | ||||
-rw-r--r-- | lib/sbi/sbi_hart.c | 25 |
2 files changed, 28 insertions, 1 deletions
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h index 57f80bc..be3ad9f 100644 --- a/include/sbi/sbi_hart.h +++ b/include/sbi/sbi_hart.h @@ -28,9 +28,11 @@ enum sbi_hart_features { SBI_HART_HAS_AIA = (1 << 5), /** HART has menvcfg CSR */ SBI_HART_HAS_MENVCFG = (1 << 6), + /** HART has mstateen CSR **/ + SBI_HART_HAS_SMSTATEEN = (1 << 7), /** Last index of Hart features*/ - SBI_HART_HAS_LAST_FEATURE = SBI_HART_HAS_MENVCFG, + SBI_HART_HAS_LAST_FEATURE = SBI_HART_HAS_SMSTATEEN, }; struct sbi_scratch; diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index 6be9286..b0edf38 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -43,6 +43,7 @@ static void mstatus_init(struct sbi_scratch *scratch) int cidx; unsigned int num_mhpm = sbi_hart_mhpm_count(scratch); uint64_t mhpmevent_init_val = 0; + uint64_t mstateen_val; /* Enable FPU */ if (misa_extension('D') || misa_extension('F')) @@ -87,6 +88,22 @@ static void mstatus_init(struct sbi_scratch *scratch) #endif } + if (sbi_hart_has_feature(scratch, SBI_HART_HAS_SMSTATEEN)) { + mstateen_val = csr_read(CSR_MSTATEEN0); +#if __riscv_xlen == 32 + mstateen_val |= ((uint64_t)csr_read(CSR_MSTATEEN0H)) << 32; +#endif + mstateen_val |= SMSTATEEN_STATEN; + if (sbi_hart_has_feature(scratch, SBI_HART_HAS_MENVCFG)) + mstateen_val |= SMSTATEEN0_HSENVCFG; + else + mstateen_val &= ~SMSTATEEN0_HSENVCFG; + csr_write(CSR_MSTATEEN0, mstateen_val); +#if __riscv_xlen == 32 + csr_write(CSR_MSTATEEN0H, mstateen_val >> 32); +#endif + } + if (sbi_hart_has_feature(scratch, SBI_HART_HAS_MENVCFG)) { menvcfg_val = csr_read(CSR_MENVCFG); @@ -348,6 +365,9 @@ static inline char *sbi_hart_feature_id2string(unsigned long feature) case SBI_HART_HAS_MENVCFG: fstr = "menvcfg"; break; + case SBI_HART_HAS_SMSTATEEN: + fstr = "smstateen"; + break; default: break; } @@ -584,6 +604,11 @@ __aia_skip: if (!trap.cause) hfeatures->features |= SBI_HART_HAS_MENVCFG; + /* Detect if hart supports mstateen CSRs */ + val = csr_read_allowed(CSR_MSTATEEN0, (unsigned long)&trap); + if (!trap.cause) + hfeatures->features |= SBI_HART_HAS_SMSTATEEN; + return; } |