[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220210214018.55739-4-atishp@rivosinc.com>
Date: Thu, 10 Feb 2022 13:40:15 -0800
From: Atish Patra <atishp@...osinc.com>
To: linux-kernel@...r.kernel.org
Cc: Tsukasa OI <research_trasio@....a4lg.com>,
Atish Patra <atishp@...osinc.com>,
Albert Ou <aou@...s.berkeley.edu>,
Atish Patra <atishp@...shpatra.org>,
Anup Patel <anup@...infault.org>,
Damien Le Moal <damien.lemoal@....com>,
devicetree@...r.kernel.org, Jisheng Zhang <jszhang@...nel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski@...onical.com>,
linux-riscv@...ts.infradead.org,
Palmer Dabbelt <palmer@...belt.com>,
Paul Walmsley <paul.walmsley@...ive.com>,
Rob Herring <robh+dt@...nel.org>
Subject: [PATCH v2 3/6] RISC-V: Extract multi-letter extension names from "riscv,isa"
From: Tsukasa OI <research_trasio@....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@....a4lg.com>
[Improved commit text and comments]
Signed-off-by: Atish Patra <atishp@...osinc.com>
---
arch/riscv/kernel/cpufeature.c | 41 +++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 10 deletions(-)
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index e19ae4391a9b..e9e3b0693d16 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -102,6 +102,7 @@ void __init riscv_fill_hwcap(void)
#endif
for (; *isa; ++isa) {
const char *ext = isa++;
+ const char *ext_end = isa;
bool ext_long, ext_err = false;
switch (*ext) {
@@ -119,19 +120,39 @@ 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:
ext_long = false;
- if (!islower(*ext)) {
+ if (unlikely(!islower(*ext))) {
ext_err = true;
break;
}
/* Find next extension */
if (!isdigit(*isa))
break;
+ /* Skip the minor version */
while (isdigit(*++isa))
;
if (*isa != 'p')
@@ -140,20 +161,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'));
+ }
}
/*
--
2.30.2
Powered by blists - more mailing lists