diff options
author | John Toomey <john.toomey@amd.com> | 2024-05-22 11:37:19 +0100 |
---|---|---|
committer | Mark Hatle <mark.hatle@amd.com> | 2024-11-21 10:35:27 -0600 |
commit | 5abe2c2c45e02e037f234b05f2ad0017ca7605fa (patch) | |
tree | f75480145f0a7cbec003f77ea45b84ef52c37f4c /meta-xilinx-core/recipes-devtools | |
parent | 111172b6ec6d26664e62e426b37ccdf5233607d1 (diff) | |
download | meta-xilinx-5abe2c2c45e02e037f234b05f2ad0017ca7605fa.tar.gz |
qemu-system-aarch64-multiarch: Add -bootbin flag
Add support for booting QEMU using a static BOOT.bin file (or OSPI file
with a boot.bin at offset 0x00000000) - the required firmware components
are extracted from the boot.bin and offsets read from the header using
bootgen.
Signed-off-by: John Toomey <john.toomey@amd.com>
Signed-off-by: Mark Hatle <mark.hatle@amd.com>
Diffstat (limited to 'meta-xilinx-core/recipes-devtools')
-rw-r--r-- | meta-xilinx-core/recipes-devtools/qemu/files/qemu-system-aarch64-multiarch | 76 | ||||
-rw-r--r-- | meta-xilinx-core/recipes-devtools/qemu/qemu-xilinx-system-native_8.1.0.bb | 2 |
2 files changed, 54 insertions, 24 deletions
diff --git a/meta-xilinx-core/recipes-devtools/qemu/files/qemu-system-aarch64-multiarch b/meta-xilinx-core/recipes-devtools/qemu/files/qemu-system-aarch64-multiarch index 1dcac990..2b13908d 100644 --- a/meta-xilinx-core/recipes-devtools/qemu/files/qemu-system-aarch64-multiarch +++ b/meta-xilinx-core/recipes-devtools/qemu/files/qemu-system-aarch64-multiarch | |||
@@ -5,12 +5,12 @@ import os | |||
5 | import subprocess | 5 | import subprocess |
6 | import sys | 6 | import sys |
7 | import tempfile | 7 | import tempfile |
8 | import re | ||
8 | import shutil | 9 | import shutil |
9 | 10 | ||
10 | binpath = os.path.dirname(os.path.abspath(__file__)) | 11 | binpath = os.path.dirname(os.path.abspath(__file__)) |
11 | mach_path = tempfile.mkdtemp() | 12 | mach_path = tempfile.mkdtemp() |
12 | 13 | ||
13 | |||
14 | # Separate PMU and APU arguments | 14 | # Separate PMU and APU arguments |
15 | APU_args = sys.argv[1:] | 15 | APU_args = sys.argv[1:] |
16 | PMU_args = [] | 16 | PMU_args = [] |
@@ -26,50 +26,80 @@ if '-plm-args' in APU_args: | |||
26 | PLM_args = APU_args[plm_args_idx+1].split() | 26 | PLM_args = APU_args[plm_args_idx+1].split() |
27 | del APU_args[plm_args_idx:plm_args_idx+2] | 27 | del APU_args[plm_args_idx:plm_args_idx+2] |
28 | 28 | ||
29 | if '-bootbin' in APU_args: | ||
30 | bootbin_args_idx = APU_args.index('-bootbin') | ||
31 | bootbin_arg = APU_args[bootbin_args_idx+1] | ||
32 | del APU_args[bootbin_args_idx:bootbin_args_idx+2] | ||
33 | |||
29 | if PMU_args and PLM_args: | 34 | if PMU_args and PLM_args: |
30 | sys.exit("\nError: -pmu-args can not be used with -plm-args\n") | 35 | sys.exit("\nError: -pmu-args can not be used with -plm-args\n") |
31 | 36 | ||
32 | if ('--help' in APU_args) or (not PMU_args and not PLM_args): | 37 | if ('--help' in APU_args) or (not PMU_args and not PLM_args): |
33 | print("AMD FPGA QEMU multiarch wrapper\n") | 38 | print("AMD FPGA QEMU multiarch wrapper\nVersion 2024.1\n\nUsage:") |
34 | print("Version 2024.1") | 39 | print(f" {sys.argv[0]} <APU options> [-pmu-args <pmu options>]") |
35 | print("") | 40 | print(f" {sys.argv[0]} <APU options> [-plm-args <plm options>]\n") |
36 | print("Usage:") | ||
37 | print(" %s <APU options> [-pmu-args <pmu options>]" % (sys.argv[0])) | ||
38 | print(" %s <APU options> [-plm-args <plm options>]" % (sys.argv[0])) | ||
39 | print("") | ||
40 | sys.exit(1) | 41 | sys.exit(1) |
41 | 42 | ||
42 | if PMU_args: | 43 | if PMU_args: |
43 | PMU_rom = PMU_args[PMU_args.index('-kernel')+1] | 44 | PMU_rom = PMU_args[PMU_args.index('-kernel')+1] |
44 | 45 | ||
45 | if not os.path.exists(PMU_rom): | 46 | if not os.path.exists(PMU_rom): |
46 | error_msg = '\nError: Missing PMU ROM: %s' % PMU_rom | 47 | sys.exit(f'\nERROR: Missing PMU ROM: {PMU_rom}' |
47 | error_msg += '\nSee "meta-xilinx/README.qemu.md" for more information on accquiring the PMU ROM.\n' | 48 | '\nSee "meta-xilinx/README.qemu.md" for more information on accquiring the PMU ROM.\n') |
48 | sys.exit(error_msg) | 49 | |
50 | if bootbin_arg: | ||
51 | if not os.path.isfile(bootbin_arg): | ||
52 | print(f"\nERROR: bootbin file not found at {bootbin_arg}" | ||
53 | " Please build and ospi_image or set QB_OSPI_BIN variable to prebuilt file\n") | ||
54 | sys.exit(1) | ||
55 | |||
56 | shutil.copyfile(bootbin_arg, f'{mach_path}/boot.bin') | ||
57 | |||
58 | bootgen_command = [f'{binpath}/bootgen', '-arch', 'versal', '-dump', 'boot.bin'] | ||
59 | subprocess.run(bootgen_command + ['bh'], check=True, cwd=mach_path, stdout=subprocess.DEVNULL) | ||
60 | subprocess.run(bootgen_command + ['plm'], check=True, cwd=mach_path, stdout=subprocess.DEVNULL) | ||
61 | subprocess.run(bootgen_command + ['pmc_cdo'], check=True, cwd=mach_path, stdout=subprocess.DEVNULL) | ||
62 | |||
63 | bootgen_command = f"{binpath}/bootgen -arch versal -read {bootbin_arg}" | ||
64 | result = subprocess.check_output(bootgen_command.split()) | ||
65 | bootgen_output = result.decode().splitlines() | ||
66 | |||
67 | for i, l in enumerate(bootgen_output): | ||
68 | if 'PARTITION HEADER TABLE (pmc_subsys.0.0)' in l: | ||
69 | plm_line = bootgen_output[i+4] | ||
70 | if 'BOOT HEADER' in l: | ||
71 | pmc_line = bootgen_output[i+6] | ||
49 | 72 | ||
50 | # We need to switch tcp serial arguments (if they exist, e.g. qemurunner) to get the output correctly | 73 | plm_load_addr = re.search(r"exec_addr_lo \(0x10\) : (0x\w*)\s*", plm_line).group(1) |
74 | pmc_load_addr = re.search(r"pmccdo_load_addr \(0x20\) : (0x\w*)", pmc_line).group(1) | ||
75 | |||
76 | PLM_args.append(f"-device loader,file={mach_path}/boot_bh.bin,addr=0xF201E000,force-raw=on") | ||
77 | PLM_args.append(f"-device loader,file={mach_path}/pmc_cdo.bin,addr={pmc_load_addr},force-raw=on") | ||
78 | PLM_args.append(f"-device loader,file={mach_path}/plm.bin,addr={plm_load_addr},force-raw=on") | ||
79 | PLM_args.append(f"-device loader,addr={plm_load_addr},cpu-num=1") | ||
80 | |||
81 | # We need to switch tcp serial arguments (if they exist, e.g. qemurunner) to get the output | ||
51 | tcp_serial_ports = [i for i, s in enumerate(APU_args) if 'tcp:127.0.0.1:' in s] | 82 | tcp_serial_ports = [i for i, s in enumerate(APU_args) if 'tcp:127.0.0.1:' in s] |
52 | 83 | ||
53 | #NEED TO FIX for next yocto release (dont need to switch ports anymore, they will be provided correctly upstream | 84 | #FIXME for next yocto release (dont need to switch ports anymore, they will be provided correctly upstream |
54 | # We can only switch these if there are exactly two, otherwise we can't assume what is being executed so we leave it as is | 85 | # We can only switch these if there are exactly two, otherwise we can't assume what is being executed so we leave it as is |
55 | if len(tcp_serial_ports) == 2: | 86 | if len(tcp_serial_ports) == 2: |
56 | APU_args[tcp_serial_ports[0]],APU_args[tcp_serial_ports[1]] = APU_args[tcp_serial_ports[1]],APU_args[tcp_serial_ports[0]] | 87 | APU_args[tcp_serial_ports[0]],APU_args[tcp_serial_ports[1]] = APU_args[tcp_serial_ports[1]],APU_args[tcp_serial_ports[0]] |
57 | 88 | ||
58 | mb_cmd = "" | 89 | mb_cmd = "" |
59 | if PMU_args: | 90 | if PMU_args: |
60 | mb_cmd = binpath + '/qemu-system-microblazeel ' + ' '.join(PMU_args) + ' -machine-path ' + mach_path | 91 | pmu_args_s = ' '.join(PMU_args) |
61 | 92 | mb_cmd = f'{binpath}/qemu-system-microblazeel {pmu_args_s} -machine-path {mach_path}' | |
62 | print("PMU instance cmd: %s\n" % mb_cmd) | 93 | print(f"PMU instance cmd: {mb_cmd}\n") |
63 | 94 | ||
64 | if PLM_args: | 95 | if PLM_args: |
65 | mb_cmd = binpath + '/qemu-system-microblazeel ' + ' '.join(PLM_args) + ' -machine-path ' + mach_path | 96 | plm_args_s = ' '.join(PLM_args) |
66 | 97 | mb_cmd = f'{binpath}/qemu-system-microblazeel {plm_args_s} -machine-path {mach_path}' | |
67 | print("PLM instance cmd: %s\n" % mb_cmd) | 98 | print(f"PLM instance cmd: {mb_cmd}\n") |
68 | |||
69 | apu_cmd = binpath + '/qemu-system-aarch64 ' + ' '.join(APU_args) + ' -machine-path ' + mach_path | ||
70 | |||
71 | print("APU instance cmd: %s\n" % apu_cmd) | ||
72 | 99 | ||
100 | apu_args_s = ' '.join(APU_args) | ||
101 | apu_cmd = f'{binpath}/qemu-system-aarch64 {apu_args_s} -machine-path {mach_path}' | ||
102 | print(f"APU instance cmd: {apu_cmd}\n") | ||
73 | 103 | ||
74 | if mb_cmd: | 104 | if mb_cmd: |
75 | process_mb = subprocess.Popen(mb_cmd, shell=True, stderr=subprocess.PIPE) | 105 | process_mb = subprocess.Popen(mb_cmd, shell=True, stderr=subprocess.PIPE) |
diff --git a/meta-xilinx-core/recipes-devtools/qemu/qemu-xilinx-system-native_8.1.0.bb b/meta-xilinx-core/recipes-devtools/qemu/qemu-xilinx-system-native_8.1.0.bb index 3c8bb171..1e626ffe 100644 --- a/meta-xilinx-core/recipes-devtools/qemu/qemu-xilinx-system-native_8.1.0.bb +++ b/meta-xilinx-core/recipes-devtools/qemu/qemu-xilinx-system-native_8.1.0.bb | |||
@@ -8,7 +8,7 @@ require qemu-xilinx-native-8.1.inc | |||
8 | # and avoid file clashes | 8 | # and avoid file clashes |
9 | DEPENDS += "glib-2.0-native zlib-native pixman-native qemu-native" | 9 | DEPENDS += "glib-2.0-native zlib-native pixman-native qemu-native" |
10 | 10 | ||
11 | DEPENDS += "qemu-xilinx-multiarch-helper-native" | 11 | DEPENDS += "qemu-xilinx-multiarch-helper-native bootgen-native" |
12 | 12 | ||
13 | EXTRA_OECONF:append = " --target-list=${@get_qemu_system_target_list(d)}" | 13 | EXTRA_OECONF:append = " --target-list=${@get_qemu_system_target_list(d)}" |
14 | 14 | ||