riscv: cpu: check U-Mode before counteren write

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>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
This commit is contained in:
Nikita Shubin 2022-12-14 08:58:43 +03:00 committed by Leo Yu-Chi Liang
parent 73a3f51391
commit 81b56a55c2

View File

@ -33,7 +33,9 @@ u32 available_harts_lock = 1;
static inline bool supports_extension(char ext) 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; struct udevice *dev;
char desc[32]; char desc[32];
int i; int i;
@ -58,13 +60,9 @@ static inline bool supports_extension(char ext)
return false; return false;
#else /* !CONFIG_CPU */ #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 "There is no way to determine the available extensions in S-mode."
#warning "Please convert your board to use the RISC-V CPU driver." #warning "Please convert your board to use the RISC-V CPU driver."
return false; return false;
#endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */
#endif /* CONFIG_CPU */ #endif /* CONFIG_CPU */
} }
@ -112,12 +110,14 @@ int riscv_cpu_setup(void *ctx, struct event *event)
* Enable perf counters for cycle, time, * Enable perf counters for cycle, time,
* and instret counters only * and instret counters only
*/ */
if (supports_extension('u')) {
#ifdef CONFIG_RISCV_PRIV_1_9 #ifdef CONFIG_RISCV_PRIV_1_9
csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0)); csr_write(CSR_MSCOUNTEREN, GENMASK(2, 0));
csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0)); csr_write(CSR_MUCOUNTEREN, GENMASK(2, 0));
#else #else
csr_write(CSR_MCOUNTEREN, GENMASK(2, 0)); csr_write(CSR_MCOUNTEREN, GENMASK(2, 0));
#endif #endif
}
/* Disable paging */ /* Disable paging */
if (supports_extension('s')) if (supports_extension('s'))