diff --git a/.github/workflows/tests_archdetect.yml b/.github/workflows/tests_archdetect.yml index 891669a2..b4d2e41e 100644 --- a/.github/workflows/tests_archdetect.yml +++ b/.github/workflows/tests_archdetect.yml @@ -25,9 +25,13 @@ jobs: - aarch64/neoverse_v1/AWS-awslinux-graviton3 - aarch64/nvidia/grace/Jureca-Rocky95 - aarch64/google/axion/GCP-axion - - riscv64/sifive/premier-Ubuntu24 + - riscv64/sifive/p550/premier-Ubuntu24 + - riscv64/sifive/u74-mc/starvision-Ubuntu24 - riscv64/spacemit/bananaf3-Armbian - riscv64/spacemit/bananaf3-k6.6 + - riscv64/generic/rva20u64/synthetic + - riscv64/generic/rva22u64/synthetic + - riscv64/generic/rva23u64/synthetic # commented out since these targets are currently not supported in software.eessi.io repo # (and some tests assume that the corresponding subdirectory in software layer is there) # - ppc64le/power9le/unknown-power9le diff --git a/init/arch_specs/eessi_arch_riscv.spec b/init/arch_specs/eessi_arch_riscv.spec index aa56fcaa..6c7c3c62 100644 --- a/init/arch_specs/eessi_arch_riscv.spec +++ b/init/arch_specs/eessi_arch_riscv.spec @@ -1,7 +1,49 @@ # RISC-V CPU architecture specifications (see https://github.com/riscv/learn?tab=readme-ov-file#open-risc-v-implementations) # CPU vendors: SiFive (0x489), Spacemit (0x710) +# Spec lines must not use parentheses in trailing comments: update_arch_specs evals each line. +# +# Profile paths generic/rva*: empty Vendor ID means any vendor. Compact base ISA +# blobs like rv64imafdc are letter-expanded at match time in eessi_archdetect.sh. +# +# Matching floors ≈ detectable mandatory userspace ISA subset of the official +# RVA*U64 profiles — not optarch/-march assumptions. Sources: +# RVA20U64: https://docs.riscv.org/reference/rva20-rvi20-rva22/v1.0/rva20.html +# RVA22U64: https://docs.riscv.org/reference/rva20-rvi20-rva22/v1.0/rva22.html +# RVA23U64: https://docs.riscv.org/reference/rva23/v1.0/rva23-profiles.html +# Profiles repo: https://github.com/riscv/riscv-profiles +# +# Only tokens that can appear in Linux /proc/cpuinfo isa are required. Official +# mandates that are PMA / behaviour / EE contracts and are not advertised as +# cpuinfo extension tokens are omitted from floors (still mandated by the +# profile text): +# RVA20+: Ziccif, Ziccrse, Ziccamoa, Zicclsm; Za128rs (RVA20) / Za64rs (RVA22+) +# RVA22+: Zic64b +# RVA23+: Supm (pointer-masking EE contract; not a stable cpuinfo token yet) +# B in RVA23 is Zba+Zbb+Zbs; floors require those named extensions, not letter b. +# +# Floors (detectable mandatory subset): +# rva20u64: rv64imafdc zicsr zicntr zifencei +# rva22u64: + zihpm zihintpause zba zbb zbs zicbom zicbop zicboz zfhmin zkt +# rva23u64: + v zihintntl zicond zimop zcmop zcb zfa zawrs zvfhmin zvbb zvkt +# and retains zicbo* from RVA22 (still mandatory in RVA23) +# Vendor paths require the *full* measured /proc/cpuinfo isa from the matching +# archdetect fixture, not a truncated userspace subset. That includes S-mode +# tokens when the board advertises them, e.g. sscofpmf / sstc / sv*. A host +# whose kernel drops any required vendor token will miss that path and may fall +# through to generic/rva* — intentional for vendor-specific software trees. +# SpacemiT AI / custom bits such as xsmtvdot are omitted until a fixture isa +# line advertises them. x60 vs x60-k6.6 are two kernel views of the same SoC; +# neither is a clean rva22u64 host. Fixture sources: +# sifive/p550 <- tests/.../sifive/p550/premier-Ubuntu24.cpuinfo +# sifive/u74-mc <- tests/.../sifive/u74-mc/starvision-Ubuntu24.cpuinfo +# spacemit/x60 <- tests/.../spacemit/bananaf3-Armbian.cpuinfo +# spacemit/x60-k6.6 <- tests/.../spacemit/bananaf3-k6.6.cpuinfo # Software path in EESSI | Vendor ID | List of defining CPU features -"riscv64/sifive/p550" "0x489" "rv64imafdch_zicsr_zifencei_zba_zbb_sscofpmf" # HiFive Premier P550 -"riscv64/spacemit/x60" "0x710" "rv64imafdcv_sscofpmf_sstc_svpbmt_zicbom_zicboz_zicbop_zihintpause" # Banana Pi F3 -"riscv64/spacemit/x60-k6.6" "0x710" "rv64imafdcv_zicbom_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zfhmin_zca_zcd_zba_zbb_zbc_zbs_zkt_zve32f_zve32x_zve64d_zve64f_zve64x_zvfh_zvfhmin_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt" # Banana Pi F3 k6.6 +"riscv64/generic/rva20u64" "" "rv64imafdc zicsr zicntr zifencei" +"riscv64/generic/rva22u64" "" "rv64imafdc zicsr zicntr zifencei zihpm zihintpause zba zbb zbs zicbom zicbop zicboz zfhmin zkt" +"riscv64/generic/rva23u64" "" "rv64imafdcv zicsr zicntr zifencei zihpm zihintpause zihintntl zba zbb zbs zicbom zicbop zicboz zfhmin zkt zicond zimop zcmop zcb zfa zawrs zvfhmin zvbb zvkt" +"riscv64/sifive/p550" "0x489" "rv64imafdch zicsr zifencei zba zbb sscofpmf" # full measured P550 isa +"riscv64/sifive/u74-mc" "0x489" "rv64imafdc zicntr zicsr zifencei zihpm zca zcd zba zbb" # full measured VisionFive 2 isa +"riscv64/spacemit/x60" "0x710" "rv64imafdcv sscofpmf sstc svpbmt zicbom zicboz zicbop zihintpause" # full Armbian-short isa +"riscv64/spacemit/x60-k6.6" "0x710" "rv64imafdcv zicbom zicboz zicntr zicond zicsr zifencei zihintpause zihpm zfh zfhmin zca zcd zba zbb zbc zbs zkt zve32f zve32x zve64d zve64f zve64x zvfh zvfhmin zvkt sscofpmf sstc svinval svnapot svpbmt" # full k6.6 isa diff --git a/init/eessi_archdetect.sh b/init/eessi_archdetect.sh index 64d4131f..8fce5520 100755 --- a/init/eessi_archdetect.sh +++ b/init/eessi_archdetect.sh @@ -17,7 +17,7 @@ else exit 1 fi -VERSION="1.2.0" +VERSION="1.3.0" # default log level: only emit warnings or errors LOG_LEVEL="WARN" @@ -55,7 +55,7 @@ update_arch_specs(){ # format spec line as an array and append it to array with all CPU arch specs cpu_arch_spec+=("(${spec_line})") # remove comments from spec file - done < <(sed -E 's/(^|[\s\t])#.*$//g;/^\s*$/d' "$spec_file") + done < <(sed -E 's/(^|[[:space:]])#.*$//g;/^[[:space:]]*$/d' "$spec_file") } # CPU specification of host system @@ -64,7 +64,7 @@ get_cpuinfo(){ # 1: string with key pattern [ -z "$1" ] && log "ERROR" "get_cpuinfo: missing key pattern in argument list" - cpuinfo_pattern="^${1}\s*:\s*" + cpuinfo_pattern="^${1}[[:space:]]*:[[:space:]]*" # case insensitive match of key pattern and delete key pattern from result grep -i "$cpuinfo_pattern" ${EESSI_PROC_CPUINFO:-/proc/cpuinfo} | tail -n 1 | sed "s/$cpuinfo_pattern//i" @@ -85,6 +85,29 @@ check_allinfirst(){ return 0 } +riscv_expand_base(){ + # Expand compact RISC-V base ISA blobs into per-letter tokens at match time. + # Host /proc/cpuinfo and eessi_arch_riscv.spec both use concatenated forms + # (e.g. rv64imafdch); without expansion a superset host like rv64imafdcvh + # fails a subset spec asking for rv64imafdch because the whole blob is one + # token. Expand both sides so specs stay readable and letter-wise subsets match. + # rv64imafdch -> rv64 i m a f d c h + # rv64gc -> rv64 i m a f d c (g is the IMAFD shorthand) + # Multi-letter extensions (zicsr, zba, sscofpmf, ...) pass through unchanged. + local out="" tok letters + for tok in "$@"; do + if [ "${tok#rv64}" != "${tok}" ]; then + # Replace g with imafd before letter-splitting; then split to tokens + letters=$(printf '%s' "${tok#rv64}" | sed 's/g/imafd/g; s/./& /g') + out="${out} rv64 ${letters}" + else + out="${out} ${tok}" + fi + done + # Normalise whitespace so callers can word-split safely (no empty tokens) + printf '%s' "${out}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/[[:space:]]\{1,\}/ /g' +} + cpupath(){ # If EESSI_SOFTWARE_SUBDIR_OVERRIDE is set, use it log "DEBUG" "cpupath: Override variable set as '$EESSI_SOFTWARE_SUBDIR_OVERRIDE' " @@ -154,6 +177,14 @@ cpupath(){ fi local cpu_flags=$(get_cpuinfo "$cpu_flag_tag") + if [ "${machine_type}" == "riscv64" ]; then + # RISC-V ISA strings use '_' as extension separators. + # Convert them to space-separated feature tokens so they + # can be matched like x86 CPU flags, then expand the compact + # base blob (rv64imafdc...) into per-letter tokens. + cpu_flags=${cpu_flags//_/ } + cpu_flags=$(riscv_expand_base ${cpu_flags}) + fi log "DEBUG" "cpupath: CPU flags of host system: '$cpu_flags'" # Default to generic CPU @@ -164,11 +195,19 @@ cpupath(){ # Order of the specifications matters, the last one to match will be selected for arch in "${cpu_arch_spec[@]}"; do eval "arch_spec=$arch" - if [ "${cpu_vendor}x" == "${arch_spec[1]}x" ]; then + # Empty vendor in the spec means "any vendor" (profile paths like riscv64/generic/rva*). + # Vendor-specific entries still require an exact match (same as before). + if [ -z "${arch_spec[1]}" ] || [ "${cpu_vendor}x" == "${arch_spec[1]}x" ]; then # each flag in this CPU specification must be found in the list of flags of the host - check_allinfirst "${cpu_flags[*]}" ${arch_spec[2]} && best_arch_match=${arch_spec[0]} && \ - all_arch_matches="$best_arch_match:$all_arch_matches" && \ - log "DEBUG" "cpupath: host CPU best match updated to $best_arch_match" + if [ "${machine_type}" == "riscv64" ]; then + check_allinfirst "${cpu_flags}" $(riscv_expand_base ${arch_spec[2]}) && best_arch_match=${arch_spec[0]} && \ + all_arch_matches="$best_arch_match:$all_arch_matches" && \ + log "DEBUG" "cpupath: host CPU best match updated to $best_arch_match" + else + check_allinfirst "${cpu_flags[*]}" ${arch_spec[2]} && best_arch_match=${arch_spec[0]} && \ + all_arch_matches="$best_arch_match:$all_arch_matches" && \ + log "DEBUG" "cpupath: host CPU best match updated to $best_arch_match" + fi fi done diff --git a/tests/archdetect/riscv64/generic/rva20u64/synthetic.all.output b/tests/archdetect/riscv64/generic/rva20u64/synthetic.all.output new file mode 100644 index 00000000..aff95fb3 --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva20u64/synthetic.all.output @@ -0,0 +1 @@ +riscv64/generic/rva20u64:riscv64/generic diff --git a/tests/archdetect/riscv64/generic/rva20u64/synthetic.cpuinfo b/tests/archdetect/riscv64/generic/rva20u64/synthetic.cpuinfo new file mode 100644 index 00000000..17ce8dba --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva20u64/synthetic.cpuinfo @@ -0,0 +1,10 @@ +# Synthetic RVA20U64-floor host: unknown vendor so only empty-vendor profile +# entries can match (not sifive/spacemit vendor lines). Floor is the detectable +# mandatory RVA20U64 subset: rv64imafdc zicsr zicntr. +processor : 0 +hart : 0 +isa : rv64imafdc_zicsr_zifencei_zicntr +mmu : sv39 +mvendorid : 0x123 +marchid : 0x0 +mimpid : 0x0 diff --git a/tests/archdetect/riscv64/generic/rva20u64/synthetic.output b/tests/archdetect/riscv64/generic/rva20u64/synthetic.output new file mode 100644 index 00000000..080a6fd0 --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva20u64/synthetic.output @@ -0,0 +1 @@ +riscv64/generic/rva20u64 diff --git a/tests/archdetect/riscv64/generic/rva22u64/synthetic.all.output b/tests/archdetect/riscv64/generic/rva22u64/synthetic.all.output new file mode 100644 index 00000000..cb1f814a --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva22u64/synthetic.all.output @@ -0,0 +1 @@ +riscv64/generic/rva22u64:riscv64/generic/rva20u64:riscv64/generic diff --git a/tests/archdetect/riscv64/generic/rva22u64/synthetic.cpuinfo b/tests/archdetect/riscv64/generic/rva22u64/synthetic.cpuinfo new file mode 100644 index 00000000..b3a85a4f --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva22u64/synthetic.cpuinfo @@ -0,0 +1,10 @@ +# Synthetic RVA22U64-floor host: unknown vendor; ISA tokens match the +# detectable mandatory RVA22U64 subset (base + zihpm/zihintpause/bitmanip/ +# zfhmin/zicbo*/zkt). +processor : 0 +hart : 0 +isa : rv64imafdc_zicsr_zifencei_zicntr_zihpm_zihintpause_zba_zbb_zbs_zicbom_zicbop_zicboz_zfhmin_zkt +mmu : sv39 +mvendorid : 0x123 +marchid : 0x0 +mimpid : 0x0 diff --git a/tests/archdetect/riscv64/generic/rva22u64/synthetic.output b/tests/archdetect/riscv64/generic/rva22u64/synthetic.output new file mode 100644 index 00000000..36431a2a --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva22u64/synthetic.output @@ -0,0 +1 @@ +riscv64/generic/rva22u64 diff --git a/tests/archdetect/riscv64/generic/rva23u64/synthetic.all.output b/tests/archdetect/riscv64/generic/rva23u64/synthetic.all.output new file mode 100644 index 00000000..3343fc55 --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva23u64/synthetic.all.output @@ -0,0 +1 @@ +riscv64/generic/rva23u64:riscv64/generic/rva22u64:riscv64/generic/rva20u64:riscv64/generic diff --git a/tests/archdetect/riscv64/generic/rva23u64/synthetic.cpuinfo b/tests/archdetect/riscv64/generic/rva23u64/synthetic.cpuinfo new file mode 100644 index 00000000..8dec5baa --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva23u64/synthetic.cpuinfo @@ -0,0 +1,11 @@ +# Synthetic RVA23U64-floor host: unknown vendor; ISA tokens cover the +# detectable mandatory RVA23U64 subset (includes V, zicbo*, zicond, zimop/ +# zcmop, zcb, zfa, zawrs, vector crypto-adjacent zv*, etc.) so the host also +# matches the rva22 and rva20 floors. +processor : 0 +hart : 0 +isa : rv64imafdcv_zicsr_zifencei_zicntr_zihpm_zihintpause_zihintntl_zba_zbb_zbs_zicbom_zicbop_zicboz_zfhmin_zkt_zicond_zimop_zcmop_zcb_zfa_zawrs_zvfhmin_zvbb_zvkt +mmu : sv39 +mvendorid : 0x123 +marchid : 0x0 +mimpid : 0x0 diff --git a/tests/archdetect/riscv64/generic/rva23u64/synthetic.output b/tests/archdetect/riscv64/generic/rva23u64/synthetic.output new file mode 100644 index 00000000..cc3cee01 --- /dev/null +++ b/tests/archdetect/riscv64/generic/rva23u64/synthetic.output @@ -0,0 +1 @@ +riscv64/generic/rva23u64 diff --git a/tests/archdetect/riscv64/sifive/premier-Ubuntu24.all.output b/tests/archdetect/riscv64/sifive/p550/premier-Ubuntu24.all.output similarity index 100% rename from tests/archdetect/riscv64/sifive/premier-Ubuntu24.all.output rename to tests/archdetect/riscv64/sifive/p550/premier-Ubuntu24.all.output diff --git a/tests/archdetect/riscv64/sifive/premier-Ubuntu24.cpuinfo b/tests/archdetect/riscv64/sifive/p550/premier-Ubuntu24.cpuinfo similarity index 100% rename from tests/archdetect/riscv64/sifive/premier-Ubuntu24.cpuinfo rename to tests/archdetect/riscv64/sifive/p550/premier-Ubuntu24.cpuinfo diff --git a/tests/archdetect/riscv64/sifive/premier-Ubuntu24.output b/tests/archdetect/riscv64/sifive/p550/premier-Ubuntu24.output similarity index 100% rename from tests/archdetect/riscv64/sifive/premier-Ubuntu24.output rename to tests/archdetect/riscv64/sifive/p550/premier-Ubuntu24.output diff --git a/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.all.output b/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.all.output new file mode 100644 index 00000000..411fdbac --- /dev/null +++ b/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.all.output @@ -0,0 +1 @@ +riscv64/sifive/u74-mc:riscv64/generic/rva20u64:riscv64/generic diff --git a/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.cpuinfo b/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.cpuinfo new file mode 100644 index 00000000..0a714672 --- /dev/null +++ b/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.cpuinfo @@ -0,0 +1,9 @@ +processor : 0 +hart : 1 +isa : rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd_zba_zbb +mmu : sv39 +uarch : sifive,u74-mc +mvendorid : 0x489 +marchid : 0x8000000000000007 +mimpid : 0x4210427 +hart isa : rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd_zba_zbb diff --git a/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.output b/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.output new file mode 100644 index 00000000..aa779a2b --- /dev/null +++ b/tests/archdetect/riscv64/sifive/u74-mc/starvision-Ubuntu24.output @@ -0,0 +1 @@ +riscv64/sifive/u74-mc diff --git a/tests/archdetect/riscv64/spacemit/bananaf3-k6.6.all.output b/tests/archdetect/riscv64/spacemit/bananaf3-k6.6.all.output index e514227d..41bee6eb 100644 --- a/tests/archdetect/riscv64/spacemit/bananaf3-k6.6.all.output +++ b/tests/archdetect/riscv64/spacemit/bananaf3-k6.6.all.output @@ -1 +1 @@ -riscv64/spacemit/x60-k6.6:riscv64/generic +riscv64/spacemit/x60-k6.6:riscv64/generic/rva20u64:riscv64/generic