diff mbox series

[RFC,v2,3/4] riscv: cpufeature: Extract extension names from "riscv, isa"

Message ID cb0f6782c7b7a3784335f0e4a461bb018ec7c72d.1637834060.git.research_trasio@irq.a4lg.com (mailing list archive)
State New, archived
Headers show
Series riscv: cpufeature: Improvements for extended feature handling | expand

Commit Message

Tsukasa OI Nov. 25, 2021, 10:02 a.m. UTC
It's possible that we only need extension names implemented but not
version numbers.  This commit doesn't parse version numbers but does
extract implemented extension names.

`ext_end-1` points at the last character of the extension name and
`ext_end-ext` is the length of the extension name.

Beware that the extension name is **not** null-terminated.

Signed-off-by: Tsukasa OI <research_trasio@irq.a4lg.com>
---
 arch/riscv/kernel/cpufeature.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 93b436addd90..61bc326d15b0 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;
 			unsigned short ext_err = 0;
 			bool ext_long;
 
@@ -115,7 +116,21 @@  void __init riscv_fill_hwcap(void)
 				for (; *isa && *isa != '_'; ++isa)
 					if (!islower(*isa) && !isdigit(*isa))
 						ext_err = 1;
-				/* ... but must be ignored. */
+				/* Find end of the extension name backwards */
+				ext_end = isa;
+				if (ext_err)
+					break;
+				if (!isdigit(ext_end[-1]))
+					break;
+				while (isdigit(*--ext_end))
+					;
+				if (ext_end[0] != 'p'
+				    || !isdigit(ext_end[-1])) {
+					++ext_end;
+					break;
+				}
+				while (isdigit(*--ext_end))
+					;
 				break;
 			default:
 				ext_long = false;
@@ -144,7 +159,7 @@  void __init riscv_fill_hwcap(void)
 			 * TODO: Full version-aware handling including
 			 * multi-letter extensions will be added in-future.
 			 */
-			if (!ext_long && !ext_err) {
+			if (!ext_err) {
 				this_hwcap |= isa2hwcap[(unsigned char)(*ext)];
 				if (!ext_long)
 					this_isa |= (1UL << (*ext - 'a'));