Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/tests_archdetect.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
48 changes: 45 additions & 3 deletions init/arch_specs/eessi_arch_riscv.spec
Original file line number Diff line number Diff line change
@@ -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
53 changes: 46 additions & 7 deletions init/eessi_archdetect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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"
Expand All @@ -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' "
Expand Down Expand Up @@ -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
Comment on lines +180 to +187

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the format is open: the leading rv64imafdch blob still matches as one token, so a superset host (say rv64imafdcvh) fails a spec asking rv64imafdch.
Splitting the blob into per-letter tokens would make the base extensions individually matchable, which I think is what the description is going for?
If the expansion happens on both sides at match time, the spec files keep the readable concatenated form, something like

riscv_expand_base(){
    # rv64imafdch -> rv64 i m a f d c h ; every other token passes through
    local out="" tok
    for tok in "$@"; do
        if [ "${tok#rv64}" != "${tok}" ]; then
            out="${out} rv64 $(printf '%s' "${tok#rv64}" | sed 's/./& /g')"
        else
            out="${out} ${tok}"
        fi
    done
    printf '%s' "${out}"
}

# here, for the host flags:
cpu_flags=$(riscv_expand_base ${cpu_flags})

# and at the match, for the spec side:
check_allinfirst "${cpu_flags[*]}" $(riscv_expand_base ${arch_spec[2]})

so a superset host matches any subset spec without the spec files caring how the kernel concatenated the letters.
Also trailing whitespace on this line, and the comment block is tab-indented against the file.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — done on this PR (tip 3d7f7e5; landed in 2e67c0d).

riscv_expand_base() expands compact rv64* blobs into per-letter tokens at match time on both host flags and the spec side (rv64imafdchrv64 i m a f d c h; gimafd before splitting). Multi-letter extensions pass through. Superset hosts now match subset specs without changing the readable concatenated form in eessi_arch_riscv.spec.

Also cleaned the trailing whitespace / indentation on that block.

log "DEBUG" "cpupath: CPU flags of host system: '$cpu_flags'"

# Default to generic CPU
Expand All @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
riscv64/generic/rva20u64:riscv64/generic
10 changes: 10 additions & 0 deletions tests/archdetect/riscv64/generic/rva20u64/synthetic.cpuinfo
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions tests/archdetect/riscv64/generic/rva20u64/synthetic.output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
riscv64/generic/rva20u64
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
riscv64/generic/rva22u64:riscv64/generic/rva20u64:riscv64/generic
10 changes: 10 additions & 0 deletions tests/archdetect/riscv64/generic/rva22u64/synthetic.cpuinfo
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions tests/archdetect/riscv64/generic/rva22u64/synthetic.output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
riscv64/generic/rva22u64
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
riscv64/generic/rva23u64:riscv64/generic/rva22u64:riscv64/generic/rva20u64:riscv64/generic
11 changes: 11 additions & 0 deletions tests/archdetect/riscv64/generic/rva23u64/synthetic.cpuinfo
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions tests/archdetect/riscv64/generic/rva23u64/synthetic.output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
riscv64/generic/rva23u64
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
riscv64/sifive/u74-mc:riscv64/generic/rva20u64:riscv64/generic
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
riscv64/sifive/u74-mc
2 changes: 1 addition & 1 deletion tests/archdetect/riscv64/spacemit/bananaf3-k6.6.all.output
Original file line number Diff line number Diff line change
@@ -1 +1 @@
riscv64/spacemit/x60-k6.6:riscv64/generic
riscv64/spacemit/x60-k6.6:riscv64/generic/rva20u64:riscv64/generic