Message ID | 20220215090211.911366-4-atishp@rivosinc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Provide a fraemework for RISC-V ISA extensions | expand |
On Tue, Feb 15, 2022 at 2:32 PM Atish Patra <atishp@rivosinc.com> wrote: > > From: Tsukasa OI <research_trasio@irq.a4lg.com> > > 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. > > Signed-off-by: Tsukasa OI <research_trasio@irq.a4lg.com> > [Improved commit text and comments] > Signed-off-by: Atish Patra <atishp@rivosinc.com> > Tested-by: Heiko Stuebner <heiko@sntech.de> > --- > arch/riscv/kernel/cpufeature.c | 38 ++++++++++++++++++++++++++-------- > 1 file changed, 29 insertions(+), 9 deletions(-) > > diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c > index 9d5448542226..cd9eb34f8d11 100644 > --- a/arch/riscv/kernel/cpufeature.c > +++ b/arch/riscv/kernel/cpufeature.c > @@ -119,9 +119,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; > - /* ... but must be ignored. */ > + /* 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))) { > @@ -131,6 +150,7 @@ void __init riscv_fill_hwcap(void) > /* Find next extension */ > if (!isdigit(*isa)) > break; > + /* Skip the minor version */ This comment should be moved to PATCH2 > while (isdigit(*++isa)) > ; > if (*isa != 'p') > @@ -139,20 +159,20 @@ void __init riscv_fill_hwcap(void) > --isa; > break; > } > + /* Skip the major version */ Same applies to this comment as well. > while (isdigit(*++isa)) > ; > break; > } > 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.30.2 > Otherwise it looks good to me. Reviewed-by: Anup Patel <anup@brainfault.org> Regards, Anup
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 9d5448542226..cd9eb34f8d11 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -119,9 +119,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; - /* ... but must be ignored. */ + /* 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))) { @@ -131,6 +150,7 @@ void __init riscv_fill_hwcap(void) /* Find next extension */ if (!isdigit(*isa)) break; + /* Skip the minor version */ while (isdigit(*++isa)) ; if (*isa != 'p') @@ -139,20 +159,20 @@ void __init riscv_fill_hwcap(void) --isa; break; } + /* Skip the major version */ while (isdigit(*++isa)) ; break; } 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')); + } } /*