summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta-xilinx-core/recipes-devtools/qemu/files/qemu-system-aarch64-multiarch76
1 files changed, 59 insertions, 17 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 e66c0fd0..d3328fa7 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
@@ -74,7 +74,7 @@ def help(status):
74 if not set(APU_args).intersection(set(help_options)): 74 if not set(APU_args).intersection(set(help_options)):
75 APU_args.append('-help') 75 APU_args.append('-help')
76 print(f"APU Options:\n") 76 print(f"APU Options:\n")
77 print(f" -bootbin <boot.bin> - Use a boot.bin instead of individual firmware, device trees and bootloader\n") 77 print(f" -bootbin [arch:]<boot.bin> - Use a boot.bin instead of individual firmware, device trees and bootloader. While arch: is optonal, it is recommended. The default arch is 'versal'.\n")
78 print(f" -dtb - Specify hardware dtb for the APU\n") 78 print(f" -dtb - Specify hardware dtb for the APU\n")
79 print(f" -kernel - option is filtered out, but is available for compatibility\n") 79 print(f" -kernel - option is filtered out, but is available for compatibility\n")
80 apu_args_s = ' '.join(APU_args) 80 apu_args_s = ' '.join(APU_args)
@@ -83,6 +83,10 @@ def help(status):
83 print(f" -machine-path <path> - Optional path to use for multiarch files. This path must be less then about 100 characters.\n Note: if specified caller is responsible for cleaning up the directory on exist\n") 83 print(f" -machine-path <path> - Optional path to use for multiarch files. This path must be less then about 100 characters.\n Note: if specified caller is responsible for cleaning up the directory on exist\n")
84 84
85 print(f"{help_cmd}\n") 85 print(f"{help_cmd}\n")
86
87 # Without this the Popen below can end up printing before the above
88 sys.stdout.flush()
89
86 process = subprocess.Popen(help_cmd, shell=True, stderr=subprocess.PIPE) 90 process = subprocess.Popen(help_cmd, shell=True, stderr=subprocess.PIPE)
87 status = process.wait() 91 status = process.wait()
88 sys.exit(status) 92 sys.exit(status)
@@ -121,16 +125,32 @@ if PMU_args:
121 '\nSee "meta-xilinx/README.qemu.md" for more information on accquiring the PMU ROM.\n') 125 '\nSee "meta-xilinx/README.qemu.md" for more information on accquiring the PMU ROM.\n')
122 126
123if bootbin_arg: 127if bootbin_arg:
124 if not os.path.isfile(bootbin_arg): 128 # List of valid bootgen arches and settings
125 print(f"\nERROR: bootbin file not found at {bootbin_arg}\n") 129 archs = [ 'versal' ]
130 boot_header_addr = {'versal' : '0xf201e000'}
131
132 # The bootbin is separated into "arch:file"
133 # Default to versal for legacy reasons
134 arch = 'versal'
135 bootbin_fn = bootbin_arg
136
137 if ':' in bootbin_arg:
138 (arch, bootbin_fn) = bootbin_arg.split(':', 1)
139
140 if not os.path.isfile(bootbin_fn):
141 print(f"\nERROR: bootbin file not found at {bootbin_fn}\n")
142 sys.exit(1)
143
144 if arch not in archs:
145 print(f"\nERROR: bootbin arch {arch} not valid ({archs})\n")
126 sys.exit(1) 146 sys.exit(1)
127 147
128 shutil.copyfile(bootbin_arg, f'{mach_path}/boot.bin') 148 shutil.copyfile(bootbin_fn, f'{mach_path}/boot.bin')
129 149
130 bootgen_command = [f'{binpath}/bootgen', '-arch', 'versal', '-dump', 'boot.bin'] 150 bootgen_command = [f'{binpath}/bootgen', '-arch', arch, '-dump', 'boot.bin']
131 subprocess.run(bootgen_command + ['boot_files'], check=True, cwd=mach_path, stdout=subprocess.DEVNULL) 151 subprocess.run(bootgen_command + ['boot_files'], check=True, cwd=mach_path, stdout=subprocess.DEVNULL)
132 152
133 bootgen_command = f"{binpath}/bootgen -arch versal -read {bootbin_arg}" 153 bootgen_command = f"{binpath}/bootgen -arch {arch} -read {bootbin_fn}"
134 result = subprocess.check_output(bootgen_command.split()) 154 result = subprocess.check_output(bootgen_command.split())
135 bootgen_output = result.decode().splitlines() 155 bootgen_output = result.decode().splitlines()
136 156
@@ -142,15 +162,26 @@ if bootbin_arg:
142 162
143 plm_load_addr = re.search(r"exec_addr_lo \(0x10\) : (0x\w*)\s*", plm_line).group(1) 163 plm_load_addr = re.search(r"exec_addr_lo \(0x10\) : (0x\w*)\s*", plm_line).group(1)
144 pmc_load_addr = re.search(r"pmccdo_load_addr \(0x20\) : (0x\w*)", pmc_line).group(1) 164 pmc_load_addr = re.search(r"pmccdo_load_addr \(0x20\) : (0x\w*)", pmc_line).group(1)
145 print(f"qemu-system-aarch64-multiarch: INFO: Using QSPI/OSPI bootbin file\n") 165 print(f"qemu-system-aarch64-multiarch: INFO: Using QSPI/OSPI bootbin file")
146 print(f"qemu-system-aarch64-multiarch: INFO: bootbin file dump PLM load addr: {plm_load_addr}\n")
147 print(f"qemu-system-aarch64-multiarch: INFO: bootbin file dump PMC load addr: {pmc_load_addr}\n")
148 166
149 PLM_args.append(f"-device loader,file={mach_path}/boot_bh.bin,addr=0xF201E000,force-raw=on") 167 boot_bh_addr = boot_header_addr[arch]
168 if boot_bh_addr and os.path.exists(f'{mach_path}/boot_bh.bin'):
169 print(f"qemu-system-aarch64-multiarch: INFO: boot header load addr: {boot_bh_addr}")
170 PLM_args.append(f"-device loader,file={mach_path}/boot_bh.bin,addr={boot_bh_addr},force-raw=on")
171 else:
172 print(f"\nERROR: boot header ({mach_path}/boot_bh.bin) or boot header ({boot_bh_addr}) address is missing\n")
173 sys.exit(1)
174
175 print(f"qemu-system-aarch64-multiarch: INFO: bootbin file dump PMC load addr: {pmc_load_addr}")
150 PLM_args.append(f"-device loader,file={mach_path}/pmc_cdo.bin,addr={pmc_load_addr},force-raw=on") 176 PLM_args.append(f"-device loader,file={mach_path}/pmc_cdo.bin,addr={pmc_load_addr},force-raw=on")
177
178 print(f"qemu-system-aarch64-multiarch: INFO: bootbin file dump PLM load addr: {plm_load_addr}")
151 PLM_args.append(f"-device loader,file={mach_path}/plm.bin,addr={plm_load_addr},force-raw=on") 179 PLM_args.append(f"-device loader,file={mach_path}/plm.bin,addr={plm_load_addr},force-raw=on")
152 PLM_args.append(f"-device loader,addr={plm_load_addr},cpu-num=1") 180 PLM_args.append(f"-device loader,addr={plm_load_addr},cpu-num=1")
153 181
182 # Add blank to make the above easier to read
183 print()
184
154# We use the normal -dtb argument to specify the hw-dtb for the multiarch runner, as -dtb is not applicable. 185# We use the normal -dtb argument to specify the hw-dtb for the multiarch runner, as -dtb is not applicable.
155if dtb_arg: 186if dtb_arg:
156 APU_args.append(f"-hw-dtb {dtb_arg}") 187 APU_args.append(f"-hw-dtb {dtb_arg}")
@@ -184,15 +215,26 @@ if mb_cmd:
184if apu_cmd: 215if apu_cmd:
185 process_apu = subprocess.Popen(apu_cmd, shell=True, stderr=subprocess.PIPE) 216 process_apu = subprocess.Popen(apu_cmd, shell=True, stderr=subprocess.PIPE)
186 217
218rc = 0
187error_msg = "" 219error_msg = ""
188if apu_cmd and process_apu.wait(): 220if apu_cmd:
189 # We only check for failures on the MB instance if APU fails 221 apu_rc = process_apu.wait()
190 error_msg += '\nQEMU APU instance failed:\n%s' % process_apu.stderr.read().decode() 222 if apu_rc:
191 223 rc = apu_rc
192 if mb_cmd and process_mb.wait(): 224 error_msg += '\nQEMU APU instance failed (%s):\n%s' % (apu_rc, process_apu.stderr.read().decode())
193 error_msg += '\nQEMU MB instance failed:\n%s' % process_mb.stderr.read().decode() 225
226# We only report errors for MB if the APU failed (or APU wasn't started)
227# otherwise we assume that the shutdown of the APU is the cause of the error
228try:
229 if mb_cmd:
230 mb_rc = process_mb.wait(timeout=5)
231 if mb_rc and (apu_cmd and apu_rc):
232 rc += mb_rc
233 error_msg += '\nQEMU MB instance failed (%s):\n%s' % (mb_rc, process_mb.stderr.read().decode())
234except subprocess.TimeoutExpired:
235 process_mb.kill()
194 236
195if not mach_path_arg: 237if not mach_path_arg:
196 shutil.rmtree(mach_path) 238 shutil.rmtree(mach_path)
197 239
198sys.exit(error_msg) 240sys.exit(apu_rc)