* [PATCH v2 0/7] ISA based RISC-V tune implementation
@ 2025-06-17 23:39 Mark Hatle
2025-06-17 23:39 ` [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features Mark Hatle
` (7 more replies)
0 siblings, 8 replies; 16+ messages in thread
From: Mark Hatle @ 2025-06-17 23:39 UTC (permalink / raw)
To: openembedded-core
From: Mark Hatle <mark.hatle@amd.com>
The following implements the risc-v processor tune based on the ISA approach
as documented in the oe-architecture post:
https://lists.openembedded.org/g/openembedded-architecture/message/2155
This set also attempts to make u-boot and kernel configurations dynamic
based on the TUNE_FEATURES.
For the linux-yocto, I suspect that the config fragments should be
sent to the kmeta (kernel-cache), but I'd like a review from Bruce and
others before I do this.
Additionally, this enables a new (optional) features_check for TUNE_FEATURES.
I've found numerous items in the system have certain RISC-V ISA expectations
that may need to be addressed over time, however the obvious one is the
Linux kernel requires ima_zicsr_zifencei. Since it has it's own -march=
setting this will ensure the processor defintion will be compatible.
Also dynamically configure the QEMU cpu based on the tune_features. This
is nice to ensure that what we're actually building should be able to run
on real hardware. However, it does highlight some of the (extension)
limitations in the current design. (limitations as in extension not yet
enabled.)
Note: OpenSBI _requires_ the 'c' extension or it will not execute. I
suspect this can be fixed, but it's beyond my capabilities at this time.
v2:
- Note: the linux-yocto change still needs further rework (noted in commit)
(if everything else is merged, it will still work fine)
- Change the TUNE_FEATURES check to kernel.bbclass per review comments
- Add 7/7 patch for RUST configuration.
Mark Hatle (7):
riscv tunes: ISA Implementation of RISC-V tune features
linux-yocto: Enable risc-v TUNE_FEATURES ISA selections ** DO NOT
MERGE **
u-boot: Dynamic RISC-V ISA configuration
qemuriscv: Dynamically configure qemu CPU
features_check.bbclass: Add support for required TUNE_FEATURES
kernel.bbclass: State riscv required tune_features for Linux
rust-target-config.bbclass: Update for new riscv TUNE_FEATURES
meta/classes-recipe/features_check.bbclass | 2 +-
meta/classes-recipe/kernel.bbclass | 6 +-
.../classes-recipe/rust-target-config.bbclass | 65 ++++++---
meta/conf/machine/include/riscv/README | 122 ++++++++++++++++
.../conf/machine/include/riscv/arch-riscv.inc | 138 +++++++++++++++++-
meta/conf/machine/include/riscv/qemuriscv.inc | 31 +++-
.../conf/machine/include/riscv/tune-riscv.inc | 40 ++---
meta/conf/machine/qemuriscv32.conf | 4 +-
meta/lib/oe/__init__.py | 2 +-
meta/lib/oe/rust.py | 2 -
meta/lib/oe/tune.py | 81 ++++++++++
.../u-boot/files/u-boot-riscv-isa_a.cfg | 1 +
.../u-boot/files/u-boot-riscv-isa_c.cfg | 1 +
.../u-boot/files/u-boot-riscv-isa_clear.cfg | 6 +
.../u-boot/files/u-boot-riscv-isa_d.cfg | 1 +
.../u-boot/files/u-boot-riscv-isa_f.cfg | 1 +
.../u-boot/files/u-boot-riscv-isa_zbb.cfg | 1 +
.../u-boot/files/u-boot-riscv-isa_zicbom.cfg | 1 +
meta/recipes-bsp/u-boot/u-boot-common.inc | 12 ++
.../linux/files/risc-v-isa-c.cfg | 1 +
.../linux/files/risc-v-isa-clear.cfg | 9 ++
.../linux/files/risc-v-isa-fpu.cfg | 1 +
.../linux/files/risc-v-isa-rv32i.cfg | 2 +
.../linux/files/risc-v-isa-rv64i.cfg | 2 +
.../linux/files/risc-v-isa-v.cfg | 1 +
.../linux/files/risc-v-isa-zbb.cfg | 1 +
.../linux/files/risc-v-isa-zicbom.cfg | 1 +
meta/recipes-kernel/linux/linux-yocto.inc | 14 ++
28 files changed, 480 insertions(+), 69 deletions(-)
create mode 100644 meta/conf/machine/include/riscv/README
create mode 100644 meta/lib/oe/tune.py
create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_a.cfg
create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_c.cfg
create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_clear.cfg
create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_d.cfg
create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_f.cfg
create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zbb.cfg
create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zicbom.cfg
create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-c.cfg
create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-clear.cfg
create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-fpu.cfg
create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-rv32i.cfg
create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-rv64i.cfg
create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-v.cfg
create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-zbb.cfg
create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-zicbom.cfg
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features 2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle @ 2025-06-17 23:39 ` Mark Hatle 2025-06-18 4:00 ` [OE-core] " Alistair Francis 2025-06-17 23:39 ` [PATCH v2 2/7] linux-yocto: Enable risc-v TUNE_FEATURES ISA selections ** DO NOT MERGE ** Mark Hatle ` (6 subsequent siblings) 7 siblings, 1 reply; 16+ messages in thread From: Mark Hatle @ 2025-06-17 23:39 UTC (permalink / raw) To: openembedded-core From: Mark Hatle <mark.hatle@amd.com> This implements the following base ISAs: * rv32i, rv64i * rv32e, rv64i The following ABIs: * ilp32, ilp32e, ilp32f, ilp32d * lp64, lp64e, lp64f, lp64d The following ISA extension are also implemented: * M - Integer Multiplication and Division Extension * A - Atomic Memory Extension * F - Single-Precision Floating-Point Extension * D - Double-Precision Floating-Point Extension * C - Compressed Extension * B - Bit Manipulation Extension (implies Zba, Zbb, Zbs) * V - Vector Operations Extension * Zicsr - Control and Status Register Access Extension * Zifencei - Instruction-Fetch Fence Extension * Zba - Address bit manipulation extension * Zbb - Basic bit manipulation extension * Zbc - Carry-less multiplication extension * Zbs - Single-bit manipulation extension * Zicbom - Cache-block management extension The existing processors tunes are preserved: * riscv64 (rv64gc) * riscv32 (rv32gc) * riscv64nf (rv64imac_zicsr_zifencei) * riscv32nf (rv32imac_zicsr_zifencei) * riscv64nc (rv64imafd_zicsr_zifencei) Previously defined feature 'big-endian' has been removed as it was not used. Signed-off-by: Mark Hatle <mark.hatle@amd.com> --- meta/conf/machine/include/riscv/README | 122 ++++++++++++++++ .../conf/machine/include/riscv/arch-riscv.inc | 138 +++++++++++++++++- .../conf/machine/include/riscv/tune-riscv.inc | 40 ++--- meta/conf/machine/qemuriscv32.conf | 4 +- meta/lib/oe/__init__.py | 2 +- meta/lib/oe/tune.py | 81 ++++++++++ 6 files changed, 349 insertions(+), 38 deletions(-) create mode 100644 meta/conf/machine/include/riscv/README create mode 100644 meta/lib/oe/tune.py diff --git a/meta/conf/machine/include/riscv/README b/meta/conf/machine/include/riscv/README new file mode 100644 index 0000000000..beef68f523 --- /dev/null +++ b/meta/conf/machine/include/riscv/README @@ -0,0 +1,122 @@ +2025/06/08 - Mark Hatle <mark.hatle@amd.com> + - Initial Revision + +The RISC-V ISA is broken into two parts, a base ISA and extensions. As +of the writing of this document these are documented at: + +https://lf-riscv.atlassian.net/wiki/spaces/HOME/pages/16154769/RISC-V+Technical+Specifications + +Specifically "The RISC-V Instruction Set Manual Volume I: Unprivileged ISA" +was used to create this implementation. + +Requirements +------------ +As RISC-V is a “variable” ISA (a base isa plus numerous extensions), a +mechanism is required to specify a series of ISA features that a user or +tune can use to specify a specific CPU instantiation. + +Not all ratified or draft features should or can be implemented with the +available resources. + +The implementation should work for Linux, baremetal (newlib), zephyr and +other operating systems. Supported extensions should be based on +real-world examples. + +Linux +----- +Linux required base and support extensions should be available. Linux +requires: +* Base: rv32ima & rv64ima +* Optional FPU: fd +* Optional RISCV_ISA_C: c +* Optiona RISCV_ISA_V: v +* Required additional: _zicsr_zifencei +* Optional RISCV_ISA_ZBA: _zba +* Optional RISCV_ISA_ZBB: _zbb +* Optional RISCV_ISA_ZBC: _zbc (not supported by current QEMU design) + +See: https://git.yoctoproject.org/linux-yocto/tree/arch/riscv/Makefile?h=v6.12/base + +Baremetal +--------- +AMD Microblaze-V FPGA support uses the following static configurations: +Base: rv32e, rv32i, rv64i +Extensions: m, a, f, d, c, b, zicsr, zifencei + +Zephyr +------ +AMD Microblaze-V development for Zephyr is the same as Baremetal, with a +few additional extensions: zbc, zicbom + +ABI +--- +The following ABIs are supported GNU tools and some combination of systems. +* ilp32 - Integer, long and pointer are 32-bit +* lp64 - Long and pointer are 64-bit (integer is 32-bit) + +The ABI is dependent upon the core system implementation, as ilp32 can +only used on an ‘rv32’ system, while lp64 can only be used on an ‘rv64’ +system. + +There are additional variations of each ABI: +* e - used with the Reduced register extension +* f - used when single precision floating point (but not double precision) is + enabled +* d - used when both single and double precision floating point is enabled + +Based on the above, the ABI should be automatically determined based on +the selected Base ISA and Extensions. + +Implementation +-------------- +To make it easier to generate the RISC-V canonical arch, ISA based -march, +and the ABI string, a few new variables are added for specific RISC-V items. + +TUNE_RISCV_ARCH - This contains the canonical GNU style arch, generally this + will evaluate to "riscv32" or "riscv64". + +TUNE_RISCV_MARCH - This will contain an ISA based -march string compatible + with gcc and similar toolchains. For example: + rv32imacfd_zicsr_zifencei + +TUNE_RISCV_ABI - This is the generated ABI that corresponds to the ARCH and + MARCH/ISA values. For riscv32, the value will be ilp32 + (int, long and pointer is 32-bit) with the ISA + variation. For riscv64, the value will be lp64 (long + and pointer are 64-bit bit, while int is 32-bit) with the + ISA variation. The ISA affects the ABI when the 'e', 'f' + and 'd' extension are used. + +TUNE_RISCV_PKGARCH - This is the generated PKGARCH value. + +The standard variables are defined as: + +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}" + +The above will allow the user to specify an implementation specific +TUNE_CCARGS for a given processor tune if the default implementtion is +not adequate for some reason. It is expected that most, if not all, +implementations will use the default behavior. + +TUNE_ARCH = "${TUNE_RISCV_ARCH}" +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}" + +The above two will always base their setting off the standard TUNE_FEATURES. + +Ratified and draft extensions should be implemented as TUNE_FEATURES in +the arch-riscv.inc file. + +Vendor specific extensions and processor specific settings should go +into a 'tune-<vendor>.inc' file, with tune-riscv.inc being reserved for +general purpose tunes. + +TUNE_FEATURE Helper +------------------- +A special helper function has been written that will convert RISC-V ISA +notation into TUNE_FEATURE notion, for example: + +rv32g -> rv 32 i m a f d zicsr zifencei + +The helper can be called using oe.tune.riscv_isa_to_tune("<ISA>") such as +oe.tune.riscv_isa_to_tune("rv64gc") which would return: + rv 64 i m a f d c zicsr zifencei diff --git a/meta/conf/machine/include/riscv/arch-riscv.inc b/meta/conf/machine/include/riscv/arch-riscv.inc index b34064e78f..99bed8fde5 100644 --- a/meta/conf/machine/include/riscv/arch-riscv.inc +++ b/meta/conf/machine/include/riscv/arch-riscv.inc @@ -1,14 +1,140 @@ # RISCV Architecture definition -DEFAULTTUNE ?= "riscv64" +# Based on the RISC-V Instruction Set Manual Volume I: Unprivileged ISA from May 2025 +# As well as the RISC-V options for using GCC (as of June 2025) -TUNE_ARCH = "${TUNE_ARCH:tune-${DEFAULTTUNE}}" -TUNE_PKGARCH = "${TUNE_PKGARCH:tune-${DEFAULTTUNE}}" -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nf', ' -mabi=lp64', ' ', d)}" -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv32nf', ' -mabi=ilp32', ' ', d)}" +# Note: the following should be implemented in the order that GCC expects +# -march= values to be defined in. -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nc', ' -march=rv64imafd', ' ', d)}" +# Base ISA +# All supported march strings must start with rv32 or rv64 +TUNEVALID[rv] = "RISC-V" +TUNE_RISCV_ARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "riscv", "", d)}" +TUNE_RISCV_MARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "rv", "", d)}" +TUNE_RISCV_ABI = "" +# There are two primary ABIs, ilp32 and lp64 +# There are variants of both, that appears to be based on extensions above +# For example: +# rv32i uses ilp32, rv32e uses ilp32e, rv32f uses ilp32f +# rv64i uses lp64, rv64if uses lp64f, rv64id uses lp64d +TUNEVALID[32] = "ISA XLEN - 32-bit" +TUNECONFLICTS[32] = "64" +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}" +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "32", "ilp32", "", d)}" + +TUNEVALID[64] = "ISA XLEN - 64-bit" +TUNECONFLICTS[64] = "32" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}" +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}" +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "64", "lp64", "", d)}" + +# The package arch starts with the canonical arch, but adds some extensions to make +# package compatibility clear +TUNE_RISCV_PKGARCH = "${TUNE_RISCV_ARCH}" + +# i, e, or g are defined by gcc, but 'g' refers to 'i' + extensions 'MAFD Zicsr Zifencei' +# So 'g' will not be defined here as it is an abbreviation of the expanded version +TUNEVALID[e] = "Reduced register base integer extension" +TUNECONFLICTS[e] = "i" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" + +TUNEVALID[i] = "Base integer extension" +TUNECONFLICTS[i] = "e" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}" + +# Extensions +TUNEVALID[m] = "Integer multiplication and division extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}" + +TUNEVALID[a] = "Atomic extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}" + +TUNEVALID[f] = "Single-precision floating-point extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}" + +TUNEVALID[d] = "Double-precision floating-point extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}" + +# Only f OR d, but just one +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", bb.utils.contains("TUNE_FEATURES", "f", "f", "", d), d)}" + +TUNEVALID[c] = "Compressed extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}" + +TUNEVALID[b] = "Bit Manipulation extension" +# Handled below via zba, zbb, zbs +# This matches current Linux kernel behavior +#TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}" +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}" + +TUNEVALID[v] = "Vector operations extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}" + +# Now the special Z extensions +TUNEVALID[zicbom] = "Cache-block management extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}" + +TUNEVALID[zicsr] = "Control and status register access extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}" +# If zicsr (or zifencei) is in the path, OpenSBI fails to use the extensions, do to (Makefile): +# # Check whether the assembler and the compiler support the Zicsr and Zifencei extensions +# CC_SUPPORT_ZICSR_ZIFENCEI := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)imafd_zicsr_zifencei -x c /dev/null -o /dev/null 2>&1 | grep -e "zicsr" -e "zifencei" > /dev/null && echo n || echo y) +# this will match on the path containing zicsr or zifencei when an error is reported, which +# will always happens in this check. +# +# Yocto Project Bugzilla 15897 +# +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}" + +TUNEVALID[zifencei] = "Instruction-fetch fence extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}" +# See above Bug 15897 +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}" + +TUNEVALID[zba] = "Address bit manipulation extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}" + +TUNEVALID[zbb] = "Basic bit manipulation extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}" + +TUNEVALID[zbc] = "Carry-less multiplication extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}" + +TUNEVALID[zbs] = "Single-bit manipulation extension" +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}" +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}" + +# Construct TUNE_CCARGS +# This should result in a CCARG similar to: +# -march=rv32imac -mabi=ilp32 +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}" + +# Construct TUNE_ARCH +# This should result in an arch string similar to: +# riscv32 +TUNE_ARCH = "${TUNE_RISCV_ARCH}" + +# Construct TUNE_PKGARCH +# This should result in a package are like: +# riscv32imac +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}" + +# Misc settings # Fix: ld: unrecognized option '--hash-style=sysv' LINKER_HASH_STYLE:libc-newlib = "" LINKER_HASH_STYLE:libc-picolibc = "" diff --git a/meta/conf/machine/include/riscv/tune-riscv.inc b/meta/conf/machine/include/riscv/tune-riscv.inc index 804712077e..12c1125c8b 100644 --- a/meta/conf/machine/include/riscv/tune-riscv.inc +++ b/meta/conf/machine/include/riscv/tune-riscv.inc @@ -1,41 +1,23 @@ require conf/machine/include/riscv/arch-riscv.inc -TUNEVALID[riscv64] = "Enable 64-bit RISC-V optimizations" -TUNEVALID[riscv32] = "Enable 32-bit RISC-V optimizations" - -TUNEVALID[riscv64nf] = "Enable 64-bit RISC-V optimizations no floating point" -TUNEVALID[riscv32nf] = "Enable 32-bit RISC-V optimizations no floating point" - -TUNEVALID[riscv64nc] = "Enable 64-bit RISC-V optimizations without compressed instructions" - -TUNEVALID[bigendian] = "Big endian mode" +DEFAULTTUNE ?= "riscv64" AVAILTUNES += "riscv64 riscv32 riscv64nc riscv64nf riscv32nf" # Default -TUNE_FEATURES:tune-riscv64 = "riscv64" -TUNE_ARCH:tune-riscv64 = "riscv64" -TUNE_PKGARCH:tune-riscv64 = "riscv64" -PACKAGE_EXTRA_ARCHS:tune-riscv64 = "riscv64" +TUNE_FEATURES:tune-riscv64 := "${@oe.tune.riscv_isa_to_tune("rv64gc")}" +PACKAGE_EXTRA_ARCHS:tune-riscv64 = "${TUNE_RISCV_PKGARCH}" -TUNE_FEATURES:tune-riscv32 = "riscv32" -TUNE_ARCH:tune-riscv32 = "riscv32" -TUNE_PKGARCH:tune-riscv32 = "riscv32" -PACKAGE_EXTRA_ARCHS:tune-riscv32 = "riscv32" +TUNE_FEATURES:tune-riscv32 := "${@oe.tune.riscv_isa_to_tune("rv32gc")}" +PACKAGE_EXTRA_ARCHS:tune-riscv32 = "${TUNE_RISCV_PKGARCH}" # No float -TUNE_FEATURES:tune-riscv64nf = "${TUNE_FEATURES:tune-riscv64} riscv64nf" -TUNE_ARCH:tune-riscv64nf = "riscv64" -TUNE_PKGARCH:tune-riscv64nf = "riscv64nf" -PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "riscv64nf" +TUNE_FEATURES:tune-riscv64nf := "${@oe.tune.riscv_isa_to_tune("rv64imac_zicsr_zifencei")}" +PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "${TUNE_RISCV_PKGARCH}" -TUNE_FEATURES:tune-riscv32nf = "${TUNE_FEATURES:tune-riscv32} riscv32nf" -TUNE_ARCH:tune-riscv32nf = "riscv32" -TUNE_PKGARCH:tune-riscv32nf = "riscv32nf" -PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "riscv32nf" +TUNE_FEATURES:tune-riscv32nf := "${@oe.tune.riscv_isa_to_tune("rv32imac_zicsr_zifencei")}" +PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "${TUNE_RISCV_PKGARCH}" # no compressed -TUNE_FEATURES:tune-riscv64nc = "${TUNE_FEATURES:tune-riscv64} riscv64nc" -TUNE_ARCH:tune-riscv64nc = "riscv64" -TUNE_PKGARCH:tune-riscv64nc = "riscv64nc" -PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "riscv64nc" +TUNE_FEATURES:tune-riscv64nc := "${@oe.tune.riscv_isa_to_tune("rv64imafd_zicsr_zifencei")}" +PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "${TUNE_RISCV_PKGARCH}" diff --git a/meta/conf/machine/qemuriscv32.conf b/meta/conf/machine/qemuriscv32.conf index d3858dc051..aff36c28a5 100644 --- a/meta/conf/machine/qemuriscv32.conf +++ b/meta/conf/machine/qemuriscv32.conf @@ -2,9 +2,9 @@ #@NAME: generic riscv32 machine #@DESCRIPTION: Machine configuration for running a generic riscv32 -require conf/machine/include/riscv/qemuriscv.inc +DEFAULTTUNE ?= "riscv32" -DEFAULTTUNE = "riscv32" +require conf/machine/include/riscv/qemuriscv.inc PREFERRED_VERSION_openocd-native = "riscv" PREFERRED_VERSION_openocd = "riscv" diff --git a/meta/lib/oe/__init__.py b/meta/lib/oe/__init__.py index dd094a874a..73de774266 100644 --- a/meta/lib/oe/__init__.py +++ b/meta/lib/oe/__init__.py @@ -12,4 +12,4 @@ __path__ = extend_path(__path__, __name__) BBIMPORTS = ["qa", "data", "path", "utils", "types", "package", "packagedata", \ "packagegroup", "sstatesig", "lsb", "cachedpath", "license", "qemu", \ "reproducible", "rust", "buildcfg", "go", "spdx30_tasks", "spdx_common", \ - "cve_check"] + "cve_check", "tune"] diff --git a/meta/lib/oe/tune.py b/meta/lib/oe/tune.py new file mode 100644 index 0000000000..7fda19430d --- /dev/null +++ b/meta/lib/oe/tune.py @@ -0,0 +1,81 @@ +# +# Copyright OpenEmbedded Contributors +# +# SPDX-License-Identifier: GPL-2.0-only +# + +# riscv_isa_to_tune(isa) +# +# Automatically translate a RISC-V ISA string to TUNE_FEATURES +# +# Abbreviations, such as rv32g -> rv32imaffd_zicsr_zifencei are supported. +# +# Profiles, such as rva22u64, are NOT supported, you must use ISA strings. +# +def riscv_isa_to_tune(isa): + _isa = isa.lower() + + feature = [] + iter = 0 + + # rv or riscv + if _isa[iter:].startswith('rv'): + feature.append('rv') + iter = iter + 2 + elif _isa[iter:].startswith('riscv'): + feature.append('rv') + iter = iter + 5 + else: + # Not a risc-v ISA! + return _isa + + while (_isa[iter:]): + # Skip _ and whitespace + if _isa[iter] == '_' or _isa[iter].isspace(): + iter = iter + 1 + continue + + # Length, just capture numbers here + if _isa[iter].isdigit(): + iter_end = iter + while iter_end < len(_isa) and _isa[iter_end].isdigit(): + iter_end = iter_end + 1 + + feature.append(_isa[iter:iter_end]) + iter = iter_end + continue + + # Typically i, e or g is next, followed by extensions. + # Extensions are single character, except for Z, Ss, Sh, Sm, Sv, and X + + # If the extension starts with 'Z', 'S' or 'X' use the name until the next _, whitespace or end + if _isa[iter] in ['z', 's', 'x']: + ext_type = _isa[iter] + iter_end = iter + 1 + + # Multicharacter extension, these are supposed to have a _ before the next multicharacter extension + # See 37.4 and 37.5: + # 37.4: Underscores "_" may be used to separate ISA extensions... + # 37.5: All multi-letter extensions ... must be separated from other multi-letter extensions by an underscore... + # Some extensions permit only alphabetic characters, while others allow alphanumeric chartacters + while iter_end < len(_isa) and _isa[iter_end] != "_" and not _isa[iter_end].isspace(): + iter_end = iter_end + 1 + + feature.append(_isa[iter:iter_end]) + iter = iter_end + continue + + # 'g' is special, it's an abbreviation for imafd_zicsr_zifencei + # When expanding the abbreviation, any additional letters must appear before the _z* extensions + if _isa[iter] == 'g': + _isa = 'imafd' + _isa[iter+1:] + '_zicsr_zifencei' + iter = 0 + continue + + feature.append(_isa[iter]) + iter = iter + 1 + continue + + # Eliminate duplicates, but preserve the order + feature = list(dict.fromkeys(feature)) + return ' '.join(feature) -- 2.34.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [OE-core] [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features 2025-06-17 23:39 ` [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features Mark Hatle @ 2025-06-18 4:00 ` Alistair Francis 2025-06-18 14:12 ` Mark Hatle [not found] ` <184A2891E949D242.11882@lists.openembedded.org> 0 siblings, 2 replies; 16+ messages in thread From: Alistair Francis @ 2025-06-18 4:00 UTC (permalink / raw) To: mark.hatle; +Cc: openembedded-core On Wed, Jun 18, 2025 at 9:39 AM Mark Hatle via lists.openembedded.org <mark.hatle=kernel.crashing.org@lists.openembedded.org> wrote: > > From: Mark Hatle <mark.hatle@amd.com> > > This implements the following base ISAs: > > * rv32i, rv64i > * rv32e, rv64i > > The following ABIs: > * ilp32, ilp32e, ilp32f, ilp32d > * lp64, lp64e, lp64f, lp64d > > The following ISA extension are also implemented: > * M - Integer Multiplication and Division Extension > * A - Atomic Memory Extension > * F - Single-Precision Floating-Point Extension > * D - Double-Precision Floating-Point Extension > * C - Compressed Extension > * B - Bit Manipulation Extension (implies Zba, Zbb, Zbs) > * V - Vector Operations Extension > * Zicsr - Control and Status Register Access Extension > * Zifencei - Instruction-Fetch Fence Extension > * Zba - Address bit manipulation extension > * Zbb - Basic bit manipulation extension > * Zbc - Carry-less multiplication extension > * Zbs - Single-bit manipulation extension > * Zicbom - Cache-block management extension > > The existing processors tunes are preserved: > * riscv64 (rv64gc) > * riscv32 (rv32gc) > * riscv64nf (rv64imac_zicsr_zifencei) > * riscv32nf (rv32imac_zicsr_zifencei) > * riscv64nc (rv64imafd_zicsr_zifencei) I'm not sure this is the way we want to handle this. You are picking and choosing each individual extension, which is difficult for users to do. Not to mention it's easy to get wrong as some extensions conflict with other extensions. You also end up using the `rv32` or `rv64` CPUs with QEMU and enabling extensions manually. We will probably remove those CPUs from QEMU in the future as they cause a lot of user confusion. I think instead we should be moving towards the RISC-V profiles. Individual extensions can still be enabled/disabled on top of a profile if required. That's what we are doing in QEMU and it makes things a lot clearer to users exactly what is/isn't enabled. Alistair > > Previously defined feature 'big-endian' has been removed as it was not used. > > Signed-off-by: Mark Hatle <mark.hatle@amd.com> > --- > meta/conf/machine/include/riscv/README | 122 ++++++++++++++++ > .../conf/machine/include/riscv/arch-riscv.inc | 138 +++++++++++++++++- > .../conf/machine/include/riscv/tune-riscv.inc | 40 ++--- > meta/conf/machine/qemuriscv32.conf | 4 +- > meta/lib/oe/__init__.py | 2 +- > meta/lib/oe/tune.py | 81 ++++++++++ > 6 files changed, 349 insertions(+), 38 deletions(-) > create mode 100644 meta/conf/machine/include/riscv/README > create mode 100644 meta/lib/oe/tune.py > > diff --git a/meta/conf/machine/include/riscv/README b/meta/conf/machine/include/riscv/README > new file mode 100644 > index 0000000000..beef68f523 > --- /dev/null > +++ b/meta/conf/machine/include/riscv/README > @@ -0,0 +1,122 @@ > +2025/06/08 - Mark Hatle <mark.hatle@amd.com> > + - Initial Revision > + > +The RISC-V ISA is broken into two parts, a base ISA and extensions. As > +of the writing of this document these are documented at: > + > +https://lf-riscv.atlassian.net/wiki/spaces/HOME/pages/16154769/RISC-V+Technical+Specifications > + > +Specifically "The RISC-V Instruction Set Manual Volume I: Unprivileged ISA" > +was used to create this implementation. > + > +Requirements > +------------ > +As RISC-V is a “variable” ISA (a base isa plus numerous extensions), a > +mechanism is required to specify a series of ISA features that a user or > +tune can use to specify a specific CPU instantiation. > + > +Not all ratified or draft features should or can be implemented with the > +available resources. > + > +The implementation should work for Linux, baremetal (newlib), zephyr and > +other operating systems. Supported extensions should be based on > +real-world examples. > + > +Linux > +----- > +Linux required base and support extensions should be available. Linux > +requires: > +* Base: rv32ima & rv64ima > +* Optional FPU: fd > +* Optional RISCV_ISA_C: c > +* Optiona RISCV_ISA_V: v > +* Required additional: _zicsr_zifencei > +* Optional RISCV_ISA_ZBA: _zba > +* Optional RISCV_ISA_ZBB: _zbb > +* Optional RISCV_ISA_ZBC: _zbc (not supported by current QEMU design) > + > +See: https://git.yoctoproject.org/linux-yocto/tree/arch/riscv/Makefile?h=v6.12/base > + > +Baremetal > +--------- > +AMD Microblaze-V FPGA support uses the following static configurations: > +Base: rv32e, rv32i, rv64i > +Extensions: m, a, f, d, c, b, zicsr, zifencei > + > +Zephyr > +------ > +AMD Microblaze-V development for Zephyr is the same as Baremetal, with a > +few additional extensions: zbc, zicbom > + > +ABI > +--- > +The following ABIs are supported GNU tools and some combination of systems. > +* ilp32 - Integer, long and pointer are 32-bit > +* lp64 - Long and pointer are 64-bit (integer is 32-bit) > + > +The ABI is dependent upon the core system implementation, as ilp32 can > +only used on an ‘rv32’ system, while lp64 can only be used on an ‘rv64’ > +system. > + > +There are additional variations of each ABI: > +* e - used with the Reduced register extension > +* f - used when single precision floating point (but not double precision) is > + enabled > +* d - used when both single and double precision floating point is enabled > + > +Based on the above, the ABI should be automatically determined based on > +the selected Base ISA and Extensions. > + > +Implementation > +-------------- > +To make it easier to generate the RISC-V canonical arch, ISA based -march, > +and the ABI string, a few new variables are added for specific RISC-V items. > + > +TUNE_RISCV_ARCH - This contains the canonical GNU style arch, generally this > + will evaluate to "riscv32" or "riscv64". > + > +TUNE_RISCV_MARCH - This will contain an ISA based -march string compatible > + with gcc and similar toolchains. For example: > + rv32imacfd_zicsr_zifencei > + > +TUNE_RISCV_ABI - This is the generated ABI that corresponds to the ARCH and > + MARCH/ISA values. For riscv32, the value will be ilp32 > + (int, long and pointer is 32-bit) with the ISA > + variation. For riscv64, the value will be lp64 (long > + and pointer are 64-bit bit, while int is 32-bit) with the > + ISA variation. The ISA affects the ABI when the 'e', 'f' > + and 'd' extension are used. > + > +TUNE_RISCV_PKGARCH - This is the generated PKGARCH value. > + > +The standard variables are defined as: > + > +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}" > + > +The above will allow the user to specify an implementation specific > +TUNE_CCARGS for a given processor tune if the default implementtion is > +not adequate for some reason. It is expected that most, if not all, > +implementations will use the default behavior. > + > +TUNE_ARCH = "${TUNE_RISCV_ARCH}" > +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}" > + > +The above two will always base their setting off the standard TUNE_FEATURES. > + > +Ratified and draft extensions should be implemented as TUNE_FEATURES in > +the arch-riscv.inc file. > + > +Vendor specific extensions and processor specific settings should go > +into a 'tune-<vendor>.inc' file, with tune-riscv.inc being reserved for > +general purpose tunes. > + > +TUNE_FEATURE Helper > +------------------- > +A special helper function has been written that will convert RISC-V ISA > +notation into TUNE_FEATURE notion, for example: > + > +rv32g -> rv 32 i m a f d zicsr zifencei > + > +The helper can be called using oe.tune.riscv_isa_to_tune("<ISA>") such as > +oe.tune.riscv_isa_to_tune("rv64gc") which would return: > + rv 64 i m a f d c zicsr zifencei > diff --git a/meta/conf/machine/include/riscv/arch-riscv.inc b/meta/conf/machine/include/riscv/arch-riscv.inc > index b34064e78f..99bed8fde5 100644 > --- a/meta/conf/machine/include/riscv/arch-riscv.inc > +++ b/meta/conf/machine/include/riscv/arch-riscv.inc > @@ -1,14 +1,140 @@ > # RISCV Architecture definition > > -DEFAULTTUNE ?= "riscv64" > +# Based on the RISC-V Instruction Set Manual Volume I: Unprivileged ISA from May 2025 > +# As well as the RISC-V options for using GCC (as of June 2025) > > -TUNE_ARCH = "${TUNE_ARCH:tune-${DEFAULTTUNE}}" > -TUNE_PKGARCH = "${TUNE_PKGARCH:tune-${DEFAULTTUNE}}" > -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nf', ' -mabi=lp64', ' ', d)}" > -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv32nf', ' -mabi=ilp32', ' ', d)}" > +# Note: the following should be implemented in the order that GCC expects > +# -march= values to be defined in. > > -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nc', ' -march=rv64imafd', ' ', d)}" > +# Base ISA > +# All supported march strings must start with rv32 or rv64 > +TUNEVALID[rv] = "RISC-V" > +TUNE_RISCV_ARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "riscv", "", d)}" > +TUNE_RISCV_MARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "rv", "", d)}" > +TUNE_RISCV_ABI = "" > > +# There are two primary ABIs, ilp32 and lp64 > +# There are variants of both, that appears to be based on extensions above > +# For example: > +# rv32i uses ilp32, rv32e uses ilp32e, rv32f uses ilp32f > +# rv64i uses lp64, rv64if uses lp64f, rv64id uses lp64d > +TUNEVALID[32] = "ISA XLEN - 32-bit" > +TUNECONFLICTS[32] = "64" > +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}" > +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "32", "ilp32", "", d)}" > + > +TUNEVALID[64] = "ISA XLEN - 64-bit" > +TUNECONFLICTS[64] = "32" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}" > +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}" > +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "64", "lp64", "", d)}" > + > +# The package arch starts with the canonical arch, but adds some extensions to make > +# package compatibility clear > +TUNE_RISCV_PKGARCH = "${TUNE_RISCV_ARCH}" > + > +# i, e, or g are defined by gcc, but 'g' refers to 'i' + extensions 'MAFD Zicsr Zifencei' > +# So 'g' will not be defined here as it is an abbreviation of the expanded version > +TUNEVALID[e] = "Reduced register base integer extension" > +TUNECONFLICTS[e] = "i" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" > +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" > + > +TUNEVALID[i] = "Base integer extension" > +TUNECONFLICTS[i] = "e" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}" > + > +# Extensions > +TUNEVALID[m] = "Integer multiplication and division extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}" > + > +TUNEVALID[a] = "Atomic extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}" > + > +TUNEVALID[f] = "Single-precision floating-point extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}" > + > +TUNEVALID[d] = "Double-precision floating-point extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}" > + > +# Only f OR d, but just one > +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", bb.utils.contains("TUNE_FEATURES", "f", "f", "", d), d)}" > + > +TUNEVALID[c] = "Compressed extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}" > + > +TUNEVALID[b] = "Bit Manipulation extension" > +# Handled below via zba, zbb, zbs > +# This matches current Linux kernel behavior > +#TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}" > +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}" > + > +TUNEVALID[v] = "Vector operations extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}" > + > +# Now the special Z extensions > +TUNEVALID[zicbom] = "Cache-block management extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}" > + > +TUNEVALID[zicsr] = "Control and status register access extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}" > +# If zicsr (or zifencei) is in the path, OpenSBI fails to use the extensions, do to (Makefile): > +# # Check whether the assembler and the compiler support the Zicsr and Zifencei extensions > +# CC_SUPPORT_ZICSR_ZIFENCEI := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)imafd_zicsr_zifencei -x c /dev/null -o /dev/null 2>&1 | grep -e "zicsr" -e "zifencei" > /dev/null && echo n || echo y) > +# this will match on the path containing zicsr or zifencei when an error is reported, which > +# will always happens in this check. > +# > +# Yocto Project Bugzilla 15897 > +# > +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}" > + > +TUNEVALID[zifencei] = "Instruction-fetch fence extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}" > +# See above Bug 15897 > +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}" > + > +TUNEVALID[zba] = "Address bit manipulation extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}" > + > +TUNEVALID[zbb] = "Basic bit manipulation extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}" > + > +TUNEVALID[zbc] = "Carry-less multiplication extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}" > + > +TUNEVALID[zbs] = "Single-bit manipulation extension" > +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}" > +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}" > + > +# Construct TUNE_CCARGS > +# This should result in a CCARG similar to: > +# -march=rv32imac -mabi=ilp32 > +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}" > + > +# Construct TUNE_ARCH > +# This should result in an arch string similar to: > +# riscv32 > +TUNE_ARCH = "${TUNE_RISCV_ARCH}" > + > +# Construct TUNE_PKGARCH > +# This should result in a package are like: > +# riscv32imac > +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}" > + > +# Misc settings > # Fix: ld: unrecognized option '--hash-style=sysv' > LINKER_HASH_STYLE:libc-newlib = "" > LINKER_HASH_STYLE:libc-picolibc = "" > diff --git a/meta/conf/machine/include/riscv/tune-riscv.inc b/meta/conf/machine/include/riscv/tune-riscv.inc > index 804712077e..12c1125c8b 100644 > --- a/meta/conf/machine/include/riscv/tune-riscv.inc > +++ b/meta/conf/machine/include/riscv/tune-riscv.inc > @@ -1,41 +1,23 @@ > require conf/machine/include/riscv/arch-riscv.inc > > -TUNEVALID[riscv64] = "Enable 64-bit RISC-V optimizations" > -TUNEVALID[riscv32] = "Enable 32-bit RISC-V optimizations" > - > -TUNEVALID[riscv64nf] = "Enable 64-bit RISC-V optimizations no floating point" > -TUNEVALID[riscv32nf] = "Enable 32-bit RISC-V optimizations no floating point" > - > -TUNEVALID[riscv64nc] = "Enable 64-bit RISC-V optimizations without compressed instructions" > - > -TUNEVALID[bigendian] = "Big endian mode" > +DEFAULTTUNE ?= "riscv64" > > AVAILTUNES += "riscv64 riscv32 riscv64nc riscv64nf riscv32nf" > > # Default > -TUNE_FEATURES:tune-riscv64 = "riscv64" > -TUNE_ARCH:tune-riscv64 = "riscv64" > -TUNE_PKGARCH:tune-riscv64 = "riscv64" > -PACKAGE_EXTRA_ARCHS:tune-riscv64 = "riscv64" > +TUNE_FEATURES:tune-riscv64 := "${@oe.tune.riscv_isa_to_tune("rv64gc")}" > +PACKAGE_EXTRA_ARCHS:tune-riscv64 = "${TUNE_RISCV_PKGARCH}" > > -TUNE_FEATURES:tune-riscv32 = "riscv32" > -TUNE_ARCH:tune-riscv32 = "riscv32" > -TUNE_PKGARCH:tune-riscv32 = "riscv32" > -PACKAGE_EXTRA_ARCHS:tune-riscv32 = "riscv32" > +TUNE_FEATURES:tune-riscv32 := "${@oe.tune.riscv_isa_to_tune("rv32gc")}" > +PACKAGE_EXTRA_ARCHS:tune-riscv32 = "${TUNE_RISCV_PKGARCH}" > > # No float > -TUNE_FEATURES:tune-riscv64nf = "${TUNE_FEATURES:tune-riscv64} riscv64nf" > -TUNE_ARCH:tune-riscv64nf = "riscv64" > -TUNE_PKGARCH:tune-riscv64nf = "riscv64nf" > -PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "riscv64nf" > +TUNE_FEATURES:tune-riscv64nf := "${@oe.tune.riscv_isa_to_tune("rv64imac_zicsr_zifencei")}" > +PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "${TUNE_RISCV_PKGARCH}" > > -TUNE_FEATURES:tune-riscv32nf = "${TUNE_FEATURES:tune-riscv32} riscv32nf" > -TUNE_ARCH:tune-riscv32nf = "riscv32" > -TUNE_PKGARCH:tune-riscv32nf = "riscv32nf" > -PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "riscv32nf" > +TUNE_FEATURES:tune-riscv32nf := "${@oe.tune.riscv_isa_to_tune("rv32imac_zicsr_zifencei")}" > +PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "${TUNE_RISCV_PKGARCH}" > > # no compressed > -TUNE_FEATURES:tune-riscv64nc = "${TUNE_FEATURES:tune-riscv64} riscv64nc" > -TUNE_ARCH:tune-riscv64nc = "riscv64" > -TUNE_PKGARCH:tune-riscv64nc = "riscv64nc" > -PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "riscv64nc" > +TUNE_FEATURES:tune-riscv64nc := "${@oe.tune.riscv_isa_to_tune("rv64imafd_zicsr_zifencei")}" > +PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "${TUNE_RISCV_PKGARCH}" > diff --git a/meta/conf/machine/qemuriscv32.conf b/meta/conf/machine/qemuriscv32.conf > index d3858dc051..aff36c28a5 100644 > --- a/meta/conf/machine/qemuriscv32.conf > +++ b/meta/conf/machine/qemuriscv32.conf > @@ -2,9 +2,9 @@ > #@NAME: generic riscv32 machine > #@DESCRIPTION: Machine configuration for running a generic riscv32 > > -require conf/machine/include/riscv/qemuriscv.inc > +DEFAULTTUNE ?= "riscv32" > > -DEFAULTTUNE = "riscv32" > +require conf/machine/include/riscv/qemuriscv.inc > > PREFERRED_VERSION_openocd-native = "riscv" > PREFERRED_VERSION_openocd = "riscv" > diff --git a/meta/lib/oe/__init__.py b/meta/lib/oe/__init__.py > index dd094a874a..73de774266 100644 > --- a/meta/lib/oe/__init__.py > +++ b/meta/lib/oe/__init__.py > @@ -12,4 +12,4 @@ __path__ = extend_path(__path__, __name__) > BBIMPORTS = ["qa", "data", "path", "utils", "types", "package", "packagedata", \ > "packagegroup", "sstatesig", "lsb", "cachedpath", "license", "qemu", \ > "reproducible", "rust", "buildcfg", "go", "spdx30_tasks", "spdx_common", \ > - "cve_check"] > + "cve_check", "tune"] > diff --git a/meta/lib/oe/tune.py b/meta/lib/oe/tune.py > new file mode 100644 > index 0000000000..7fda19430d > --- /dev/null > +++ b/meta/lib/oe/tune.py > @@ -0,0 +1,81 @@ > +# > +# Copyright OpenEmbedded Contributors > +# > +# SPDX-License-Identifier: GPL-2.0-only > +# > + > +# riscv_isa_to_tune(isa) > +# > +# Automatically translate a RISC-V ISA string to TUNE_FEATURES > +# > +# Abbreviations, such as rv32g -> rv32imaffd_zicsr_zifencei are supported. > +# > +# Profiles, such as rva22u64, are NOT supported, you must use ISA strings. > +# > +def riscv_isa_to_tune(isa): > + _isa = isa.lower() > + > + feature = [] > + iter = 0 > + > + # rv or riscv > + if _isa[iter:].startswith('rv'): > + feature.append('rv') > + iter = iter + 2 > + elif _isa[iter:].startswith('riscv'): > + feature.append('rv') > + iter = iter + 5 > + else: > + # Not a risc-v ISA! > + return _isa > + > + while (_isa[iter:]): > + # Skip _ and whitespace > + if _isa[iter] == '_' or _isa[iter].isspace(): > + iter = iter + 1 > + continue > + > + # Length, just capture numbers here > + if _isa[iter].isdigit(): > + iter_end = iter > + while iter_end < len(_isa) and _isa[iter_end].isdigit(): > + iter_end = iter_end + 1 > + > + feature.append(_isa[iter:iter_end]) > + iter = iter_end > + continue > + > + # Typically i, e or g is next, followed by extensions. > + # Extensions are single character, except for Z, Ss, Sh, Sm, Sv, and X > + > + # If the extension starts with 'Z', 'S' or 'X' use the name until the next _, whitespace or end > + if _isa[iter] in ['z', 's', 'x']: > + ext_type = _isa[iter] > + iter_end = iter + 1 > + > + # Multicharacter extension, these are supposed to have a _ before the next multicharacter extension > + # See 37.4 and 37.5: > + # 37.4: Underscores "_" may be used to separate ISA extensions... > + # 37.5: All multi-letter extensions ... must be separated from other multi-letter extensions by an underscore... > + # Some extensions permit only alphabetic characters, while others allow alphanumeric chartacters > + while iter_end < len(_isa) and _isa[iter_end] != "_" and not _isa[iter_end].isspace(): > + iter_end = iter_end + 1 > + > + feature.append(_isa[iter:iter_end]) > + iter = iter_end > + continue > + > + # 'g' is special, it's an abbreviation for imafd_zicsr_zifencei > + # When expanding the abbreviation, any additional letters must appear before the _z* extensions > + if _isa[iter] == 'g': > + _isa = 'imafd' + _isa[iter+1:] + '_zicsr_zifencei' > + iter = 0 > + continue > + > + feature.append(_isa[iter]) > + iter = iter + 1 > + continue > + > + # Eliminate duplicates, but preserve the order > + feature = list(dict.fromkeys(feature)) > + return ' '.join(feature) > -- > 2.34.1 > > > -=-=-=-=-=-=-=-=-=-=-=- > Links: You receive all messages sent to this group. > View/Reply Online (#218948): https://lists.openembedded.org/g/openembedded-core/message/218948 > Mute This Topic: https://lists.openembedded.org/mt/113700338/3619028 > Group Owner: openembedded-core+owner@lists.openembedded.org > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [alistair23@gmail.com] > -=-=-=-=-=-=-=-=-=-=-=- > ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core] [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features 2025-06-18 4:00 ` [OE-core] " Alistair Francis @ 2025-06-18 14:12 ` Mark Hatle [not found] ` <184A2891E949D242.11882@lists.openembedded.org> 1 sibling, 0 replies; 16+ messages in thread From: Mark Hatle @ 2025-06-18 14:12 UTC (permalink / raw) To: Alistair Francis; +Cc: openembedded-core On 6/17/25 11:00 PM, Alistair Francis wrote: > On Wed, Jun 18, 2025 at 9:39 AM Mark Hatle via lists.openembedded.org > <mark.hatle=kernel.crashing.org@lists.openembedded.org> wrote: >> >> From: Mark Hatle <mark.hatle@amd.com> >> >> This implements the following base ISAs: >> >> * rv32i, rv64i >> * rv32e, rv64i >> >> The following ABIs: >> * ilp32, ilp32e, ilp32f, ilp32d >> * lp64, lp64e, lp64f, lp64d >> >> The following ISA extension are also implemented: >> * M - Integer Multiplication and Division Extension >> * A - Atomic Memory Extension >> * F - Single-Precision Floating-Point Extension >> * D - Double-Precision Floating-Point Extension >> * C - Compressed Extension >> * B - Bit Manipulation Extension (implies Zba, Zbb, Zbs) >> * V - Vector Operations Extension >> * Zicsr - Control and Status Register Access Extension >> * Zifencei - Instruction-Fetch Fence Extension >> * Zba - Address bit manipulation extension >> * Zbb - Basic bit manipulation extension >> * Zbc - Carry-less multiplication extension >> * Zbs - Single-bit manipulation extension >> * Zicbom - Cache-block management extension >> >> The existing processors tunes are preserved: >> * riscv64 (rv64gc) >> * riscv32 (rv32gc) >> * riscv64nf (rv64imac_zicsr_zifencei) >> * riscv32nf (rv32imac_zicsr_zifencei) >> * riscv64nc (rv64imafd_zicsr_zifencei) > > I'm not sure this is the way we want to handle this. You are picking > and choosing each individual extension, which is difficult for users > to do. Not to mention it's easy to get wrong as some extensions > conflict with other extensions. > > You also end up using the `rv32` or `rv64` CPUs with QEMU and enabling > extensions manually. We will probably remove those CPUs from QEMU in > the future as they cause a lot of user confusion. > > I think instead we should be moving towards the RISC-V profiles. > Individual extensions can still be enabled/disabled on top of a > profile if required. That's what we are doing in QEMU and it makes > things a lot clearer to users exactly what is/isn't enabled. As I've said elsewhere, profiles mean ISA + extensions. "Profiles only describe ISA features, not a complete execution environment." https://github.com/riscv/riscv-profiles/blob/main/src/profiles.adoc#2-profiles-versus-platforms For someone who understands what a specific profile is, it should be implemented in the new meta/lib/oe/tune.py file. Any missing TUNE_FEATURES should be added. I'd recommend a new function like: riscv_profile_to_tune(profile): and/or riscv_profile_to_isa(profile): (the later could call the existing riscv_isa_to_tune) Then in the tune-<name>.inc file, the user would implement it as: require conf/machine/include/riscv/arch-riscv.inc DEFAULTTUNE ?= "my-magic-cpu" AVAILTUNES += "my-magic-cpu" TUNE_FEATURES:tune-my-magic-cpu := "${@riscv_profile_to_tune("rva20u32")} m a" PACKAGE_EXTRA_ARCHS:tune-my-magic-cpu = "${TUNE_RISCV_PKGARCH}" The above should result in: rv 32 i m a , since RVI20U32 says "no mandatory extensions" but M A F D C Zifencei and Zicntr are optional. (rvi20u64 is similar) Note: rv 32 i m a is not Linux compatible, we need zicsr and zifencei as well, but Zicsr is not listed as mandatory or optional while RVA22U64 defines a specific set that contains extensions which my parts do NOT support. Thus we _MUST_ have a way to be able to use ISA + extension which is the lowest common denominator of what _WE_ support, while giving users views into the approaches they want. _I_ do not intend to implement the profile_to_... functions, as I won't see any use in the parts that I have to support. But as a project, I do think someone should implement thing table and function to make it easier for people who want to use profiles to specify something. --Mark > Alistair > >> >> Previously defined feature 'big-endian' has been removed as it was not used. >> >> Signed-off-by: Mark Hatle <mark.hatle@amd.com> >> --- >> meta/conf/machine/include/riscv/README | 122 ++++++++++++++++ >> .../conf/machine/include/riscv/arch-riscv.inc | 138 +++++++++++++++++- >> .../conf/machine/include/riscv/tune-riscv.inc | 40 ++--- >> meta/conf/machine/qemuriscv32.conf | 4 +- >> meta/lib/oe/__init__.py | 2 +- >> meta/lib/oe/tune.py | 81 ++++++++++ >> 6 files changed, 349 insertions(+), 38 deletions(-) >> create mode 100644 meta/conf/machine/include/riscv/README >> create mode 100644 meta/lib/oe/tune.py >> >> diff --git a/meta/conf/machine/include/riscv/README b/meta/conf/machine/include/riscv/README >> new file mode 100644 >> index 0000000000..beef68f523 >> --- /dev/null >> +++ b/meta/conf/machine/include/riscv/README >> @@ -0,0 +1,122 @@ >> +2025/06/08 - Mark Hatle <mark.hatle@amd.com> >> + - Initial Revision >> + >> +The RISC-V ISA is broken into two parts, a base ISA and extensions. As >> +of the writing of this document these are documented at: >> + >> +https://lf-riscv.atlassian.net/wiki/spaces/HOME/pages/16154769/RISC-V+Technical+Specifications >> + >> +Specifically "The RISC-V Instruction Set Manual Volume I: Unprivileged ISA" >> +was used to create this implementation. >> + >> +Requirements >> +------------ >> +As RISC-V is a “variable” ISA (a base isa plus numerous extensions), a >> +mechanism is required to specify a series of ISA features that a user or >> +tune can use to specify a specific CPU instantiation. >> + >> +Not all ratified or draft features should or can be implemented with the >> +available resources. >> + >> +The implementation should work for Linux, baremetal (newlib), zephyr and >> +other operating systems. Supported extensions should be based on >> +real-world examples. >> + >> +Linux >> +----- >> +Linux required base and support extensions should be available. Linux >> +requires: >> +* Base: rv32ima & rv64ima >> +* Optional FPU: fd >> +* Optional RISCV_ISA_C: c >> +* Optiona RISCV_ISA_V: v >> +* Required additional: _zicsr_zifencei >> +* Optional RISCV_ISA_ZBA: _zba >> +* Optional RISCV_ISA_ZBB: _zbb >> +* Optional RISCV_ISA_ZBC: _zbc (not supported by current QEMU design) >> + >> +See: https://git.yoctoproject.org/linux-yocto/tree/arch/riscv/Makefile?h=v6.12/base >> + >> +Baremetal >> +--------- >> +AMD Microblaze-V FPGA support uses the following static configurations: >> +Base: rv32e, rv32i, rv64i >> +Extensions: m, a, f, d, c, b, zicsr, zifencei >> + >> +Zephyr >> +------ >> +AMD Microblaze-V development for Zephyr is the same as Baremetal, with a >> +few additional extensions: zbc, zicbom >> + >> +ABI >> +--- >> +The following ABIs are supported GNU tools and some combination of systems. >> +* ilp32 - Integer, long and pointer are 32-bit >> +* lp64 - Long and pointer are 64-bit (integer is 32-bit) >> + >> +The ABI is dependent upon the core system implementation, as ilp32 can >> +only used on an ‘rv32’ system, while lp64 can only be used on an ‘rv64’ >> +system. >> + >> +There are additional variations of each ABI: >> +* e - used with the Reduced register extension >> +* f - used when single precision floating point (but not double precision) is >> + enabled >> +* d - used when both single and double precision floating point is enabled >> + >> +Based on the above, the ABI should be automatically determined based on >> +the selected Base ISA and Extensions. >> + >> +Implementation >> +-------------- >> +To make it easier to generate the RISC-V canonical arch, ISA based -march, >> +and the ABI string, a few new variables are added for specific RISC-V items. >> + >> +TUNE_RISCV_ARCH - This contains the canonical GNU style arch, generally this >> + will evaluate to "riscv32" or "riscv64". >> + >> +TUNE_RISCV_MARCH - This will contain an ISA based -march string compatible >> + with gcc and similar toolchains. For example: >> + rv32imacfd_zicsr_zifencei >> + >> +TUNE_RISCV_ABI - This is the generated ABI that corresponds to the ARCH and >> + MARCH/ISA values. For riscv32, the value will be ilp32 >> + (int, long and pointer is 32-bit) with the ISA >> + variation. For riscv64, the value will be lp64 (long >> + and pointer are 64-bit bit, while int is 32-bit) with the >> + ISA variation. The ISA affects the ABI when the 'e', 'f' >> + and 'd' extension are used. >> + >> +TUNE_RISCV_PKGARCH - This is the generated PKGARCH value. >> + >> +The standard variables are defined as: >> + >> +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}" >> + >> +The above will allow the user to specify an implementation specific >> +TUNE_CCARGS for a given processor tune if the default implementtion is >> +not adequate for some reason. It is expected that most, if not all, >> +implementations will use the default behavior. >> + >> +TUNE_ARCH = "${TUNE_RISCV_ARCH}" >> +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}" >> + >> +The above two will always base their setting off the standard TUNE_FEATURES. >> + >> +Ratified and draft extensions should be implemented as TUNE_FEATURES in >> +the arch-riscv.inc file. >> + >> +Vendor specific extensions and processor specific settings should go >> +into a 'tune-<vendor>.inc' file, with tune-riscv.inc being reserved for >> +general purpose tunes. >> + >> +TUNE_FEATURE Helper >> +------------------- >> +A special helper function has been written that will convert RISC-V ISA >> +notation into TUNE_FEATURE notion, for example: >> + >> +rv32g -> rv 32 i m a f d zicsr zifencei >> + >> +The helper can be called using oe.tune.riscv_isa_to_tune("<ISA>") such as >> +oe.tune.riscv_isa_to_tune("rv64gc") which would return: >> + rv 64 i m a f d c zicsr zifencei >> diff --git a/meta/conf/machine/include/riscv/arch-riscv.inc b/meta/conf/machine/include/riscv/arch-riscv.inc >> index b34064e78f..99bed8fde5 100644 >> --- a/meta/conf/machine/include/riscv/arch-riscv.inc >> +++ b/meta/conf/machine/include/riscv/arch-riscv.inc >> @@ -1,14 +1,140 @@ >> # RISCV Architecture definition >> >> -DEFAULTTUNE ?= "riscv64" >> +# Based on the RISC-V Instruction Set Manual Volume I: Unprivileged ISA from May 2025 >> +# As well as the RISC-V options for using GCC (as of June 2025) >> >> -TUNE_ARCH = "${TUNE_ARCH:tune-${DEFAULTTUNE}}" >> -TUNE_PKGARCH = "${TUNE_PKGARCH:tune-${DEFAULTTUNE}}" >> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nf', ' -mabi=lp64', ' ', d)}" >> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv32nf', ' -mabi=ilp32', ' ', d)}" >> +# Note: the following should be implemented in the order that GCC expects >> +# -march= values to be defined in. >> >> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nc', ' -march=rv64imafd', ' ', d)}" >> +# Base ISA >> +# All supported march strings must start with rv32 or rv64 >> +TUNEVALID[rv] = "RISC-V" >> +TUNE_RISCV_ARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "riscv", "", d)}" >> +TUNE_RISCV_MARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "rv", "", d)}" >> +TUNE_RISCV_ABI = "" >> >> +# There are two primary ABIs, ilp32 and lp64 >> +# There are variants of both, that appears to be based on extensions above >> +# For example: >> +# rv32i uses ilp32, rv32e uses ilp32e, rv32f uses ilp32f >> +# rv64i uses lp64, rv64if uses lp64f, rv64id uses lp64d >> +TUNEVALID[32] = "ISA XLEN - 32-bit" >> +TUNECONFLICTS[32] = "64" >> +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}" >> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "32", "ilp32", "", d)}" >> + >> +TUNEVALID[64] = "ISA XLEN - 64-bit" >> +TUNECONFLICTS[64] = "32" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}" >> +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}" >> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "64", "lp64", "", d)}" >> + >> +# The package arch starts with the canonical arch, but adds some extensions to make >> +# package compatibility clear >> +TUNE_RISCV_PKGARCH = "${TUNE_RISCV_ARCH}" >> + >> +# i, e, or g are defined by gcc, but 'g' refers to 'i' + extensions 'MAFD Zicsr Zifencei' >> +# So 'g' will not be defined here as it is an abbreviation of the expanded version >> +TUNEVALID[e] = "Reduced register base integer extension" >> +TUNECONFLICTS[e] = "i" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" >> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" >> + >> +TUNEVALID[i] = "Base integer extension" >> +TUNECONFLICTS[i] = "e" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}" >> + >> +# Extensions >> +TUNEVALID[m] = "Integer multiplication and division extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}" >> + >> +TUNEVALID[a] = "Atomic extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}" >> + >> +TUNEVALID[f] = "Single-precision floating-point extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}" >> + >> +TUNEVALID[d] = "Double-precision floating-point extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}" >> + >> +# Only f OR d, but just one >> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", bb.utils.contains("TUNE_FEATURES", "f", "f", "", d), d)}" >> + >> +TUNEVALID[c] = "Compressed extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}" >> + >> +TUNEVALID[b] = "Bit Manipulation extension" >> +# Handled below via zba, zbb, zbs >> +# This matches current Linux kernel behavior >> +#TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}" >> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}" >> + >> +TUNEVALID[v] = "Vector operations extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}" >> + >> +# Now the special Z extensions >> +TUNEVALID[zicbom] = "Cache-block management extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}" >> + >> +TUNEVALID[zicsr] = "Control and status register access extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}" >> +# If zicsr (or zifencei) is in the path, OpenSBI fails to use the extensions, do to (Makefile): >> +# # Check whether the assembler and the compiler support the Zicsr and Zifencei extensions >> +# CC_SUPPORT_ZICSR_ZIFENCEI := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)imafd_zicsr_zifencei -x c /dev/null -o /dev/null 2>&1 | grep -e "zicsr" -e "zifencei" > /dev/null && echo n || echo y) >> +# this will match on the path containing zicsr or zifencei when an error is reported, which >> +# will always happens in this check. >> +# >> +# Yocto Project Bugzilla 15897 >> +# >> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}" >> + >> +TUNEVALID[zifencei] = "Instruction-fetch fence extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}" >> +# See above Bug 15897 >> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}" >> + >> +TUNEVALID[zba] = "Address bit manipulation extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}" >> + >> +TUNEVALID[zbb] = "Basic bit manipulation extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}" >> + >> +TUNEVALID[zbc] = "Carry-less multiplication extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}" >> + >> +TUNEVALID[zbs] = "Single-bit manipulation extension" >> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}" >> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}" >> + >> +# Construct TUNE_CCARGS >> +# This should result in a CCARG similar to: >> +# -march=rv32imac -mabi=ilp32 >> +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}" >> + >> +# Construct TUNE_ARCH >> +# This should result in an arch string similar to: >> +# riscv32 >> +TUNE_ARCH = "${TUNE_RISCV_ARCH}" >> + >> +# Construct TUNE_PKGARCH >> +# This should result in a package are like: >> +# riscv32imac >> +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}" >> + >> +# Misc settings >> # Fix: ld: unrecognized option '--hash-style=sysv' >> LINKER_HASH_STYLE:libc-newlib = "" >> LINKER_HASH_STYLE:libc-picolibc = "" >> diff --git a/meta/conf/machine/include/riscv/tune-riscv.inc b/meta/conf/machine/include/riscv/tune-riscv.inc >> index 804712077e..12c1125c8b 100644 >> --- a/meta/conf/machine/include/riscv/tune-riscv.inc >> +++ b/meta/conf/machine/include/riscv/tune-riscv.inc >> @@ -1,41 +1,23 @@ >> require conf/machine/include/riscv/arch-riscv.inc >> >> -TUNEVALID[riscv64] = "Enable 64-bit RISC-V optimizations" >> -TUNEVALID[riscv32] = "Enable 32-bit RISC-V optimizations" >> - >> -TUNEVALID[riscv64nf] = "Enable 64-bit RISC-V optimizations no floating point" >> -TUNEVALID[riscv32nf] = "Enable 32-bit RISC-V optimizations no floating point" >> - >> -TUNEVALID[riscv64nc] = "Enable 64-bit RISC-V optimizations without compressed instructions" >> - >> -TUNEVALID[bigendian] = "Big endian mode" >> +DEFAULTTUNE ?= "riscv64" >> >> AVAILTUNES += "riscv64 riscv32 riscv64nc riscv64nf riscv32nf" >> >> # Default >> -TUNE_FEATURES:tune-riscv64 = "riscv64" >> -TUNE_ARCH:tune-riscv64 = "riscv64" >> -TUNE_PKGARCH:tune-riscv64 = "riscv64" >> -PACKAGE_EXTRA_ARCHS:tune-riscv64 = "riscv64" >> +TUNE_FEATURES:tune-riscv64 := "${@oe.tune.riscv_isa_to_tune("rv64gc")}" >> +PACKAGE_EXTRA_ARCHS:tune-riscv64 = "${TUNE_RISCV_PKGARCH}" >> >> -TUNE_FEATURES:tune-riscv32 = "riscv32" >> -TUNE_ARCH:tune-riscv32 = "riscv32" >> -TUNE_PKGARCH:tune-riscv32 = "riscv32" >> -PACKAGE_EXTRA_ARCHS:tune-riscv32 = "riscv32" >> +TUNE_FEATURES:tune-riscv32 := "${@oe.tune.riscv_isa_to_tune("rv32gc")}" >> +PACKAGE_EXTRA_ARCHS:tune-riscv32 = "${TUNE_RISCV_PKGARCH}" >> >> # No float >> -TUNE_FEATURES:tune-riscv64nf = "${TUNE_FEATURES:tune-riscv64} riscv64nf" >> -TUNE_ARCH:tune-riscv64nf = "riscv64" >> -TUNE_PKGARCH:tune-riscv64nf = "riscv64nf" >> -PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "riscv64nf" >> +TUNE_FEATURES:tune-riscv64nf := "${@oe.tune.riscv_isa_to_tune("rv64imac_zicsr_zifencei")}" >> +PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "${TUNE_RISCV_PKGARCH}" >> >> -TUNE_FEATURES:tune-riscv32nf = "${TUNE_FEATURES:tune-riscv32} riscv32nf" >> -TUNE_ARCH:tune-riscv32nf = "riscv32" >> -TUNE_PKGARCH:tune-riscv32nf = "riscv32nf" >> -PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "riscv32nf" >> +TUNE_FEATURES:tune-riscv32nf := "${@oe.tune.riscv_isa_to_tune("rv32imac_zicsr_zifencei")}" >> +PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "${TUNE_RISCV_PKGARCH}" >> >> # no compressed >> -TUNE_FEATURES:tune-riscv64nc = "${TUNE_FEATURES:tune-riscv64} riscv64nc" >> -TUNE_ARCH:tune-riscv64nc = "riscv64" >> -TUNE_PKGARCH:tune-riscv64nc = "riscv64nc" >> -PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "riscv64nc" >> +TUNE_FEATURES:tune-riscv64nc := "${@oe.tune.riscv_isa_to_tune("rv64imafd_zicsr_zifencei")}" >> +PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "${TUNE_RISCV_PKGARCH}" >> diff --git a/meta/conf/machine/qemuriscv32.conf b/meta/conf/machine/qemuriscv32.conf >> index d3858dc051..aff36c28a5 100644 >> --- a/meta/conf/machine/qemuriscv32.conf >> +++ b/meta/conf/machine/qemuriscv32.conf >> @@ -2,9 +2,9 @@ >> #@NAME: generic riscv32 machine >> #@DESCRIPTION: Machine configuration for running a generic riscv32 >> >> -require conf/machine/include/riscv/qemuriscv.inc >> +DEFAULTTUNE ?= "riscv32" >> >> -DEFAULTTUNE = "riscv32" >> +require conf/machine/include/riscv/qemuriscv.inc >> >> PREFERRED_VERSION_openocd-native = "riscv" >> PREFERRED_VERSION_openocd = "riscv" >> diff --git a/meta/lib/oe/__init__.py b/meta/lib/oe/__init__.py >> index dd094a874a..73de774266 100644 >> --- a/meta/lib/oe/__init__.py >> +++ b/meta/lib/oe/__init__.py >> @@ -12,4 +12,4 @@ __path__ = extend_path(__path__, __name__) >> BBIMPORTS = ["qa", "data", "path", "utils", "types", "package", "packagedata", \ >> "packagegroup", "sstatesig", "lsb", "cachedpath", "license", "qemu", \ >> "reproducible", "rust", "buildcfg", "go", "spdx30_tasks", "spdx_common", \ >> - "cve_check"] >> + "cve_check", "tune"] >> diff --git a/meta/lib/oe/tune.py b/meta/lib/oe/tune.py >> new file mode 100644 >> index 0000000000..7fda19430d >> --- /dev/null >> +++ b/meta/lib/oe/tune.py >> @@ -0,0 +1,81 @@ >> +# >> +# Copyright OpenEmbedded Contributors >> +# >> +# SPDX-License-Identifier: GPL-2.0-only >> +# >> + >> +# riscv_isa_to_tune(isa) >> +# >> +# Automatically translate a RISC-V ISA string to TUNE_FEATURES >> +# >> +# Abbreviations, such as rv32g -> rv32imaffd_zicsr_zifencei are supported. >> +# >> +# Profiles, such as rva22u64, are NOT supported, you must use ISA strings. >> +# >> +def riscv_isa_to_tune(isa): >> + _isa = isa.lower() >> + >> + feature = [] >> + iter = 0 >> + >> + # rv or riscv >> + if _isa[iter:].startswith('rv'): >> + feature.append('rv') >> + iter = iter + 2 >> + elif _isa[iter:].startswith('riscv'): >> + feature.append('rv') >> + iter = iter + 5 >> + else: >> + # Not a risc-v ISA! >> + return _isa >> + >> + while (_isa[iter:]): >> + # Skip _ and whitespace >> + if _isa[iter] == '_' or _isa[iter].isspace(): >> + iter = iter + 1 >> + continue >> + >> + # Length, just capture numbers here >> + if _isa[iter].isdigit(): >> + iter_end = iter >> + while iter_end < len(_isa) and _isa[iter_end].isdigit(): >> + iter_end = iter_end + 1 >> + >> + feature.append(_isa[iter:iter_end]) >> + iter = iter_end >> + continue >> + >> + # Typically i, e or g is next, followed by extensions. >> + # Extensions are single character, except for Z, Ss, Sh, Sm, Sv, and X >> + >> + # If the extension starts with 'Z', 'S' or 'X' use the name until the next _, whitespace or end >> + if _isa[iter] in ['z', 's', 'x']: >> + ext_type = _isa[iter] >> + iter_end = iter + 1 >> + >> + # Multicharacter extension, these are supposed to have a _ before the next multicharacter extension >> + # See 37.4 and 37.5: >> + # 37.4: Underscores "_" may be used to separate ISA extensions... >> + # 37.5: All multi-letter extensions ... must be separated from other multi-letter extensions by an underscore... >> + # Some extensions permit only alphabetic characters, while others allow alphanumeric chartacters >> + while iter_end < len(_isa) and _isa[iter_end] != "_" and not _isa[iter_end].isspace(): >> + iter_end = iter_end + 1 >> + >> + feature.append(_isa[iter:iter_end]) >> + iter = iter_end >> + continue >> + >> + # 'g' is special, it's an abbreviation for imafd_zicsr_zifencei >> + # When expanding the abbreviation, any additional letters must appear before the _z* extensions >> + if _isa[iter] == 'g': >> + _isa = 'imafd' + _isa[iter+1:] + '_zicsr_zifencei' >> + iter = 0 >> + continue >> + >> + feature.append(_isa[iter]) >> + iter = iter + 1 >> + continue >> + >> + # Eliminate duplicates, but preserve the order >> + feature = list(dict.fromkeys(feature)) >> + return ' '.join(feature) >> -- >> 2.34.1 >> >> >> -=-=-=-=-=-=-=-=-=-=-=- >> Links: You receive all messages sent to this group. >> View/Reply Online (#218948): https://lists.openembedded.org/g/openembedded-core/message/218948 >> Mute This Topic: https://lists.openembedded.org/mt/113700338/3619028 >> Group Owner: openembedded-core+owner@lists.openembedded.org >> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [alistair23@gmail.com] >> -=-=-=-=-=-=-=-=-=-=-=- >> ^ permalink raw reply [flat|nested] 16+ messages in thread
[parent not found: <184A2891E949D242.11882@lists.openembedded.org>]
* Re: [OE-core] [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features [not found] ` <184A2891E949D242.11882@lists.openembedded.org> @ 2025-06-18 16:50 ` Mark Hatle 0 siblings, 0 replies; 16+ messages in thread From: Mark Hatle @ 2025-06-18 16:50 UTC (permalink / raw) To: Alistair Francis; +Cc: openembedded-core one minor addendum below On 6/18/25 9:12 AM, Mark Hatle wrote: > > > On 6/17/25 11:00 PM, Alistair Francis wrote: >> On Wed, Jun 18, 2025 at 9:39 AM Mark Hatle via lists.openembedded.org >> <mark.hatle=kernel.crashing.org@lists.openembedded.org> wrote: >>> >>> From: Mark Hatle <mark.hatle@amd.com> >>> >>> This implements the following base ISAs: >>> >>> * rv32i, rv64i >>> * rv32e, rv64i >>> >>> The following ABIs: >>> * ilp32, ilp32e, ilp32f, ilp32d >>> * lp64, lp64e, lp64f, lp64d >>> >>> The following ISA extension are also implemented: >>> * M - Integer Multiplication and Division Extension >>> * A - Atomic Memory Extension >>> * F - Single-Precision Floating-Point Extension >>> * D - Double-Precision Floating-Point Extension >>> * C - Compressed Extension >>> * B - Bit Manipulation Extension (implies Zba, Zbb, Zbs) >>> * V - Vector Operations Extension >>> * Zicsr - Control and Status Register Access Extension >>> * Zifencei - Instruction-Fetch Fence Extension >>> * Zba - Address bit manipulation extension >>> * Zbb - Basic bit manipulation extension >>> * Zbc - Carry-less multiplication extension >>> * Zbs - Single-bit manipulation extension >>> * Zicbom - Cache-block management extension >>> >>> The existing processors tunes are preserved: >>> * riscv64 (rv64gc) >>> * riscv32 (rv32gc) >>> * riscv64nf (rv64imac_zicsr_zifencei) >>> * riscv32nf (rv32imac_zicsr_zifencei) >>> * riscv64nc (rv64imafd_zicsr_zifencei) >> >> I'm not sure this is the way we want to handle this. You are picking >> and choosing each individual extension, which is difficult for users >> to do. Not to mention it's easy to get wrong as some extensions >> conflict with other extensions. We already have TUNE_CONFLICTS, which must be used to ensure that conflicting extensions do not get defined together. This conflict will error during parsing and hopefully give the user helpful information. In the existing implementation (part of this patch), I am using this already as: TUNECONFLICTS[32] = "64" TUNECONFLICTS[64] = "32" TUNECONFLICTS[e] = "i" TUNECONFLICTS[i] = "e" The other thing with risc-v ISA features is some items imply other things. Unfortunately there is not such a mechanism today. This MIGHT be a reasonable extension to the tune stuff.. but until then, I've implemented this like: ${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)} since b implies zba (just like d implies f... and f or d implies zicsr) It would be nice if we could do: TUNEIMPLIES[b] = "zba zbb zbs" So when code inspects TUNE_FEATURES, it can ignore 'b' and just use 'zba', but this might be difficult to implelement in a more efficient way then what we currently have. >> You also end up using the `rv32` or `rv64` CPUs with QEMU and enabling >> extensions manually. We will probably remove those CPUs from QEMU in >> the future as they cause a lot of user confusion. Yes, this was intentional as emulating more extensions that what we're compiling for means that testing won't cover if we have assembly or compilation that uses instructions we don't want. (i.e. OpenSBI requires 'c', while not all CPUs are required to implement 'c'.) This was discovered specifically because of this 'only enable' the instructions we have enabled behavior. >> I think instead we should be moving towards the RISC-V profiles. >> Individual extensions can still be enabled/disabled on top of a >> profile if required. That's what we are doing in QEMU and it makes >> things a lot clearer to users exactly what is/isn't enabled. > > As I've said elsewhere, profiles mean ISA + extensions. > > "Profiles only describe ISA features, not a complete execution environment." > > > https://github.com/riscv/riscv-profiles/blob/main/src/profiles.adoc#2-profiles-versus-platforms > > For someone who understands what a specific profile is, it should be implemented > in the new meta/lib/oe/tune.py file. Any missing TUNE_FEATURES should be added. > > I'd recommend a new function like: > > riscv_profile_to_tune(profile): > > and/or > > riscv_profile_to_isa(profile): > > (the later could call the existing riscv_isa_to_tune) > > Then in the tune-<name>.inc file, the user would implement it as: > > require conf/machine/include/riscv/arch-riscv.inc > > DEFAULTTUNE ?= "my-magic-cpu" > > AVAILTUNES += "my-magic-cpu" > > TUNE_FEATURES:tune-my-magic-cpu := "${@riscv_profile_to_tune("rva20u32")} m a" > PACKAGE_EXTRA_ARCHS:tune-my-magic-cpu = "${TUNE_RISCV_PKGARCH}" > > The above should result in: > > rv 32 i m a , since RVI20U32 says "no mandatory extensions" but M A F D C > Zifencei and Zicntr are optional. (rvi20u64 is similar) > > Note: rv 32 i m a is not Linux compatible, we need zicsr and zifencei as well, > but Zicsr is not listed as mandatory or optional > > while RVA22U64 defines a specific set that contains extensions which my parts do > NOT support. > > Thus we _MUST_ have a way to be able to use ISA + extension which is the lowest > common denominator of what _WE_ support, while giving users views into the > approaches they want. > > _I_ do not intend to implement the profile_to_... functions, as I won't see any > use in the parts that I have to support. But as a project, I do think someone > should implement thing table and function to make it easier for people who want > to use profiles to specify something. > > --Mark > >> Alistair >> >>> >>> Previously defined feature 'big-endian' has been removed as it was not used. >>> >>> Signed-off-by: Mark Hatle <mark.hatle@amd.com> >>> --- >>> meta/conf/machine/include/riscv/README | 122 ++++++++++++++++ >>> .../conf/machine/include/riscv/arch-riscv.inc | 138 +++++++++++++++++- >>> .../conf/machine/include/riscv/tune-riscv.inc | 40 ++--- >>> meta/conf/machine/qemuriscv32.conf | 4 +- >>> meta/lib/oe/__init__.py | 2 +- >>> meta/lib/oe/tune.py | 81 ++++++++++ >>> 6 files changed, 349 insertions(+), 38 deletions(-) >>> create mode 100644 meta/conf/machine/include/riscv/README >>> create mode 100644 meta/lib/oe/tune.py >>> >>> diff --git a/meta/conf/machine/include/riscv/README b/meta/conf/machine/include/riscv/README >>> new file mode 100644 >>> index 0000000000..beef68f523 >>> --- /dev/null >>> +++ b/meta/conf/machine/include/riscv/README >>> @@ -0,0 +1,122 @@ >>> +2025/06/08 - Mark Hatle <mark.hatle@amd.com> >>> + - Initial Revision >>> + >>> +The RISC-V ISA is broken into two parts, a base ISA and extensions. As >>> +of the writing of this document these are documented at: >>> + >>> +https://lf-riscv.atlassian.net/wiki/spaces/HOME/pages/16154769/RISC-V+Technical+Specifications >>> + >>> +Specifically "The RISC-V Instruction Set Manual Volume I: Unprivileged ISA" >>> +was used to create this implementation. >>> + >>> +Requirements >>> +------------ >>> +As RISC-V is a “variable” ISA (a base isa plus numerous extensions), a >>> +mechanism is required to specify a series of ISA features that a user or >>> +tune can use to specify a specific CPU instantiation. >>> + >>> +Not all ratified or draft features should or can be implemented with the >>> +available resources. >>> + >>> +The implementation should work for Linux, baremetal (newlib), zephyr and >>> +other operating systems. Supported extensions should be based on >>> +real-world examples. >>> + >>> +Linux >>> +----- >>> +Linux required base and support extensions should be available. Linux >>> +requires: >>> +* Base: rv32ima & rv64ima >>> +* Optional FPU: fd >>> +* Optional RISCV_ISA_C: c >>> +* Optiona RISCV_ISA_V: v >>> +* Required additional: _zicsr_zifencei >>> +* Optional RISCV_ISA_ZBA: _zba >>> +* Optional RISCV_ISA_ZBB: _zbb >>> +* Optional RISCV_ISA_ZBC: _zbc (not supported by current QEMU design) >>> + >>> +See: https://git.yoctoproject.org/linux-yocto/tree/arch/riscv/Makefile?h=v6.12/base >>> + >>> +Baremetal >>> +--------- >>> +AMD Microblaze-V FPGA support uses the following static configurations: >>> +Base: rv32e, rv32i, rv64i >>> +Extensions: m, a, f, d, c, b, zicsr, zifencei >>> + >>> +Zephyr >>> +------ >>> +AMD Microblaze-V development for Zephyr is the same as Baremetal, with a >>> +few additional extensions: zbc, zicbom >>> + >>> +ABI >>> +--- >>> +The following ABIs are supported GNU tools and some combination of systems. >>> +* ilp32 - Integer, long and pointer are 32-bit >>> +* lp64 - Long and pointer are 64-bit (integer is 32-bit) >>> + >>> +The ABI is dependent upon the core system implementation, as ilp32 can >>> +only used on an ‘rv32’ system, while lp64 can only be used on an ‘rv64’ >>> +system. >>> + >>> +There are additional variations of each ABI: >>> +* e - used with the Reduced register extension >>> +* f - used when single precision floating point (but not double precision) is >>> + enabled >>> +* d - used when both single and double precision floating point is enabled >>> + >>> +Based on the above, the ABI should be automatically determined based on >>> +the selected Base ISA and Extensions. >>> + >>> +Implementation >>> +-------------- >>> +To make it easier to generate the RISC-V canonical arch, ISA based -march, >>> +and the ABI string, a few new variables are added for specific RISC-V items. >>> + >>> +TUNE_RISCV_ARCH - This contains the canonical GNU style arch, generally this >>> + will evaluate to "riscv32" or "riscv64". >>> + >>> +TUNE_RISCV_MARCH - This will contain an ISA based -march string compatible >>> + with gcc and similar toolchains. For example: >>> + rv32imacfd_zicsr_zifencei >>> + >>> +TUNE_RISCV_ABI - This is the generated ABI that corresponds to the ARCH and >>> + MARCH/ISA values. For riscv32, the value will be ilp32 >>> + (int, long and pointer is 32-bit) with the ISA >>> + variation. For riscv64, the value will be lp64 (long >>> + and pointer are 64-bit bit, while int is 32-bit) with the >>> + ISA variation. The ISA affects the ABI when the 'e', 'f' >>> + and 'd' extension are used. >>> + >>> +TUNE_RISCV_PKGARCH - This is the generated PKGARCH value. >>> + >>> +The standard variables are defined as: >>> + >>> +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}" >>> + >>> +The above will allow the user to specify an implementation specific >>> +TUNE_CCARGS for a given processor tune if the default implementtion is >>> +not adequate for some reason. It is expected that most, if not all, >>> +implementations will use the default behavior. >>> + >>> +TUNE_ARCH = "${TUNE_RISCV_ARCH}" >>> +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}" >>> + >>> +The above two will always base their setting off the standard TUNE_FEATURES. >>> + >>> +Ratified and draft extensions should be implemented as TUNE_FEATURES in >>> +the arch-riscv.inc file. >>> + >>> +Vendor specific extensions and processor specific settings should go >>> +into a 'tune-<vendor>.inc' file, with tune-riscv.inc being reserved for >>> +general purpose tunes. >>> + >>> +TUNE_FEATURE Helper >>> +------------------- >>> +A special helper function has been written that will convert RISC-V ISA >>> +notation into TUNE_FEATURE notion, for example: >>> + >>> +rv32g -> rv 32 i m a f d zicsr zifencei >>> + >>> +The helper can be called using oe.tune.riscv_isa_to_tune("<ISA>") such as >>> +oe.tune.riscv_isa_to_tune("rv64gc") which would return: >>> + rv 64 i m a f d c zicsr zifencei >>> diff --git a/meta/conf/machine/include/riscv/arch-riscv.inc b/meta/conf/machine/include/riscv/arch-riscv.inc >>> index b34064e78f..99bed8fde5 100644 >>> --- a/meta/conf/machine/include/riscv/arch-riscv.inc >>> +++ b/meta/conf/machine/include/riscv/arch-riscv.inc >>> @@ -1,14 +1,140 @@ >>> # RISCV Architecture definition >>> >>> -DEFAULTTUNE ?= "riscv64" >>> +# Based on the RISC-V Instruction Set Manual Volume I: Unprivileged ISA from May 2025 >>> +# As well as the RISC-V options for using GCC (as of June 2025) >>> >>> -TUNE_ARCH = "${TUNE_ARCH:tune-${DEFAULTTUNE}}" >>> -TUNE_PKGARCH = "${TUNE_PKGARCH:tune-${DEFAULTTUNE}}" >>> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nf', ' -mabi=lp64', ' ', d)}" >>> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv32nf', ' -mabi=ilp32', ' ', d)}" >>> +# Note: the following should be implemented in the order that GCC expects >>> +# -march= values to be defined in. >>> >>> -TUNE_CCARGS:append = "${@bb.utils.contains('TUNE_FEATURES', 'riscv64nc', ' -march=rv64imafd', ' ', d)}" >>> +# Base ISA >>> +# All supported march strings must start with rv32 or rv64 >>> +TUNEVALID[rv] = "RISC-V" >>> +TUNE_RISCV_ARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "riscv", "", d)}" >>> +TUNE_RISCV_MARCH = "${@bb.utils.contains("TUNE_FEATURES", "rv", "rv", "", d)}" >>> +TUNE_RISCV_ABI = "" >>> >>> +# There are two primary ABIs, ilp32 and lp64 >>> +# There are variants of both, that appears to be based on extensions above >>> +# For example: >>> +# rv32i uses ilp32, rv32e uses ilp32e, rv32f uses ilp32f >>> +# rv64i uses lp64, rv64if uses lp64f, rv64id uses lp64d >>> +TUNEVALID[32] = "ISA XLEN - 32-bit" >>> +TUNECONFLICTS[32] = "64" >>> +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "32", "32", "", d)}" >>> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "32", "ilp32", "", d)}" >>> + >>> +TUNEVALID[64] = "ISA XLEN - 64-bit" >>> +TUNECONFLICTS[64] = "32" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}" >>> +TUNE_RISCV_ARCH .= "${@bb.utils.contains("TUNE_FEATURES", "64", "64", "", d)}" >>> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "64", "lp64", "", d)}" >>> + >>> +# The package arch starts with the canonical arch, but adds some extensions to make >>> +# package compatibility clear >>> +TUNE_RISCV_PKGARCH = "${TUNE_RISCV_ARCH}" >>> + >>> +# i, e, or g are defined by gcc, but 'g' refers to 'i' + extensions 'MAFD Zicsr Zifencei' >>> +# So 'g' will not be defined here as it is an abbreviation of the expanded version >>> +TUNEVALID[e] = "Reduced register base integer extension" >>> +TUNECONFLICTS[e] = "i" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" >>> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "e", "e", "", d)}" >>> + >>> +TUNEVALID[i] = "Base integer extension" >>> +TUNECONFLICTS[i] = "e" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "i", "i", "", d)}" >>> + >>> +# Extensions >>> +TUNEVALID[m] = "Integer multiplication and division extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "m", "m", "", d)}" >>> + >>> +TUNEVALID[a] = "Atomic extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "a", "a", "", d)}" >>> + >>> +TUNEVALID[f] = "Single-precision floating-point extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", "f", "", d)}" >>> + >>> +TUNEVALID[d] = "Double-precision floating-point extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", "", d)}" >>> + >>> +# Only f OR d, but just one >>> +TUNE_RISCV_ABI .= "${@bb.utils.contains("TUNE_FEATURES", "d", "d", bb.utils.contains("TUNE_FEATURES", "f", "f", "", d), d)}" >>> + >>> +TUNEVALID[c] = "Compressed extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "c", "c", "", d)}" >>> + >>> +TUNEVALID[b] = "Bit Manipulation extension" >>> +# Handled below via zba, zbb, zbs >>> +# This matches current Linux kernel behavior >>> +#TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}" >>> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "b", "b", "", d)}" >>> + >>> +TUNEVALID[v] = "Vector operations extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "v", "v", "", d)}" >>> + >>> +# Now the special Z extensions >>> +TUNEVALID[zicbom] = "Cache-block management extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicbom", "_zicbom", "", d)}" >>> + >>> +TUNEVALID[zicsr] = "Control and status register access extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}" >>> +# If zicsr (or zifencei) is in the path, OpenSBI fails to use the extensions, do to (Makefile): >>> +# # Check whether the assembler and the compiler support the Zicsr and Zifencei extensions >>> +# CC_SUPPORT_ZICSR_ZIFENCEI := $(shell $(CC) $(CLANG_TARGET) $(RELAX_FLAG) -nostdlib -march=rv$(OPENSBI_CC_XLEN)imafd_zicsr_zifencei -x c /dev/null -o /dev/null 2>&1 | grep -e "zicsr" -e "zifencei" > /dev/null && echo n || echo y) >>> +# this will match on the path containing zicsr or zifencei when an error is reported, which >>> +# will always happens in this check. >>> +# >>> +# Yocto Project Bugzilla 15897 >>> +# >>> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", "_zicsr", "", d)}" >>> + >>> +TUNEVALID[zifencei] = "Instruction-fetch fence extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}" >>> +# See above Bug 15897 >>> +#TUNE_RISCV_PKGARCH .= "${@bb.utils.contains("TUNE_FEATURES", "zifencei", "_zifencei", "", d)}" >>> + >>> +TUNEVALID[zba] = "Address bit manipulation extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", "_zba", "", d)}" >>> + >>> +TUNEVALID[zbb] = "Basic bit manipulation extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "_zbb", "", d)}" >>> + >>> +TUNEVALID[zbc] = "Carry-less multiplication extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "zbc", "_zbc", "", d)}" >>> + >>> +TUNEVALID[zbs] = "Single-bit manipulation extension" >>> +TUNE_RISCV_MARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}" >>> +TUNE_RISCV_PKGARCH .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", "_zbs", "", d)}" >>> + >>> +# Construct TUNE_CCARGS >>> +# This should result in a CCARG similar to: >>> +# -march=rv32imac -mabi=ilp32 >>> +TUNE_CCARGS = "${@ '-march=${TUNE_RISCV_MARCH} -mabi=${TUNE_RISCV_ABI}' if not d.getVar('TUNE_CCARGS:tune-${DEFAULTTUNE}') else 'TUNE_CCARGS:tune-${DEFAULTTUNE}'}" >>> + >>> +# Construct TUNE_ARCH >>> +# This should result in an arch string similar to: >>> +# riscv32 >>> +TUNE_ARCH = "${TUNE_RISCV_ARCH}" >>> + >>> +# Construct TUNE_PKGARCH >>> +# This should result in a package are like: >>> +# riscv32imac >>> +TUNE_PKGARCH = "${TUNE_RISCV_PKGARCH}" >>> + >>> +# Misc settings >>> # Fix: ld: unrecognized option '--hash-style=sysv' >>> LINKER_HASH_STYLE:libc-newlib = "" >>> LINKER_HASH_STYLE:libc-picolibc = "" >>> diff --git a/meta/conf/machine/include/riscv/tune-riscv.inc b/meta/conf/machine/include/riscv/tune-riscv.inc >>> index 804712077e..12c1125c8b 100644 >>> --- a/meta/conf/machine/include/riscv/tune-riscv.inc >>> +++ b/meta/conf/machine/include/riscv/tune-riscv.inc >>> @@ -1,41 +1,23 @@ >>> require conf/machine/include/riscv/arch-riscv.inc >>> >>> -TUNEVALID[riscv64] = "Enable 64-bit RISC-V optimizations" >>> -TUNEVALID[riscv32] = "Enable 32-bit RISC-V optimizations" >>> - >>> -TUNEVALID[riscv64nf] = "Enable 64-bit RISC-V optimizations no floating point" >>> -TUNEVALID[riscv32nf] = "Enable 32-bit RISC-V optimizations no floating point" >>> - >>> -TUNEVALID[riscv64nc] = "Enable 64-bit RISC-V optimizations without compressed instructions" >>> - >>> -TUNEVALID[bigendian] = "Big endian mode" >>> +DEFAULTTUNE ?= "riscv64" >>> >>> AVAILTUNES += "riscv64 riscv32 riscv64nc riscv64nf riscv32nf" >>> >>> # Default >>> -TUNE_FEATURES:tune-riscv64 = "riscv64" >>> -TUNE_ARCH:tune-riscv64 = "riscv64" >>> -TUNE_PKGARCH:tune-riscv64 = "riscv64" >>> -PACKAGE_EXTRA_ARCHS:tune-riscv64 = "riscv64" >>> +TUNE_FEATURES:tune-riscv64 := "${@oe.tune.riscv_isa_to_tune("rv64gc")}" >>> +PACKAGE_EXTRA_ARCHS:tune-riscv64 = "${TUNE_RISCV_PKGARCH}" >>> >>> -TUNE_FEATURES:tune-riscv32 = "riscv32" >>> -TUNE_ARCH:tune-riscv32 = "riscv32" >>> -TUNE_PKGARCH:tune-riscv32 = "riscv32" >>> -PACKAGE_EXTRA_ARCHS:tune-riscv32 = "riscv32" >>> +TUNE_FEATURES:tune-riscv32 := "${@oe.tune.riscv_isa_to_tune("rv32gc")}" >>> +PACKAGE_EXTRA_ARCHS:tune-riscv32 = "${TUNE_RISCV_PKGARCH}" >>> >>> # No float >>> -TUNE_FEATURES:tune-riscv64nf = "${TUNE_FEATURES:tune-riscv64} riscv64nf" >>> -TUNE_ARCH:tune-riscv64nf = "riscv64" >>> -TUNE_PKGARCH:tune-riscv64nf = "riscv64nf" >>> -PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "riscv64nf" >>> +TUNE_FEATURES:tune-riscv64nf := "${@oe.tune.riscv_isa_to_tune("rv64imac_zicsr_zifencei")}" >>> +PACKAGE_EXTRA_ARCHS:tune-riscv64nf = "${TUNE_RISCV_PKGARCH}" >>> >>> -TUNE_FEATURES:tune-riscv32nf = "${TUNE_FEATURES:tune-riscv32} riscv32nf" >>> -TUNE_ARCH:tune-riscv32nf = "riscv32" >>> -TUNE_PKGARCH:tune-riscv32nf = "riscv32nf" >>> -PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "riscv32nf" >>> +TUNE_FEATURES:tune-riscv32nf := "${@oe.tune.riscv_isa_to_tune("rv32imac_zicsr_zifencei")}" >>> +PACKAGE_EXTRA_ARCHS:tune-riscv32nf = "${TUNE_RISCV_PKGARCH}" >>> >>> # no compressed >>> -TUNE_FEATURES:tune-riscv64nc = "${TUNE_FEATURES:tune-riscv64} riscv64nc" >>> -TUNE_ARCH:tune-riscv64nc = "riscv64" >>> -TUNE_PKGARCH:tune-riscv64nc = "riscv64nc" >>> -PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "riscv64nc" >>> +TUNE_FEATURES:tune-riscv64nc := "${@oe.tune.riscv_isa_to_tune("rv64imafd_zicsr_zifencei")}" >>> +PACKAGE_EXTRA_ARCHS:tune-riscv64nc = "${TUNE_RISCV_PKGARCH}" >>> diff --git a/meta/conf/machine/qemuriscv32.conf b/meta/conf/machine/qemuriscv32.conf >>> index d3858dc051..aff36c28a5 100644 >>> --- a/meta/conf/machine/qemuriscv32.conf >>> +++ b/meta/conf/machine/qemuriscv32.conf >>> @@ -2,9 +2,9 @@ >>> #@NAME: generic riscv32 machine >>> #@DESCRIPTION: Machine configuration for running a generic riscv32 >>> >>> -require conf/machine/include/riscv/qemuriscv.inc >>> +DEFAULTTUNE ?= "riscv32" >>> >>> -DEFAULTTUNE = "riscv32" >>> +require conf/machine/include/riscv/qemuriscv.inc >>> >>> PREFERRED_VERSION_openocd-native = "riscv" >>> PREFERRED_VERSION_openocd = "riscv" >>> diff --git a/meta/lib/oe/__init__.py b/meta/lib/oe/__init__.py >>> index dd094a874a..73de774266 100644 >>> --- a/meta/lib/oe/__init__.py >>> +++ b/meta/lib/oe/__init__.py >>> @@ -12,4 +12,4 @@ __path__ = extend_path(__path__, __name__) >>> BBIMPORTS = ["qa", "data", "path", "utils", "types", "package", "packagedata", \ >>> "packagegroup", "sstatesig", "lsb", "cachedpath", "license", "qemu", \ >>> "reproducible", "rust", "buildcfg", "go", "spdx30_tasks", "spdx_common", \ >>> - "cve_check"] >>> + "cve_check", "tune"] >>> diff --git a/meta/lib/oe/tune.py b/meta/lib/oe/tune.py >>> new file mode 100644 >>> index 0000000000..7fda19430d >>> --- /dev/null >>> +++ b/meta/lib/oe/tune.py >>> @@ -0,0 +1,81 @@ >>> +# >>> +# Copyright OpenEmbedded Contributors >>> +# >>> +# SPDX-License-Identifier: GPL-2.0-only >>> +# >>> + >>> +# riscv_isa_to_tune(isa) >>> +# >>> +# Automatically translate a RISC-V ISA string to TUNE_FEATURES >>> +# >>> +# Abbreviations, such as rv32g -> rv32imaffd_zicsr_zifencei are supported. >>> +# >>> +# Profiles, such as rva22u64, are NOT supported, you must use ISA strings. >>> +# >>> +def riscv_isa_to_tune(isa): >>> + _isa = isa.lower() >>> + >>> + feature = [] >>> + iter = 0 >>> + >>> + # rv or riscv >>> + if _isa[iter:].startswith('rv'): >>> + feature.append('rv') >>> + iter = iter + 2 >>> + elif _isa[iter:].startswith('riscv'): >>> + feature.append('rv') >>> + iter = iter + 5 >>> + else: >>> + # Not a risc-v ISA! >>> + return _isa >>> + >>> + while (_isa[iter:]): >>> + # Skip _ and whitespace >>> + if _isa[iter] == '_' or _isa[iter].isspace(): >>> + iter = iter + 1 >>> + continue >>> + >>> + # Length, just capture numbers here >>> + if _isa[iter].isdigit(): >>> + iter_end = iter >>> + while iter_end < len(_isa) and _isa[iter_end].isdigit(): >>> + iter_end = iter_end + 1 >>> + >>> + feature.append(_isa[iter:iter_end]) >>> + iter = iter_end >>> + continue >>> + >>> + # Typically i, e or g is next, followed by extensions. >>> + # Extensions are single character, except for Z, Ss, Sh, Sm, Sv, and X >>> + >>> + # If the extension starts with 'Z', 'S' or 'X' use the name until the next _, whitespace or end >>> + if _isa[iter] in ['z', 's', 'x']: >>> + ext_type = _isa[iter] >>> + iter_end = iter + 1 >>> + >>> + # Multicharacter extension, these are supposed to have a _ before the next multicharacter extension >>> + # See 37.4 and 37.5: >>> + # 37.4: Underscores "_" may be used to separate ISA extensions... >>> + # 37.5: All multi-letter extensions ... must be separated from other multi-letter extensions by an underscore... >>> + # Some extensions permit only alphabetic characters, while others allow alphanumeric chartacters >>> + while iter_end < len(_isa) and _isa[iter_end] != "_" and not _isa[iter_end].isspace(): >>> + iter_end = iter_end + 1 >>> + >>> + feature.append(_isa[iter:iter_end]) >>> + iter = iter_end >>> + continue >>> + >>> + # 'g' is special, it's an abbreviation for imafd_zicsr_zifencei >>> + # When expanding the abbreviation, any additional letters must appear before the _z* extensions >>> + if _isa[iter] == 'g': >>> + _isa = 'imafd' + _isa[iter+1:] + '_zicsr_zifencei' >>> + iter = 0 >>> + continue >>> + >>> + feature.append(_isa[iter]) >>> + iter = iter + 1 >>> + continue >>> + >>> + # Eliminate duplicates, but preserve the order >>> + feature = list(dict.fromkeys(feature)) >>> + return ' '.join(feature) >>> -- >>> 2.34.1 >>> >>> >>> >>> >>> >>> >>> -=-=-=-=-=-=-=-=-=-=-=- >>> Links: You receive all messages sent to this group. >>> View/Reply Online (#219022): https://lists.openembedded.org/g/openembedded-core/message/219022 >>> Mute This Topic: https://lists.openembedded.org/mt/113700338/3616948 >>> Group Owner: openembedded-core+owner@lists.openembedded.org >>> Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [mark.hatle@kernel.crashing.org] >>> -=-=-=-=-=-=-=-=-=-=-=- >>> ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 2/7] linux-yocto: Enable risc-v TUNE_FEATURES ISA selections ** DO NOT MERGE ** 2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle 2025-06-17 23:39 ` [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features Mark Hatle @ 2025-06-17 23:39 ` Mark Hatle 2025-06-17 23:39 ` [PATCH v2 3/7] u-boot: Dynamic RISC-V ISA configuration Mark Hatle ` (5 subsequent siblings) 7 siblings, 0 replies; 16+ messages in thread From: Mark Hatle @ 2025-06-17 23:39 UTC (permalink / raw) To: openembedded-core From: Mark Hatle <mark.hatle@amd.com> *** THIS NEEDS TO BE RE-IMPLEMENTED AS KERNEL-CACHE/KMETA *** Allow the risc-v TUNE_FEATURES to select specific ISA (kconfig) selections in the kernel config via config fragments. This allows the following items to be selected dynamically: CONFIG_ARCH_RV32I CONFIG_ARCH_RV64I CONFIG_FPU CONFIG_RISCV_ISA_C CONFIG_RISCV_ISA_V CONFIG_RISCV_ISA_ZBB CONFIG_RISCV_ISA_ZICBOM CONFIG_RISCV_ISA_ZICBOZ CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI Signed-off-by: Mark Hatle <mark.hatle@amd.com> --- meta/recipes-kernel/linux/files/risc-v-isa-c.cfg | 1 + .../linux/files/risc-v-isa-clear.cfg | 9 +++++++++ meta/recipes-kernel/linux/files/risc-v-isa-fpu.cfg | 1 + .../linux/files/risc-v-isa-rv32i.cfg | 2 ++ .../linux/files/risc-v-isa-rv64i.cfg | 2 ++ meta/recipes-kernel/linux/files/risc-v-isa-v.cfg | 1 + meta/recipes-kernel/linux/files/risc-v-isa-zbb.cfg | 1 + .../linux/files/risc-v-isa-zicbom.cfg | 1 + meta/recipes-kernel/linux/linux-yocto.inc | 14 ++++++++++++++ 9 files changed, 32 insertions(+) create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-c.cfg create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-clear.cfg create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-fpu.cfg create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-rv32i.cfg create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-rv64i.cfg create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-v.cfg create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-zbb.cfg create mode 100644 meta/recipes-kernel/linux/files/risc-v-isa-zicbom.cfg diff --git a/meta/recipes-kernel/linux/files/risc-v-isa-c.cfg b/meta/recipes-kernel/linux/files/risc-v-isa-c.cfg new file mode 100644 index 0000000000..1cb459f636 --- /dev/null +++ b/meta/recipes-kernel/linux/files/risc-v-isa-c.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_C=y diff --git a/meta/recipes-kernel/linux/files/risc-v-isa-clear.cfg b/meta/recipes-kernel/linux/files/risc-v-isa-clear.cfg new file mode 100644 index 0000000000..ba18d7b9b5 --- /dev/null +++ b/meta/recipes-kernel/linux/files/risc-v-isa-clear.cfg @@ -0,0 +1,9 @@ +# CONFIG_ARCH_RV32I is not set +# CONFIG_ARCH_RV64I is not set +# CONFIG_FPU is not set +# CONFIG_RISCV_ISA_C is not set +# CONFIG_RISCV_ISA_V is not set +# CONFIG_RISCV_ISA_ZBB is not set +# CONFIG_RISCV_ISA_ZICBOM is not set +# CONFIG_RISCV_ISA_ZICBOZ is not set +# CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI is not set diff --git a/meta/recipes-kernel/linux/files/risc-v-isa-fpu.cfg b/meta/recipes-kernel/linux/files/risc-v-isa-fpu.cfg new file mode 100644 index 0000000000..c099c8e81d --- /dev/null +++ b/meta/recipes-kernel/linux/files/risc-v-isa-fpu.cfg @@ -0,0 +1 @@ +CONFIG_FPU=y diff --git a/meta/recipes-kernel/linux/files/risc-v-isa-rv32i.cfg b/meta/recipes-kernel/linux/files/risc-v-isa-rv32i.cfg new file mode 100644 index 0000000000..4c6bac5138 --- /dev/null +++ b/meta/recipes-kernel/linux/files/risc-v-isa-rv32i.cfg @@ -0,0 +1,2 @@ +CONFIG_ARCH_RV32I=y +CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y diff --git a/meta/recipes-kernel/linux/files/risc-v-isa-rv64i.cfg b/meta/recipes-kernel/linux/files/risc-v-isa-rv64i.cfg new file mode 100644 index 0000000000..002b492e4c --- /dev/null +++ b/meta/recipes-kernel/linux/files/risc-v-isa-rv64i.cfg @@ -0,0 +1,2 @@ +CONFIG_ARCH_RV64I=y +CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI=y diff --git a/meta/recipes-kernel/linux/files/risc-v-isa-v.cfg b/meta/recipes-kernel/linux/files/risc-v-isa-v.cfg new file mode 100644 index 0000000000..c29c97fc4a --- /dev/null +++ b/meta/recipes-kernel/linux/files/risc-v-isa-v.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_V=y diff --git a/meta/recipes-kernel/linux/files/risc-v-isa-zbb.cfg b/meta/recipes-kernel/linux/files/risc-v-isa-zbb.cfg new file mode 100644 index 0000000000..2b71b016f8 --- /dev/null +++ b/meta/recipes-kernel/linux/files/risc-v-isa-zbb.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_ZBB=y diff --git a/meta/recipes-kernel/linux/files/risc-v-isa-zicbom.cfg b/meta/recipes-kernel/linux/files/risc-v-isa-zicbom.cfg new file mode 100644 index 0000000000..96daf04b20 --- /dev/null +++ b/meta/recipes-kernel/linux/files/risc-v-isa-zicbom.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_ZICBOM=y diff --git a/meta/recipes-kernel/linux/linux-yocto.inc b/meta/recipes-kernel/linux/linux-yocto.inc index 389329030d..cdf2583698 100644 --- a/meta/recipes-kernel/linux/linux-yocto.inc +++ b/meta/recipes-kernel/linux/linux-yocto.inc @@ -37,6 +37,20 @@ KERNEL_FEATURES:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'efi', 'cfg/ KERNEL_FEATURES:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'numa', 'features/numa/numa.scc', '', d)}" KERNEL_FEATURES:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'vfat', 'cfg/fs/vfat.scc', '', d)}" +SRC_URI_RISCV = "\ + file://risc-v-isa-clear.cfg \ + ${@bb.utils.contains( "TUNE_FEATURES", "rv 32 i m a", "file://risc-v-isa-rv32i.cfg", "", d)} \ + ${@bb.utils.contains( "TUNE_FEATURES", "rv 64 i m a", "file://risc-v-isa-rv64i.cfg", "", d)} \ + ${@bb.utils.contains( "TUNE_FEATURES", "f d", "file://risc-v-isa-fpu.cfg", "", d)} \ + ${@bb.utils.contains( "TUNE_FEATURES", "c", "file://risc-v-isa-c.cfg", "", d)} \ + ${@bb.utils.contains( "TUNE_FEATURES", "v", "file://risc-v-isa-v.cfg", "", d)} \ + ${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "file://risc-v-isa-zbb.cfg", "", d)} \ + ${@bb.utils.contains( "TUNE_FEATURES", "zicbom", "file://risc-v-isa-zicbom.cfg", "", d)} \ + " + +SRC_URI:append:riscv32 = "${SRC_URI_RISCV}" +SRC_URI:append:riscv64 = "${SRC_URI_RISCV}" + # A KMACHINE is the mapping of a yocto $MACHINE to what is built # by the kernel. This is typically the branch that should be built, # and it can be specific to the machine or shared -- 2.34.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 3/7] u-boot: Dynamic RISC-V ISA configuration 2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle 2025-06-17 23:39 ` [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features Mark Hatle 2025-06-17 23:39 ` [PATCH v2 2/7] linux-yocto: Enable risc-v TUNE_FEATURES ISA selections ** DO NOT MERGE ** Mark Hatle @ 2025-06-17 23:39 ` Mark Hatle 2025-06-17 23:39 ` [PATCH v2 4/7] qemuriscv: Dynamically configure qemu CPU Mark Hatle ` (4 subsequent siblings) 7 siblings, 0 replies; 16+ messages in thread From: Mark Hatle @ 2025-06-17 23:39 UTC (permalink / raw) To: openembedded-core From: Mark Hatle <mark.hatle@amd.com> Allow the risc-v TUNE_FEATURES to select specific ISA (kconfig) selections via config fragments. This allows the following items to be selected dynamically: CONFIG_RISCV_ISA_C CONFIG_RISCV_ISA_F CONFIG_RISCV_ISA_D CONFIG_RISCV_ISA_ZBB CONFIG_RISCV_ISA_A CONFIG_RISCV_ISA_ZICBOM Signed-off-by: Mark Hatle <mark.hatle@amd.com> --- meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_a.cfg | 1 + meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_c.cfg | 1 + .../u-boot/files/u-boot-riscv-isa_clear.cfg | 6 ++++++ meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_d.cfg | 1 + meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_f.cfg | 1 + .../u-boot/files/u-boot-riscv-isa_zbb.cfg | 1 + .../u-boot/files/u-boot-riscv-isa_zicbom.cfg | 1 + meta/recipes-bsp/u-boot/u-boot-common.inc | 12 ++++++++++++ 8 files changed, 24 insertions(+) create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_a.cfg create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_c.cfg create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_clear.cfg create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_d.cfg create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_f.cfg create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zbb.cfg create mode 100644 meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zicbom.cfg diff --git a/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_a.cfg b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_a.cfg new file mode 100644 index 0000000000..fc45b64480 --- /dev/null +++ b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_a.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_A=y diff --git a/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_c.cfg b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_c.cfg new file mode 100644 index 0000000000..1cb459f636 --- /dev/null +++ b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_c.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_C=y diff --git a/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_clear.cfg b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_clear.cfg new file mode 100644 index 0000000000..ce90da23ce --- /dev/null +++ b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_clear.cfg @@ -0,0 +1,6 @@ +# CONFIG_RISCV_ISA_C is not set +# CONFIG_RISCV_ISA_F is not set +# CONFIG_RISCV_ISA_D is not set +# CONFIG_RISCV_ISA_ZBB is not set +# CONFIG_RISCV_ISA_A is not set +# CONFIG_RISCV_ISA_ZICBOM is not set diff --git a/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_d.cfg b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_d.cfg new file mode 100644 index 0000000000..fd25fa4e89 --- /dev/null +++ b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_d.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_D=y diff --git a/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_f.cfg b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_f.cfg new file mode 100644 index 0000000000..dfa9876f82 --- /dev/null +++ b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_f.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_F=y diff --git a/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zbb.cfg b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zbb.cfg new file mode 100644 index 0000000000..2b71b016f8 --- /dev/null +++ b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zbb.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_ZBB=y diff --git a/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zicbom.cfg b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zicbom.cfg new file mode 100644 index 0000000000..96daf04b20 --- /dev/null +++ b/meta/recipes-bsp/u-boot/files/u-boot-riscv-isa_zicbom.cfg @@ -0,0 +1 @@ +CONFIG_RISCV_ISA_ZICBOM=y diff --git a/meta/recipes-bsp/u-boot/u-boot-common.inc b/meta/recipes-bsp/u-boot/u-boot-common.inc index fd1eab5cdd..515f18ba9c 100644 --- a/meta/recipes-bsp/u-boot/u-boot-common.inc +++ b/meta/recipes-bsp/u-boot/u-boot-common.inc @@ -16,6 +16,18 @@ SRCREV = "34820924edbc4ec7803eb89d9852f4b870fa760a" SRC_URI = "git://source.denx.de/u-boot/u-boot.git;protocol=https;branch=master;tag=v${PV}" +SRC_URI_RISCV = "\ + file://u-boot-riscv-isa_clear.cfg \ + ${@bb.utils.contains ("TUNE_FEATURES", "a", "file://u-boot-riscv-isa_a.cfg", "", d)} \ + ${@bb.utils.contains ("TUNE_FEATURES", "f", "file://u-boot-riscv-isa_f.cfg", "", d)} \ + ${@bb.utils.contains ("TUNE_FEATURES", "d", "file://u-boot-riscv-isa_d.cfg", "", d)} \ + ${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", "file://u-boot-riscv-isa_zbb.cfg", "", d)} \ + ${@bb.utils.contains ("TUNE_FEATURES", "zicbom", "file://u-boot-riscv-isa_zicbom.cfg", "", d)} \ + " + +SRC_URI:append:riscv32 = "${SRC_URI_RISCV}" +SRC_URI:append:riscv64 = "${SRC_URI_RISCV}" + S = "${WORKDIR}/git" B = "${WORKDIR}/build" -- 2.34.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 4/7] qemuriscv: Dynamically configure qemu CPU 2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle ` (2 preceding siblings ...) 2025-06-17 23:39 ` [PATCH v2 3/7] u-boot: Dynamic RISC-V ISA configuration Mark Hatle @ 2025-06-17 23:39 ` Mark Hatle 2025-06-17 23:39 ` [PATCH v2 5/7] features_check.bbclass: Add support for required TUNE_FEATURES Mark Hatle ` (3 subsequent siblings) 7 siblings, 0 replies; 16+ messages in thread From: Mark Hatle @ 2025-06-17 23:39 UTC (permalink / raw) To: openembedded-core From: Mark Hatle <mark.hatle@amd.com> Use TUNE_FEATURES to dynamically configure the QEMU emulated CPU for the options selected by the DEFAULTTUNE. Note: OpenSBI currently requires 'c' (compressed instructions) or it will not work. Change the base device configuration to use a different variable to select the emulate devices. This will allow a user to override or append the QB_OPT_APPEND without the riscv32 override getting in the way. Signed-off-by: Mark Hatle <mark.hatle@amd.com> --- meta/conf/machine/include/riscv/qemuriscv.inc | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/meta/conf/machine/include/riscv/qemuriscv.inc b/meta/conf/machine/include/riscv/qemuriscv.inc index 65cbfd66ee..91a84cdd39 100644 --- a/meta/conf/machine/include/riscv/qemuriscv.inc +++ b/meta/conf/machine/include/riscv/qemuriscv.inc @@ -27,7 +27,6 @@ UBOOT_ENTRYPOINT:riscv64 = "0x80200000" # qemuboot options QB_SMP ?= "-smp 4" QB_KERNEL_CMDLINE_APPEND = "earlycon=sbi" -QB_CPU:riscv64 ?= "-cpu rva22s64" QB_MACHINE = "-machine virt" QB_DEFAULT_BIOS = "fw_jump.elf" QB_TAP_OPT = "-netdev tap,id=net0,ifname=@TAP@,script=no,downscript=no" @@ -36,5 +35,31 @@ QB_ROOTFS_OPT = "-drive id=disk0,file=@ROOTFS@,if=none,format=raw -device virtio QB_SERIAL_OPT = "-device virtio-serial-device -chardev null,id=virtcon -device virtconsole,chardev=virtcon" QB_TCPSERIAL_OPT = " -device virtio-serial-device -chardev socket,id=virtcon,port=@PORT@,host=127.0.0.1,nodelay=on -device virtconsole,chardev=virtcon" QB_GRAPHICS = "-device bochs-display" -QB_OPT_APPEND = "-device qemu-xhci -device usb-tablet -device usb-kbd" -QB_OPT_APPEND:riscv32 = "-device virtio-tablet-pci -device virtio-keyboard-pci" +QB_OPT_APPEND = "${RV_QEMU_ISA} ${RV_QEMU_DEVICES}" + +RV_QEMU_DEVICES = "-device qemu-xhci -device usb-tablet -device usb-kbd" +RV_QEMU_DEVICES:riscv32 = "-device virtio-tablet-pci -device virtio-keyboard-pci" + +RV_QEMU_ISA = "-cpu " +# Choose rv32 or rv64 +RV_QEMU_ISA .= "${@bb.utils.contains("TUNE_FEATURES", "rv 32", "rv32", "", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains("TUNE_FEATURES", "rv 64", "rv64", "", d)}" +# Disable all of the default extensions we don't support +RV_QEMU_ISA .= ",zihintntl=false,zihintpause=false,zawrs=false,zfa=false,svadu=false,zicntr=false,zihpm=false" +RV_QEMU_ISA .= ",zicboz=false,zicbop=false,zmmul=false,sstc=false,h=false" +# Dynamically enable the extensions based on TUNE_FEATURES +RV_QEMU_ISA .= "${@bb.utils.contains ("TUNE_FEATURES", "m", ",m=true", ",m=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains ("TUNE_FEATURES", "a", ",a=true", ",a=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains_any("TUNE_FEATURES", "f d", ",f=true", ",f=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains ("TUNE_FEATURES", "d", ",d=true", ",d=false", d)}" +# OpenSBI fails to boot without 'c' +#RV_QEMU_ISA .= "${@bb.utils.contains ("TUNE_FEATURES", "c", ",c=true", ",c=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains ("TUNE_FEATURES", "v", ",v=true", ",v=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains ("TUNE_FEATURES", "zicbom", ",zicbom=true", ",zicbom=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains_any("TUNE_FEATURES", "zicsr f d", ",zicsr=true", ",zicsr=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains ("TUNE_FEATURES", "zifencei", ",zifencei=true", ",zifencei=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zba", ",zba=true", ",zba=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbb", ",zbb=true", ",zbb=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains ("TUNE_FEATURES", "zbc", ",zbc=true", ",zbc=false", d)}" +RV_QEMU_ISA .= "${@bb.utils.contains_any("TUNE_FEATURES", "b zbs", ",zbs=true", ",zbs=false", d)}" + -- 2.34.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 5/7] features_check.bbclass: Add support for required TUNE_FEATURES 2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle ` (3 preceding siblings ...) 2025-06-17 23:39 ` [PATCH v2 4/7] qemuriscv: Dynamically configure qemu CPU Mark Hatle @ 2025-06-17 23:39 ` Mark Hatle 2025-06-17 23:39 ` [PATCH v2 6/7] kernel.bbclass: State riscv required tune_features for Linux Mark Hatle ` (2 subsequent siblings) 7 siblings, 0 replies; 16+ messages in thread From: Mark Hatle @ 2025-06-17 23:39 UTC (permalink / raw) To: openembedded-core From: Mark Hatle <mark.hatle@amd.com> Signed-off-by: Mark Hatle <mark.hatle@amd.com> --- meta/classes-recipe/features_check.bbclass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta/classes-recipe/features_check.bbclass b/meta/classes-recipe/features_check.bbclass index 4e122ecaef..1e0eaa4eed 100644 --- a/meta/classes-recipe/features_check.bbclass +++ b/meta/classes-recipe/features_check.bbclass @@ -21,7 +21,7 @@ python () { unused = True - for kind in ['DISTRO', 'MACHINE', 'COMBINED', 'IMAGE']: + for kind in ['DISTRO', 'MACHINE', 'COMBINED', 'IMAGE', 'TUNE']: if d.getVar('ANY_OF_' + kind + '_FEATURES') is None and not d.hasOverrides('ANY_OF_' + kind + '_FEATURES') and \ d.getVar('REQUIRED_' + kind + '_FEATURES') is None and not d.hasOverrides('REQUIRED_' + kind + '_FEATURES') and \ d.getVar('CONFLICT_' + kind + '_FEATURES') is None and not d.hasOverrides('CONFLICT_' + kind + '_FEATURES'): -- 2.34.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 6/7] kernel.bbclass: State riscv required tune_features for Linux 2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle ` (4 preceding siblings ...) 2025-06-17 23:39 ` [PATCH v2 5/7] features_check.bbclass: Add support for required TUNE_FEATURES Mark Hatle @ 2025-06-17 23:39 ` Mark Hatle 2025-06-17 23:39 ` [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES Mark Hatle 2025-06-18 19:29 ` [OE-core] [PATCH v2 0/7] ISA based RISC-V tune implementation Gyorgy Sarvari 7 siblings, 0 replies; 16+ messages in thread From: Mark Hatle @ 2025-06-17 23:39 UTC (permalink / raw) To: openembedded-core From: Mark Hatle <mark.hatle@amd.com> Required: rv32ima_zicsr_zifencei rv64ima_zicsr_zifencei See the arch/riscv/Makefile: riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei Signed-off-by: Mark Hatle <mark.hatle@amd.com> --- meta/classes-recipe/kernel.bbclass | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/meta/classes-recipe/kernel.bbclass b/meta/classes-recipe/kernel.bbclass index 2d9943c8a0..eb03424dfc 100644 --- a/meta/classes-recipe/kernel.bbclass +++ b/meta/classes-recipe/kernel.bbclass @@ -4,10 +4,14 @@ # SPDX-License-Identifier: MIT # -inherit linux-kernel-base kernel-module-split +inherit linux-kernel-base kernel-module-split features_check COMPATIBLE_HOST = ".*-linux" +# Linux has a minimum ISA requires on riscv, see arch/riscv/Makefile +REQUIRED_TUNE_FEATURES:riscv32 = "rv 32 i m a zicsr zifencei" +REQUIRED_TUNE_FEATURES:riscv64 = "rv 64 i m a zicsr zifencei" + KERNEL_PACKAGE_NAME ??= "kernel" KERNEL_DEPLOYSUBDIR ??= "${@ "" if (d.getVar("KERNEL_PACKAGE_NAME") == "kernel") else d.getVar("KERNEL_PACKAGE_NAME") }" -- 2.34.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES 2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle ` (5 preceding siblings ...) 2025-06-17 23:39 ` [PATCH v2 6/7] kernel.bbclass: State riscv required tune_features for Linux Mark Hatle @ 2025-06-17 23:39 ` Mark Hatle 2026-01-14 10:16 ` [OE-core] " Alexander Kanavin 2025-06-18 19:29 ` [OE-core] [PATCH v2 0/7] ISA based RISC-V tune implementation Gyorgy Sarvari 7 siblings, 1 reply; 16+ messages in thread From: Mark Hatle @ 2025-06-17 23:39 UTC (permalink / raw) To: openembedded-core From: Mark Hatle <mark.hatle@amd.com> Add the new TUNE_FEATURES to the 'features:' list, based on matching output with: rustc --target=riscv32i-unknown-none-elf -Ctarget-feature=help Use the TUNE_RISCV_ABI instead of guessing for the ABI. Pass the arch "as-is", since it should now be riscv32 or riscv64. Signed-off-by: Mark Hatle <mark.hatle@amd.com> --- .../classes-recipe/rust-target-config.bbclass | 65 ++++++++++++------- meta/lib/oe/rust.py | 2 - 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/meta/classes-recipe/rust-target-config.bbclass b/meta/classes-recipe/rust-target-config.bbclass index c04940ce54..906a5083d7 100644 --- a/meta/classes-recipe/rust-target-config.bbclass +++ b/meta/classes-recipe/rust-target-config.bbclass @@ -77,8 +77,33 @@ def llvm_features_from_tune(d): f.append("+a15") if 'cortexa17' in feat: f.append("+a17") - if ('riscv64' in feat) or ('riscv32' in feat): - f.append("+a,+c,+d,+f,+m") + if 'rv' in feat: + if 'm' in feat: + f.append("+m") + if 'a' in feat: + f.append("+a") + if 'f' in feat: + f.append("+f") + if 'd' in feat: + f.append("+d") + if 'c' in feat: + f.append("+c") + if 'v' in feat: + f.append("+v") + if 'zicbom' in feat: + f.append("+zicbom") + if 'zicsr' in feat: + f.append("+zicsr") + if 'zifencei' in feat: + f.append("+zifencei") + if 'zba' in feat: + f.append("+zba") + if 'zbb' in feat: + f.append("+zbb") + if 'zbc' in feat: + f.append("+zbc") + if 'zbs' in feat: + f.append("+zbs") return f llvm_features_from_tune[vardepvalue] = "${@llvm_features_from_tune(d)}" @@ -236,19 +261,19 @@ TARGET_POINTER_WIDTH[powerpc64le] = "64" TARGET_C_INT_WIDTH[powerpc64le] = "32" MAX_ATOMIC_WIDTH[powerpc64le] = "64" -## riscv32gc-unknown-linux-{gnu, musl} -DATA_LAYOUT[riscv32gc] = "e-m:e-p:32:32-i64:64-n32-S128" -TARGET_ENDIAN[riscv32gc] = "little" -TARGET_POINTER_WIDTH[riscv32gc] = "32" -TARGET_C_INT_WIDTH[riscv32gc] = "32" -MAX_ATOMIC_WIDTH[riscv32gc] = "32" +## riscv32-unknown-linux-{gnu, musl} +DATA_LAYOUT[riscv32] = "e-m:e-p:32:32-i64:64-n32-S128" +TARGET_ENDIAN[riscv32] = "little" +TARGET_POINTER_WIDTH[riscv32] = "32" +TARGET_C_INT_WIDTH[riscv32] = "32" +MAX_ATOMIC_WIDTH[riscv32] = "32" -## riscv64gc-unknown-linux-{gnu, musl} -DATA_LAYOUT[riscv64gc] = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" -TARGET_ENDIAN[riscv64gc] = "little" -TARGET_POINTER_WIDTH[riscv64gc] = "64" -TARGET_C_INT_WIDTH[riscv64gc] = "32" -MAX_ATOMIC_WIDTH[riscv64gc] = "64" +## riscv64-unknown-linux-{gnu, musl} +DATA_LAYOUT[riscv64] = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" +TARGET_ENDIAN[riscv64] = "little" +TARGET_POINTER_WIDTH[riscv64] = "64" +TARGET_C_INT_WIDTH[riscv64] = "32" +MAX_ATOMIC_WIDTH[riscv64] = "64" ## loongarch64-unknown-linux-{gnu, musl} DATA_LAYOUT[loongarch64] = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" @@ -271,19 +296,11 @@ def arch_to_rust_target_arch(arch): return "arm" elif arch == "powerpc64le": return "powerpc64" - elif arch == "riscv32gc": - return "riscv32" - elif arch == "riscv64gc": - return "riscv64" else: return arch # Convert a rust target string to a llvm-compatible triplet def rust_sys_to_llvm_target(sys): - if sys.startswith('riscv32gc-'): - return sys.replace('riscv32gc-', 'riscv32-', 1) - if sys.startswith('riscv64gc-'): - return sys.replace('riscv64gc-', 'riscv64-', 1) return sys # generates our target CPU value @@ -380,9 +397,9 @@ def rust_gen_target(d, thing, wd, arch): else: tspec['env'] = "gnu" if "riscv64" in tspec['llvm-target']: - tspec['llvm-abiname'] = "lp64d" + tspec['llvm-abiname'] = d.getVar('TUNE_RISCV_ABI') if "riscv32" in tspec['llvm-target']: - tspec['llvm-abiname'] = "ilp32d" + tspec['llvm-abiname'] = d.getVar('TUNE_RISCV_ABI') if "loongarch64" in tspec['llvm-target']: tspec['llvm-abiname'] = "lp64d" tspec['vendor'] = "unknown" diff --git a/meta/lib/oe/rust.py b/meta/lib/oe/rust.py index 185553eeeb..1dc9cf150d 100644 --- a/meta/lib/oe/rust.py +++ b/meta/lib/oe/rust.py @@ -8,6 +8,4 @@ def arch_to_rust_arch(arch): if arch == "ppc64le": return "powerpc64le" - if arch in ('riscv32', 'riscv64'): - return arch + 'gc' return arch -- 2.34.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [OE-core] [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES 2025-06-17 23:39 ` [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES Mark Hatle @ 2026-01-14 10:16 ` Alexander Kanavin 2026-01-14 10:33 ` Richard Purdie 0 siblings, 1 reply; 16+ messages in thread From: Alexander Kanavin @ 2026-01-14 10:16 UTC (permalink / raw) To: mark.hatle; +Cc: openembedded-core, Richard Purdie, Paul Barker On Wed, 18 Jun 2025 at 01:39, Mark Hatle via lists.openembedded.org <mark.hatle=kernel.crashing.org@lists.openembedded.org> wrote: > - tspec['llvm-abiname'] = "lp64d" > + tspec['llvm-abiname'] = d.getVar('TUNE_RISCV_ABI') > if "riscv32" in tspec['llvm-target']: > - tspec['llvm-abiname'] = "ilp32d" > + tspec['llvm-abiname'] = d.getVar('TUNE_RISCV_ABI') Unfortunately this adds a dependency on TUNE_RISCV_ABI (which is set only if the target is a risc-v machine) to rust-native's rust_gen_targets task, breaking sstate reuse for it between risc-v and any other target. I can imagine other native pieces written in rust will have the same issue. It's not immediately obvious to me how to address this, so I'd really appreciate suggestions. The code is hairy. Ticket: https://bugzilla.yoctoproject.org/show_bug.cgi?id=16132 Alex ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core] [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES 2026-01-14 10:16 ` [OE-core] " Alexander Kanavin @ 2026-01-14 10:33 ` Richard Purdie 2026-01-14 10:50 ` Alexander Kanavin 0 siblings, 1 reply; 16+ messages in thread From: Richard Purdie @ 2026-01-14 10:33 UTC (permalink / raw) To: Alexander Kanavin, mark.hatle; +Cc: openembedded-core, Paul Barker On Wed, 2026-01-14 at 11:16 +0100, Alexander Kanavin wrote: > On Wed, 18 Jun 2025 at 01:39, Mark Hatle via lists.openembedded.org > <mark.hatle=kernel.crashing.org@lists.openembedded.org> wrote: > > - tspec['llvm-abiname'] = "lp64d" > > + tspec['llvm-abiname'] = d.getVar('TUNE_RISCV_ABI') > > if "riscv32" in tspec['llvm-target']: > > - tspec['llvm-abiname'] = "ilp32d" > > + tspec['llvm-abiname'] = d.getVar('TUNE_RISCV_ABI') > > Unfortunately this adds a dependency on TUNE_RISCV_ABI (which is set > only if the target is a risc-v machine) to rust-native's > rust_gen_targets task, breaking sstate reuse for it between risc-v and > any other target. I can imagine other native pieces written in rust > will have the same issue. > > It's not immediately obvious to me how to address this, so I'd really > appreciate suggestions. The code is hairy. > > Ticket: https://bugzilla.yoctoproject.org/show_bug.cgi?id=16132 Nice find. I worry about our sstate tests not covering this. We might need to do: -rust_gen_target[vardepsexclude] += "ABIEXTENSION llvm_cpu" +rust_gen_target[vardepsexclude] += "ABIEXTENSION llvm_cpu TUNE_RISCV_ABI" Cheers, Richard ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core] [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES 2026-01-14 10:33 ` Richard Purdie @ 2026-01-14 10:50 ` Alexander Kanavin 2026-01-14 10:57 ` Richard Purdie 0 siblings, 1 reply; 16+ messages in thread From: Alexander Kanavin @ 2026-01-14 10:50 UTC (permalink / raw) To: Richard Purdie; +Cc: mark.hatle, openembedded-core, Paul Barker On Wed, 14 Jan 2026 at 11:33, Richard Purdie <richard.purdie@linuxfoundation.org> wrote: > Nice find. I worry about our sstate tests not covering this. We might need to do: > > -rust_gen_target[vardepsexclude] += "ABIEXTENSION llvm_cpu" > +rust_gen_target[vardepsexclude] += "ABIEXTENSION llvm_cpu TUNE_RISCV_ABI" I thought of that, but would this rebuild correctly if someone first builds for one TUNE_RISCV_ABI, then for another? I just don't know enough about it to run experiments. It probably would, as that variable feeds into TUNE_CCARGS. Alex ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core] [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES 2026-01-14 10:50 ` Alexander Kanavin @ 2026-01-14 10:57 ` Richard Purdie 0 siblings, 0 replies; 16+ messages in thread From: Richard Purdie @ 2026-01-14 10:57 UTC (permalink / raw) To: Alexander Kanavin; +Cc: mark.hatle, openembedded-core, Paul Barker On Wed, 2026-01-14 at 11:50 +0100, Alexander Kanavin wrote: > On Wed, 14 Jan 2026 at 11:33, Richard Purdie > <richard.purdie@linuxfoundation.org> wrote: > > > Nice find. I worry about our sstate tests not covering this. We > > might need to do: > > > > -rust_gen_target[vardepsexclude] += "ABIEXTENSION llvm_cpu" > > +rust_gen_target[vardepsexclude] += "ABIEXTENSION llvm_cpu > > TUNE_RISCV_ABI" > > I thought of that, but would this rebuild correctly if someone first > builds for one TUNE_RISCV_ABI, then for another? I just don't know > enough about it to run experiments. It probably would, as that > variable feeds into TUNE_CCARGS. The comment above this line says: # These are accounted for in tmpdir path names so don't need to be in the task sig so in theory this would handle changes to different machines with different ABIs fine, as long as those ABIs have different tmpdir paths which they should. It doesn't guard against the value of TUNE_RISCV_ABI changing for a given target as that wouldn't rebuild correctly. I guess if we wanted to be really clear, we could probably do something like: RUSTCONFIG_EXCLUDEVARS = "" RUSTCONFIG_EXCLUDEVARS:class-native = "ABIEXTENSION llvm_cpu TUNE_RISCV_ABI" RUSTCONFIG_EXCLUDEVARS:class-nativesdk = "ABIEXTENSION llvm_cpu TUNE_RISCV_ABI" rust_gen_target[vardepsexclude] += "${RUSTCONFIG_EXCLUDEVARS}" but I guess we've not thought that was worth the effort in the past... Cheers, Richard ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [OE-core] [PATCH v2 0/7] ISA based RISC-V tune implementation 2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle ` (6 preceding siblings ...) 2025-06-17 23:39 ` [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES Mark Hatle @ 2025-06-18 19:29 ` Gyorgy Sarvari 7 siblings, 0 replies; 16+ messages in thread From: Gyorgy Sarvari @ 2025-06-18 19:29 UTC (permalink / raw) To: mark.hatle, openembedded-core On 6/18/25 01:39, Mark Hatle via lists.openembedded.org wrote: > v2: > > - Note: the linux-yocto change still needs further rework (noted in commit) > (if everything else is merged, it will still work fine) > > - Change the TUNE_FEATURES check to kernel.bbclass per review comments > > - Add 7/7 patch for RUST configuration. > Just to update my previous note: I managed to build my image on qemuriscv64 with this series, and it ran fine when I booted into it and executed my application. ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-01-14 10:57 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-17 23:39 [PATCH v2 0/7] ISA based RISC-V tune implementation Mark Hatle
2025-06-17 23:39 ` [PATCH v2 1/7] riscv tunes: ISA Implementation of RISC-V tune features Mark Hatle
2025-06-18 4:00 ` [OE-core] " Alistair Francis
2025-06-18 14:12 ` Mark Hatle
[not found] ` <184A2891E949D242.11882@lists.openembedded.org>
2025-06-18 16:50 ` Mark Hatle
2025-06-17 23:39 ` [PATCH v2 2/7] linux-yocto: Enable risc-v TUNE_FEATURES ISA selections ** DO NOT MERGE ** Mark Hatle
2025-06-17 23:39 ` [PATCH v2 3/7] u-boot: Dynamic RISC-V ISA configuration Mark Hatle
2025-06-17 23:39 ` [PATCH v2 4/7] qemuriscv: Dynamically configure qemu CPU Mark Hatle
2025-06-17 23:39 ` [PATCH v2 5/7] features_check.bbclass: Add support for required TUNE_FEATURES Mark Hatle
2025-06-17 23:39 ` [PATCH v2 6/7] kernel.bbclass: State riscv required tune_features for Linux Mark Hatle
2025-06-17 23:39 ` [PATCH v2 7/7] rust-target-config.bbclass: Update for new riscv TUNE_FEATURES Mark Hatle
2026-01-14 10:16 ` [OE-core] " Alexander Kanavin
2026-01-14 10:33 ` Richard Purdie
2026-01-14 10:50 ` Alexander Kanavin
2026-01-14 10:57 ` Richard Purdie
2025-06-18 19:29 ` [OE-core] [PATCH v2 0/7] ISA based RISC-V tune implementation Gyorgy Sarvari
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox