Skip to content

Commit

Permalink
Inject CPU options to spike run test from elf file
Browse files Browse the repository at this point in the history
* Refactor CPU options for exacting common part between qemu and spike.
* Inject CPU options to spike run command line.

The below common CPU options are extracted to common part.

* xlen
* vlen
* extensions

The above CPU options will be leveraged to build the run arguments for
both the qemu and spike, for example.

QEMU: qemu-riscv64 -cpu rv64,v=true,vlen=1024,elen=64,vext_spec=v1.0
SPIKE: spike --isa=rv64imafdcv_zicsr_zifencei_zmmul --varch=vlen:1024,elen:64

Signed-off-by: Pan Li <[email protected]>
  • Loading branch information
Incarnation-p-lee committed Nov 21, 2023
1 parent 82c3d65 commit 1749dfb
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 40 deletions.
127 changes: 95 additions & 32 deletions scripts/march-to-cpu-opt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import elftools.elf.elffile
import elftools.elf.enums
import elftools.elf.sections

EXT_OPTS = {
QEMU_EXT_OPTS = {
"zba": "zba=true",
"zbb": "zbb=true",
"zbc": "zbc=true",
Expand All @@ -16,21 +16,48 @@ EXT_OPTS = {
"zve32f": "Zve32f=true",
"zve64f": "Zve64f=true",
"zfh": "Zfh=true",
"zfhmin": "Zfhmin=true",
"zfhmin": "Zfhmin=true",
"zhinx": "zhinx=true",
"zfinx": "zfinx=true",
"zdinx": "zdinx=true",
}

SPIKE_EXT_NOT_ALLOWED = [
"zve32x",
"zve32f",
"zve64x",
"zve64f",
"zve64d",
"zvl32b",
"zvl64b",
"zvl128b",
"zvl256b",
"zvl512b",
"zvl1024b",
"zvl2048b",
"zvl4096b",
]

CPU_OPTIONS = {
"xlen": "",
"vlen": "",
"extensions": [],
}

SUPPORTTED_EXTS = "iemafdcbvph"
MC_EXT_PREFIX = "zsx"

def parse_opt(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-march', '--with-arch', type=str, dest='march')
parser.add_argument('-selftest', action='store_true')
parser.add_argument('--get-riscv-tag', type=str)
parser.add_argument('--get-elf-class', type=str)
parser.add_argument('--elf-file-path', type=str)
parser.add_argument('--print-xlen', action='store_true', default=False)
parser.add_argument('--print-vlen', action='store_true', default=False)
parser.add_argument('--print-qemu-cpu', action='store_true', default=False)
parser.add_argument('--print-spike-isa', action='store_true', default=False)
parser.add_argument('--print-spike-varch', action='store_true',
default=False)
opt = parser.parse_args()
return opt

Expand Down Expand Up @@ -119,31 +146,47 @@ def get_vlen(ext_dict):
vlen = max(vlen, zvelen)
return vlen

def conver_arch_to_qemu_cpu_opt(march):
if len(march) < 5:
return None

ext_dict = parse_march(march)

cpu_opt = []
cpu_opt.append(march[0:4]) # rv32 or rv64

vlen = get_vlen(ext_dict)
def print_qemu_cpu():
cpu_options = []
cpu_options.append("rv{0}".format(CPU_OPTIONS['xlen']))

if vlen != 0:
cpu_opt.append("vlen=%d" % vlen)
if CPU_OPTIONS['vlen']:
cpu_options.append("vlen={0}".format(CPU_OPTIONS['vlen']))

disable_all_fd = False
for ext in ext_dict.keys():
if ext in EXT_OPTS:
cpu_opt.append(EXT_OPTS[ext])
for ext in CPU_OPTIONS['extensions']:
if ext in QEMU_EXT_OPTS:
cpu_options.append(QEMU_EXT_OPTS[ext])

if ext in ['zhinx', 'zfinx', 'zdinx']:
disable_all_fd = True

if disable_all_fd:
cpu_opt.append("f=false")
cpu_opt.append("d=false")
return ",".join(cpu_opt)
cpu_options.append("f=false")
cpu_options.append("d=false")

return ",".join(cpu_options)

def print_spike_isa():
cpu_options = []
cpu_options.append("rv{0}".format(CPU_OPTIONS['xlen']))

for ext in CPU_OPTIONS['extensions']:
if ext not in SPIKE_EXT_NOT_ALLOWED:
normalized_ext_name = ext

if len(ext) > 1:
normalized_ext_name = "_{0}".format(normalized_ext_name)

cpu_options.append(normalized_ext_name)

return "".join(cpu_options)

def print_spike_varch():
if not CPU_OPTIONS['vlen']:
return ""

return "vlen:{0},elen:{1}".format(CPU_OPTIONS['vlen'], CPU_OPTIONS['xlen'])

class TestArchStringParse(unittest.TestCase):
def _test(self, arch, expected_arch_list, expected_vlen=0):
Expand All @@ -168,7 +211,7 @@ def open_elf(path):
raise Exception("%s is not ELF file!" % path)
return elffile

def read_elf_class(path):
def get_xlen(path):
elffile = open_elf(path)
return elffile.elfclass

Expand Down Expand Up @@ -204,21 +247,41 @@ def read_arch_attr (path):
return val
raise Exception("Not found ELF attribute in %s?" % path)

def parse_elf_file(elf_file_path):
extensions = []
extension_dict = parse_march(read_arch_attr(elf_file_path))

for extension in extension_dict.keys():
extensions.append(extension)

CPU_OPTIONS["extensions"] = extensions
CPU_OPTIONS["vlen"] = get_vlen(extension_dict)
CPU_OPTIONS["xlen"] = get_xlen(elf_file_path)

def main(argv):
opt = parse_opt(argv)
if opt.selftest:
selftest()
return 0
if (opt.get_elf_class):
elf_class = read_elf_class (opt.get_elf_class)
print (elf_class)

parse_elf_file(opt.elf_file_path)

if opt.print_xlen:
print(CPU_OPTIONS['xlen'])
return
if (opt.get_riscv_tag):
march = read_arch_attr (opt.get_riscv_tag)
else:
march = opt.march
cpu_opt = conver_arch_to_qemu_cpu_opt(march)
print (cpu_opt)

if opt.print_vlen:
print(CPU_OPTIONS['vlen'])
return

if opt.print_qemu_cpu:
print(print_qemu_cpu())

if opt.print_spike_isa:
print(print_spike_isa())

if opt.print_spike_varch:
print(print_spike_varch())

if __name__ == '__main__':
sys.exit(main(sys.argv))
6 changes: 4 additions & 2 deletions scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ do
shift
done

xlen="$(march-to-cpu-opt --get-elf-class $1)"
xlen="$(march-to-cpu-opt --elf-file-path $1 --print-xlen)"
qemu_cpu="$(march-to-cpu-opt --elf-file-path $1 --print-qemu-cpu)"

QEMU_CPU="$(march-to-cpu-opt --get-riscv-tag $1)" qemu-riscv$xlen -r 5.10 "${qemu_args[@]}" -L ${RISC_V_SYSROOT} "$@"
QEMU_CPU="${qemu_cpu}" qemu-riscv${xlen} -r 5.10 "${qemu_args[@]}" \
-L ${RISC_V_SYSROOT} "$@"
13 changes: 7 additions & 6 deletions scripts/wrapper/spike/riscv64-unknown-linux-gnu-run
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#!/bin/sh
#!/bin/bash

xlen="$(readelf -h $1 | grep 'Class' | cut -d: -f 2 | xargs echo | sed 's/^ELF//')"
arch="${ARCH_STR#*=}"
spike \
--isa=${arch} \
${PK_PATH}/pk${xlen} "$@"
xlen="$(march-to-cpu-opt --elf-file-path $1 --print-xlen)"
isa="$(march-to-cpu-opt --elf-file-path $1 --print-spike-isa)"
varch="$(march-to-cpu-opt --elf-file-path $1 --print-spike-varch)"

[[ -z ${varch} ]] && spike --isa=${isa} ${PK_PATH}/pk${xlen} "$@"
[[ ! -z ${varch} ]] && spike --isa=${isa} --varch=${varch} ${PK_PATH}/pk${xlen} "$@"

0 comments on commit 1749dfb

Please sign in to comment.