mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-24 15:31:22 +01:00
lib: sbi: fwft: Use only the provided PMLEN value
As of riscv-sbi-doc commit c7d3d1f7dcaa ("ext-fwft: use the provided value in fwft_set(POINTER_MASKING_PMLEN)"), the SBI implementation must use only the provided PMLEN value or else fail. It may not fall back to a larger PMLEN value. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Radim Krčmář <rkrcmar@ventanamicro.com> Link: https://lore.kernel.org/r/20250522013503.2556053-1-samuel.holland@sifive.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:

committed by
Anup Patel

parent
f30a54f3b3
commit
771c656181
@@ -223,32 +223,32 @@ static int fwft_pmlen_supported(struct fwft_config *conf)
|
|||||||
return SBI_OK;
|
return SBI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool fwft_try_to_set_pmm(unsigned long pmm)
|
|
||||||
{
|
|
||||||
csr_set(CSR_MENVCFG, pmm);
|
|
||||||
return (csr_read(CSR_MENVCFG) & ENVCFG_PMM) == pmm;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fwft_set_pmlen(struct fwft_config *conf, unsigned long value)
|
static int fwft_set_pmlen(struct fwft_config *conf, unsigned long value)
|
||||||
{
|
{
|
||||||
unsigned long prev;
|
unsigned long pmm, prev;
|
||||||
|
|
||||||
if (value > 16)
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
pmm = ENVCFG_PMM_PMLEN_0;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
pmm = ENVCFG_PMM_PMLEN_7;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
pmm = ENVCFG_PMM_PMLEN_16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return SBI_EINVAL;
|
return SBI_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
prev = csr_read_clear(CSR_MENVCFG, ENVCFG_PMM);
|
prev = csr_read_clear(CSR_MENVCFG, ENVCFG_PMM);
|
||||||
if (value == 0)
|
csr_set(CSR_MENVCFG, pmm);
|
||||||
return SBI_OK;
|
if ((csr_read(CSR_MENVCFG) & ENVCFG_PMM) != pmm) {
|
||||||
if (value <= 7) {
|
csr_write(CSR_MENVCFG, prev);
|
||||||
if (fwft_try_to_set_pmm(ENVCFG_PMM_PMLEN_7))
|
return SBI_EINVAL;
|
||||||
return SBI_OK;
|
|
||||||
csr_clear(CSR_MENVCFG, ENVCFG_PMM);
|
|
||||||
}
|
}
|
||||||
if (fwft_try_to_set_pmm(ENVCFG_PMM_PMLEN_16))
|
|
||||||
return SBI_OK;
|
|
||||||
csr_write(CSR_MENVCFG, prev);
|
|
||||||
|
|
||||||
return SBI_EINVAL;
|
return SBI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fwft_get_pmlen(struct fwft_config *conf, unsigned long *value)
|
static int fwft_get_pmlen(struct fwft_config *conf, unsigned long *value)
|
||||||
|
Reference in New Issue
Block a user