diff --git a/.github/setup-apt.sh b/.github/setup-apt.sh index 49efd024a8d..a470961c7f4 100755 --- a/.github/setup-apt.sh +++ b/.github/setup-apt.sh @@ -6,4 +6,4 @@ apt update apt install -y autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev \ libgmp-dev gawk build-essential bison flex texinfo gperf libtool \ patchutils bc zlib1g-dev libexpat-dev git ninja-build cmake libglib2.0-dev expect \ - device-tree-compiler + device-tree-compiler python3-pyelftools diff --git a/Makefile.in b/Makefile.in index 7b7a4dff3a1..e8443ca1ef0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -208,7 +208,7 @@ SIM_STAMP:= stamps/build-qemu stamps/install-python-package else ifeq ($(SIM),spike) # Using spike simulator. -SIM_PATH:=$(srcdir)/scripts/wrapper/spike +SIM_PATH:=$(srcdir)/scripts/wrapper/spike:$(srcdir)/scripts SIM_PREPARE:=PATH="$(SIM_PATH):$(INSTALL_DIR)/bin:$(PATH)" PK_PATH="$(INSTALL_DIR)/$(NEWLIB_TUPLE)/bin/" ARCH_STR="$(WITH_ARCH)" SIM_STAMP:= stamps/build-spike ifneq (,$(findstring rv32,$(NEWLIB_MULTILIB_NAMES))) diff --git a/scripts/march-to-cpu-opt b/scripts/march-to-cpu-opt index 493ab1399f6..f6777f4b79d 100755 --- a/scripts/march-to-cpu-opt +++ b/scripts/march-to-cpu-opt @@ -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", @@ -16,12 +16,34 @@ 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" @@ -29,8 +51,13 @@ 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 @@ -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): @@ -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 @@ -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)) diff --git a/scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run b/scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run index 93dfccf7013..fe5b1dc38e6 100755 --- a/scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run +++ b/scripts/wrapper/qemu/riscv64-unknown-linux-gnu-run @@ -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} "$@" diff --git a/scripts/wrapper/spike/riscv64-unknown-linux-gnu-run b/scripts/wrapper/spike/riscv64-unknown-linux-gnu-run index 6f5ba837349..fb569f15a82 100755 --- a/scripts/wrapper/spike/riscv64-unknown-linux-gnu-run +++ b/scripts/wrapper/spike/riscv64-unknown-linux-gnu-run @@ -1,7 +1,12 @@ -#!/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)" + +isa_option="--isa=${isa}" +varch_option="" + +[[ ! -z ${varch} ]] && varch_option="--varch=${varch}" + +spike ${isa_option} ${varch_option} ${PK_PATH}/pk${xlen} "$@"