From 40a4d0dfbcf00c8534ab8724041705b3db6c5ce2 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Mon, 14 Mar 2022 13:38:42 -0700 Subject: [PATCH] RISC-V: Extract multi-letter extension names from "riscv, isa" Currently, there is no usage for version numbers in extensions as any ratified non base ISA extension will always at v1.0. Extract the extension names in place for future parsing. Tested-by: Heiko Stuebner Reviewed-by: Anup Patel Signed-off-by: Tsukasa OI [Improved commit text and comments] Signed-off-by: Atish Patra Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/cpufeature.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 72c5f6e..b0df7ef 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -124,8 +124,28 @@ void __init riscv_fill_hwcap(void) ext_long = true; /* Multi-letter extension must be delimited */ for (; *isa && *isa != '_'; ++isa) - if (!islower(*isa) && !isdigit(*isa)) + if (unlikely(!islower(*isa) + && !isdigit(*isa))) ext_err = true; + /* Parse backwards */ + ext_end = isa; + if (unlikely(ext_err)) + break; + if (!isdigit(ext_end[-1])) + break; + /* Skip the minor version */ + while (isdigit(*--ext_end)) + ; + if (ext_end[0] != 'p' + || !isdigit(ext_end[-1])) { + /* Advance it to offset the pre-decrement */ + ++ext_end; + break; + } + /* Skip the major version */ + while (isdigit(*--ext_end)) + ; + ++ext_end; break; default: if (unlikely(!islower(*ext))) { @@ -151,14 +171,13 @@ void __init riscv_fill_hwcap(void) } if (*isa != '_') --isa; - /* - * TODO: Full version-aware handling including - * multi-letter extensions will be added in-future. - */ - if (ext_err || ext_long) + + if (unlikely(ext_err)) continue; - this_hwcap |= isa2hwcap[(unsigned char)(*ext)]; - this_isa |= (1UL << (*ext - 'a')); + if (!ext_long) { + this_hwcap |= isa2hwcap[(unsigned char)(*ext)]; + this_isa |= (1UL << (*ext - 'a')); + } } /* -- 2.7.4