Message ID | 20221214055843.7177-1-nikita.shubin@maquefel.me |
---|---|
State | Accepted |
Delegated to: | Andes |
Headers | show |
Series | [RFC] riscv: cpu: check U-Mode before counteren write | expand |
On Wed, Dec 14, 2022 at 08:58:43AM +0300, Nikita Shubin wrote: > From: Nikita Shubin <n.shubin@yadro.com> > > The Priv ISA states: > "In systems without U-mode, the mcounteren register should > not exist." > > Check U-Mode is present in MISA before writing to counteren, otherwise > we endup with Illegal Instruction exception on systems without U-Mode. > > Also make checking MISA default for M-Mode. > > Signed-off-by: Nikita Shubin <n.shubin@yadro.com> > --- > This seems obvious at first glance, but i've never seen 'u' extension > enywhere in "riscv,isa" device tree property, even qemu doesn't set this, > and if we simply enable this check - this will break existing board for sure. > > We can rely on MISA completely if we are in M-Mode, as we currently check only > 'd', 'f' and 'u', which are standart and nothing fancy. > --- > arch/riscv/cpu/cpu.c | 16 ++++++++-------- > 1 file changed, 8 insertions(+), 8 deletions(-) Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 0f323b26b3..917f71c8d7 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -31,7 +31,9 @@ u32 available_harts_lock = 1; static inline bool supports_extension(char ext) { -#ifdef CONFIG_CPU +#if CONFIG_IS_ENABLED(RISCV_MMODE) + return csr_read(CSR_MISA) & (1 << (ext - 'a')); +#elif CONFIG_CPU struct udevice *dev; char desc[32]; @@ -48,13 +50,9 @@ static inline bool supports_extension(char ext) return false; #else /* !CONFIG_CPU */ -#if CONFIG_IS_ENABLED(RISCV_MMODE) - return csr_read(CSR_MISA) & (1 << (ext - 'a')); -#else /* !CONFIG_IS_ENABLED(RISCV_MMODE) */ #warning "There is no way to determine the available extensions in S-mode." #warning "Please convert your board to use the RISC-V CPU driver." return false; -#endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */ #endif /* CONFIG_CPU */ } @@ -102,12 +100,14 @@ int riscv_cpu_setup(void *ctx, struct event *event) * Enable perf counters for cycle, time, * and instret counters only */ + if (supports_extension('u')) { #ifdef CONFIG_RISCV_PRIV_1_9 - csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0)); - csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0)); + csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0)); + csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0)); #else - csr_write(CSR_MCOUNTEREN, GENMASK(2, 0)); + csr_write(CSR_MCOUNTEREN, GENMASK(2, 0)); #endif + } /* Disable paging */ if (supports_extension('s'))