[PATCH 00/19] efi: Unify the scripts and start-up code

From: Simon Glass <sjg@chromium.org> We have two scripts which run QEMU, one for EFI and one for bare metal. They have similar options so it seems reasonable to try to unify them a bit. This series creates a common file and adjusts arguments so they are consistent across both scripts. The EFI app for ARM and x86 have different start-up code but in fact the code is quiet similar. This series creates a new common main program, called efi_main_common() which is used for both architectures. The small number of differences are handled in arch-specific code. Simon Glass (19): scripts: Drop unwanted Stage() function from build_helper scripts: Move common arguments into build_helper.py scripts: Use the same main() approach fo both scripts scripts: build-efi: Drop the -a option scripts: build-efi: Use -a instead of -A scripts: build-efi: Use --write-kernel instead of -K scripts: Move some QEMU-arg building into build_helper scripts: Move bitness and os_arch to helper scripts: Move OS selection into the helper efi: x86: Show app banner on startup efi: Rename efi_stub.o Makefile variable efi: Drop the efi_ prefix on the arch-specific stub files efi: Create a common file for the stub efi: Move more common stub code into the common file efi: Unify the names for use_uart and ebs_called efi: Create a common efi_main() implementation for the stub efi: Move x86 over to use the common efi_main() function efi: Move ARM over to use the common efi_main() function efi: Switch x86 and ARM to use the unified stub Makefile | 3 +- configs/efi-arm_app64_defconfig | 1 - configs/efi-x86_app32_defconfig | 1 - configs/efi-x86_app64_defconfig | 1 - configs/efi-x86_payload32_defconfig | 1 - configs/efi-x86_payload64_defconfig | 1 - include/efi.h | 8 +- include/efi_stub.h | 59 ++++++ lib/efi_client/Kconfig | 1 + lib/efi_client/Makefile | 20 +- lib/efi_client/efi.c | 24 --- lib/efi_client/{efi_stub_arm64.c => stub.c} | 117 +++++------- lib/efi_client/stub_arm64.c | 76 ++++++++ lib/efi_client/{efi_stub_x86.c => stub_x86.c} | 175 +----------------- scripts/build-efi | 80 +++----- scripts/build-qemu | 79 +------- scripts/build_helper.py | 111 +++++++++-- 17 files changed, 335 insertions(+), 423 deletions(-) rename lib/efi_client/{efi_stub_arm64.c => stub.c} (65%) create mode 100644 lib/efi_client/stub_arm64.c rename lib/efi_client/{efi_stub_x86.c => stub_x86.c} (52%) -- 2.43.0 base-commit: 55141ad119f8962d41b38bec9924524bd8daf2ba branch: appg

From: Simon Glass <sjg@chromium.org> This was brought in from another script by mistake but isn't needed. Drop it. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build_helper.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/scripts/build_helper.py b/scripts/build_helper.py index 3809ba88420..210840a3250 100644 --- a/scripts/build_helper.py +++ b/scripts/build_helper.py @@ -73,23 +73,6 @@ sct_mnt = /mnt/sct raw = self.settings.get('DEFAULT', name, fallback=fallback) return os.path.expandvars(os.path.expanduser(raw)) - def stage(self, name): - """Context manager to count requests across a range of patchwork calls - - Args: - name (str): Stage name - - Return: - _Stage: contect object - - Usage: - with self.stage('name'): - ...do things - - Note that the output only appears if the -N flag is used - """ - return self._Stage(name) - @contextlib.contextmanager def make_disk(self, fname, size_mb=20, fs_type='ext4', use_part=False): """Create a raw disk image with files on it -- 2.43.0

From: Simon Glass <sjg@chromium.org> The two main QEMU scripts (build-efi and build-qemu) share some common arguments, so put them in the common file. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-efi | 27 +++++---------------------- scripts/build-qemu | 24 +++--------------------- scripts/build_helper.py | 26 ++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 43 deletions(-) diff --git a/scripts/build-efi b/scripts/build-efi index b1a6fc8755e..e4bd90f4376 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -20,7 +20,7 @@ import os from pathlib import Path import shutil -from build_helper import Helper +import build_helper # pylint: disable=C0413 from u_boot_pylib import command @@ -36,40 +36,23 @@ def parse_args(): """ parser = ArgumentParser( epilog='Script for running U-Boot as an EFI app/payload') + build_helper.add_common_args(parser) parser.add_argument('-a', '--app', action='store_true', help='Package up the app') parser.add_argument('-A', '--arm', action='store_true', help='Run on ARM architecture') - parser.add_argument('-B', '--no-build', action='store_true', - help="Don't build (an existing build must be present") - parser.add_argument('-d', '--disk', - help='Root disk image file to use with QEMU') parser.add_argument('-g', '--debug', action='store_true', help="Run QEMU with gdb") - parser.add_argument( - '-k', '--kvm', action='store_true', - help='Use KVM (Kernel-based Virtual Machine) for acceleration') parser.add_argument('-K', '--kernel', action='store_true', help='Add a kernel') parser.add_argument('-O', '--old', action='store_true', help='Use old EFI app build (before 32/64 split)') - parser.add_argument('-o', '--os', metavar='NAME', choices=['ubuntu'], - help='Run a specified Operating System') parser.add_argument('-p', '--payload', action='store_true', help='Package up the payload') parser.add_argument('-P', '--partition', action='store_true', help='Create a partition table') - parser.add_argument('-r', '--run', action='store_true', - help='Run QEMU with the image') - parser.add_argument( - '-R', '--release', default='24.04.1', - help='Select OS release version (e.g, 24.04) Default: 24.04.1') - parser.add_argument('-s', '--serial', action='store_true', - help='Run QEMU with serial only (no display)') parser.add_argument('-v', '--verbose', action='store_true', help='Show executed commands') - parser.add_argument('-w', '--word', action='store_true', - help='Use word version (32-bit) rather than 64-bit') args = parser.parse_args() @@ -81,7 +64,7 @@ def parse_args(): class BuildEfi: """Class to collect together the various bits of state while running""" def __init__(self, args): - self.helper = Helper() + self.helper = build_helper.Helper() self.helper.read_settings() self.img = self.helper.get_setting('efi_image_file', 'efi.img') self.build_dir = self.helper.get_setting("build_dir", '/tmp') @@ -204,7 +187,7 @@ class BuildEfi: def start(self): """This does all the work""" args = self.args - bitness = 32 if args.word else 64 + bitness = 32 if args.word_32bit else 64 arch = 'arm' if args.arm else 'x86' build_type = 'payload' if args.payload else 'app' build = f'efi-{arch}_{build_type}{bitness}' @@ -223,7 +206,7 @@ class BuildEfi: command.run('cp', bzimage, f'{dirpath}/vmlinuz') if args.run: - self.run_qemu(bitness, args.serial) + self.run_qemu(bitness, args.serial_only) if __name__ == "__main__": diff --git a/scripts/build-qemu b/scripts/build-qemu index 8a6078a43fc..6fcaa379ab6 100755 --- a/scripts/build-qemu +++ b/scripts/build-qemu @@ -20,7 +20,7 @@ import sys import shlex import time -from build_helper import Helper +import build_helper OUR_PATH = os.path.dirname(os.path.realpath(__file__)) OUR1_PATH = os.path.dirname(OUR_PATH) @@ -40,14 +40,11 @@ def parse_args(): parser = argparse.ArgumentParser( description='Build and/or run U-Boot with QEMU', formatter_class=argparse.RawTextHelpFormatter) + build_helper.add_common_args(parser) parser.add_argument('-a', '--arch', default='arm', choices=['arm', 'x86'], help='Select architecture (arm, x86) Default: arm') - parser.add_argument('-B', '--no-build', action='store_true', - help="Don't build; assume a build exists") parser.add_argument('-C', '--enable-console', action='store_true', help="Enable linux console (x86 only)") - parser.add_argument('-d', '--disk', - help='Root disk image file to use with QEMU') parser.add_argument('-D', '--share-dir', metavar='DIR', help='Directory to share into the guest via virtiofs') parser.add_argument('-e', '--sct-run', action='store_true', @@ -56,25 +53,12 @@ def parse_args(): help='Run Tianocore (OVMF) instead of U-Boot') parser.add_argument('-I', '--initrd', help='Initial ramdisk to run using -initrd') - parser.add_argument( - '-k', '--kvm', action='store_true', - help='Use KVM (Kernel-based Virtual Machine) for acceleration') parser.add_argument('-K', '--kernel', help='Kernel to run using -kernel') - parser.add_argument('-o', '--os', metavar='NAME', choices=['ubuntu'], - help='Run a specified Operating System') parser.add_argument('-Q', '--use-qboot', action='store_true', help='Run qboot instead of U-Boot') - parser.add_argument('-r', '--run', action='store_true', - help='Run QEMU with the built/specified image') parser.add_argument('-x', '--xpl', action='store_true', help='Use xPL image rather than U-Boot proper') - parser.add_argument( - '-R', '--release', default='24.04.1', - help='Select OS release version (e.g, 24.04) Default: 24.04.1') - parser.add_argument( - '-s', '--serial-only', action='store_true', - help='Use serial console only (no graphical display for QEMU)') parser.add_argument( '-S', '--sct-seq', help='SCT sequence-file to be written into the SCT image if -e') @@ -86,8 +70,6 @@ def parse_args(): help='Pass the given root device to linux via root=/dev/disk/by-uuid/') parser.add_argument('-v', '--verbose', action='store_true', help='Show executed commands') - parser.add_argument('-w', '--word-32bit', action='store_true', - help='Use 32-bit version for the build/architecture') return parser.parse_args() @@ -99,7 +81,7 @@ class BuildQemu: """Set up arguments and configure paths""" self.args = args - self.helper = Helper() + self.helper = build_helper.Helper() self.helper.read_settings() self.imagedir = Path(self.helper.get_setting('image_dir', '~/dev')) self.ubdir = Path(self.helper.get_setting('build_dir', '/tmp/b')) diff --git a/scripts/build_helper.py b/scripts/build_helper.py index 210840a3250..ac7dbac9a30 100644 --- a/scripts/build_helper.py +++ b/scripts/build_helper.py @@ -107,3 +107,29 @@ sct_mnt = /mnt/sct input=f'type=c, size={size_mb-1}M, start=1M,bootable') else: shutil.copy2(tmp.name, fname) + + +def add_common_args(parser): + """Add some arguments which are common to build-efi/qemu scripts + + Args: + parser (argparse.ArgumentParser): Parser to modify + """ + parser.add_argument('-B', '--no-build', action='store_true', + help="Don't build; assume a build exists") + parser.add_argument('-d', '--disk', + help='Root disk image file to use with QEMU') + parser.add_argument( + '-k', '--kvm', action='store_true', + help='Use KVM (Kernel-based Virtual Machine) for acceleration') + parser.add_argument('-o', '--os', metavar='NAME', choices=['ubuntu'], + help='Run a specified Operating System') + parser.add_argument('-r', '--run', action='store_true', + help='Run QEMU with the image') + parser.add_argument( + '-R', '--release', default='24.04.1', + help='Select OS release version (e.g, 24.04) Default: 24.04.1') + parser.add_argument('-s', '--serial-only', action='store_true', + help='Run QEMU with serial only (no display)') + parser.add_argument('-w', '--word-32bit', action='store_true', + help='Use 32-bit version for the build/architecture') -- 2.43.0

From: Simon Glass <sjg@chromium.org> Add a main() function for EFI and adjust the scripts to look the same in this area. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-efi | 10 +++++++--- scripts/build-qemu | 3 +-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/build-efi b/scripts/build-efi index e4bd90f4376..e48a70fa510 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -209,9 +209,13 @@ class BuildEfi: self.run_qemu(bitness, args.serial_only) -if __name__ == "__main__": +def main(): + """Parse arguments and start the program""" args = parse_args() tout.init(tout.INFO if args.verbose else tout.WARNING) - efi = BuildEfi(args) - efi.start() + qemu = BuildEfi(args) + qemu.start() + +if __name__ == '__main__': + main() diff --git a/scripts/build-qemu b/scripts/build-qemu index 6fcaa379ab6..4fbf6f0a99e 100755 --- a/scripts/build-qemu +++ b/scripts/build-qemu @@ -432,8 +432,7 @@ class BuildQemu: def main(): - """Parses arguments and initiates the BuildQemu process - """ + """Parse arguments and start the program""" args = parse_args() tout.init(tout.INFO if args.verbose else tout.WARNING) -- 2.43.0

From: Simon Glass <sjg@chromium.org> This is not really needed, since it is the default and we have -p to select the payload. It also conflicts with -a in build-qemu Drop it. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-efi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/build-efi b/scripts/build-efi index e48a70fa510..365d6358cba 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -37,8 +37,6 @@ def parse_args(): parser = ArgumentParser( epilog='Script for running U-Boot as an EFI app/payload') build_helper.add_common_args(parser) - parser.add_argument('-a', '--app', action='store_true', - help='Package up the app') parser.add_argument('-A', '--arm', action='store_true', help='Run on ARM architecture') parser.add_argument('-g', '--debug', action='store_true', @@ -48,7 +46,7 @@ def parse_args(): parser.add_argument('-O', '--old', action='store_true', help='Use old EFI app build (before 32/64 split)') parser.add_argument('-p', '--payload', action='store_true', - help='Package up the payload') + help='Package up the payload instead of the app') parser.add_argument('-P', '--partition', action='store_true', help='Create a partition table') parser.add_argument('-v', '--verbose', action='store_true', @@ -56,8 +54,6 @@ def parse_args(): args = parser.parse_args() - if args.app and args.payload: - raise ValueError('Please choose either app or payload, not both') return args -- 2.43.0

From: Simon Glass <sjg@chromium.org> It seems better to specify the arch rather than using somewhat cryptic flags. The build-qemu scripts uses -a (for Architecture) so do the same for build-efi Signed-off-by: Simon Glass <sjg@chromium.org> Suggested-by: Heinrich Schuchardt <xypron.glpk@gmx.de> --- scripts/build-efi | 8 +++----- scripts/build-qemu | 2 -- scripts/build_helper.py | 2 ++ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/scripts/build-efi b/scripts/build-efi index 365d6358cba..331ba2ba0d2 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -37,8 +37,6 @@ def parse_args(): parser = ArgumentParser( epilog='Script for running U-Boot as an EFI app/payload') build_helper.add_common_args(parser) - parser.add_argument('-A', '--arm', action='store_true', - help='Run on ARM architecture') parser.add_argument('-g', '--debug', action='store_true', help="Run QEMU with gdb") parser.add_argument('-K', '--kernel', action='store_true', @@ -76,7 +74,7 @@ class BuildEfi: """ extra = [] efi_dir = self.helper.get_setting('efi_dir') - if self.args.arm: + if self.args.arch == 'arm': os_arch = 'arm64' qemu_arch = 'aarch64' extra += ['--machine', 'virt', '-cpu', 'max'] @@ -112,7 +110,7 @@ class BuildEfi: extra += ['-display', 'none', '-serial', 'mon:stdio'] serial_msg = ' (Ctrl-a x to quit)' else: - if self.args.arm: + if self.args.arch == 'arm': extra += ['-device', 'virtio-gpu-pci'] extra += ['-serial', 'mon:stdio'] serial_msg = '' @@ -184,7 +182,7 @@ class BuildEfi: """This does all the work""" args = self.args bitness = 32 if args.word_32bit else 64 - arch = 'arm' if args.arm else 'x86' + arch = 'arm' if self.args.arch == 'arm' else 'x86' build_type = 'payload' if args.payload else 'app' build = f'efi-{arch}_{build_type}{bitness}' diff --git a/scripts/build-qemu b/scripts/build-qemu index 4fbf6f0a99e..a5e02d9cedb 100755 --- a/scripts/build-qemu +++ b/scripts/build-qemu @@ -41,8 +41,6 @@ def parse_args(): description='Build and/or run U-Boot with QEMU', formatter_class=argparse.RawTextHelpFormatter) build_helper.add_common_args(parser) - parser.add_argument('-a', '--arch', default='arm', choices=['arm', 'x86'], - help='Select architecture (arm, x86) Default: arm') parser.add_argument('-C', '--enable-console', action='store_true', help="Enable linux console (x86 only)") parser.add_argument('-D', '--share-dir', metavar='DIR', diff --git a/scripts/build_helper.py b/scripts/build_helper.py index ac7dbac9a30..a166c6fce3f 100644 --- a/scripts/build_helper.py +++ b/scripts/build_helper.py @@ -115,6 +115,8 @@ def add_common_args(parser): Args: parser (argparse.ArgumentParser): Parser to modify """ + parser.add_argument('-a', '--arch', default='arm', choices=['arm', 'x86'], + help='Select architecture (arm, x86) Default: arm') parser.add_argument('-B', '--no-build', action='store_true', help="Don't build; assume a build exists") parser.add_argument('-d', '--disk', -- 2.43.0

From: Simon Glass <sjg@chromium.org> We want to use the -K option for providing a kernel via QEMU's QFW interface. Perhaps we could use the same option and require that the file be provided always, but that is less convenient. For now, rename the option. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-efi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/build-efi b/scripts/build-efi index 331ba2ba0d2..4e96f5406da 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -39,8 +39,8 @@ def parse_args(): build_helper.add_common_args(parser) parser.add_argument('-g', '--debug', action='store_true', help="Run QEMU with gdb") - parser.add_argument('-K', '--kernel', action='store_true', - help='Add a kernel') + parser.add_argument('--write-kernel', action='store_true', + help='Add a kernel to the disk image') parser.add_argument('-O', '--old', action='store_true', help='Use old EFI app build (before 32/64 split)') parser.add_argument('-p', '--payload', action='store_true', @@ -195,7 +195,7 @@ class BuildEfi: with self.helper.make_disk(self.img, fs_type='vfat', use_part=args.partition) as dirpath: self.setup_files(build, build_type, dirpath) - if self.args.kernel: + if self.args.write_kernel: bzimage = self.helper.get_setting('bzimage_file', 'bzImage') command.run('cp', bzimage, f'{dirpath}/vmlinuz') -- 2.43.0

From: Simon Glass <sjg@chromium.org> Providing a kernel, initrd and related options are useful in the EFI app too, so move them into the common code. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-efi | 1 + scripts/build-qemu | 29 +---------------------------- scripts/build_helper.py | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/scripts/build-efi b/scripts/build-efi index 4e96f5406da..eb92372ef09 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -152,6 +152,7 @@ class BuildEfi: cmd = [qemu] cmd += '-m', mem cmd += '-nic', 'none' + self.helper.add_qemu_args(self.args, cmd) cmd += extra tout.info(' '.join(cmd)) command.run(*cmd) diff --git a/scripts/build-qemu b/scripts/build-qemu index a5e02d9cedb..2309d1277e0 100755 --- a/scripts/build-qemu +++ b/scripts/build-qemu @@ -41,18 +41,12 @@ def parse_args(): description='Build and/or run U-Boot with QEMU', formatter_class=argparse.RawTextHelpFormatter) build_helper.add_common_args(parser) - parser.add_argument('-C', '--enable-console', action='store_true', - help="Enable linux console (x86 only)") parser.add_argument('-D', '--share-dir', metavar='DIR', help='Directory to share into the guest via virtiofs') parser.add_argument('-e', '--sct-run', action='store_true', help='Run UEFI Self-Certification Test (SCT)') parser.add_argument('-E', '--use-tianocore', action='store_true', help='Run Tianocore (OVMF) instead of U-Boot') - parser.add_argument('-I', '--initrd', - help='Initial ramdisk to run using -initrd') - parser.add_argument('-K', '--kernel', - help='Kernel to run using -kernel') parser.add_argument('-Q', '--use-qboot', action='store_true', help='Run qboot instead of U-Boot') parser.add_argument('-x', '--xpl', action='store_true', @@ -60,12 +54,6 @@ def parse_args(): parser.add_argument( '-S', '--sct-seq', help='SCT sequence-file to be written into the SCT image if -e') - parser.add_argument( - '-t', '--root', - help='Pass the given root device to linux via root=xxx') - parser.add_argument( - '-U', '--uuid', - help='Pass the given root device to linux via root=/dev/disk/by-uuid/') parser.add_argument('-v', '--verbose', action='store_true', help='Show executed commands') @@ -282,8 +270,6 @@ class BuildQemu: if not self.bios.exists(): tout.fatal(f"Error: BIOS file '{self.bios}' not found") - cmdline = [] - qemu_cmd = [str(self.qemu)] if self.bios: qemu_cmd.extend(['-bios', str(self.bios)]) @@ -304,20 +290,7 @@ class BuildQemu: if not any(item.startswith('-serial') for item in self.qemu_extra): qemu_cmd.extend(['-serial', 'mon:stdio']) - if self.args.kernel: - qemu_cmd.extend(['-kernel', self.args.kernel]) - if self.args.initrd: - qemu_cmd.extend(['-initrd', self.args.initrd]) - - if self.args.enable_console: - cmdline.append('console=ttyS0,115200,8n1') - if self.args.root: - cmdline.append(f'root={self.args.root}') - if self.args.uuid: - cmdline.append(f'root=/dev/disk/by-uuid/{self.args.uuid}') - - if cmdline: - qemu_cmd.extend(['-append'] + [' '.join(cmdline)]) + self.helper.add_qemu_args(self.args, qemu_cmd) # Add other parameters gathered from options qemu_cmd.extend(self.qemu_extra) diff --git a/scripts/build_helper.py b/scripts/build_helper.py index a166c6fce3f..6231500f34a 100644 --- a/scripts/build_helper.py +++ b/scripts/build_helper.py @@ -108,6 +108,31 @@ sct_mnt = /mnt/sct else: shutil.copy2(tmp.name, fname) + def add_qemu_args(self, args, cmd): + """Add QEMU arguments according to the selected options + + This helps in creating the command-line used to run QEMU. + + Args: + args (list of str): Existing arguments to add to + cmd (argparse.Namespace): Program arguments + """ + cmdline = [] + if args.kernel: + cmd.extend(['-kernel', args.kernel]) + if args.initrd: + cmd.extend(['-initrd', args.initrd]) + + if args.enable_console: + cmdline.append('console=ttyS0,115200,8n1') + if args.root: + cmdline.append(f'root={args.root}') + if args.uuid: + cmdline.append(f'root=/dev/disk/by-uuid/{args.uuid}') + + if cmdline: + cmd.extend(['-append'] + [' '.join(cmdline)]) + def add_common_args(parser): """Add some arguments which are common to build-efi/qemu scripts @@ -119,11 +144,17 @@ def add_common_args(parser): help='Select architecture (arm, x86) Default: arm') parser.add_argument('-B', '--no-build', action='store_true', help="Don't build; assume a build exists") + parser.add_argument('-C', '--enable-console', action='store_true', + help="Enable linux console (x86 only)") parser.add_argument('-d', '--disk', help='Root disk image file to use with QEMU') + parser.add_argument('-I', '--initrd', + help='Initial ramdisk to run using -initrd') parser.add_argument( '-k', '--kvm', action='store_true', help='Use KVM (Kernel-based Virtual Machine) for acceleration') + parser.add_argument('-K', '--kernel', + help='Kernel to run using -kernel') parser.add_argument('-o', '--os', metavar='NAME', choices=['ubuntu'], help='Run a specified Operating System') parser.add_argument('-r', '--run', action='store_true', @@ -133,5 +164,11 @@ def add_common_args(parser): help='Select OS release version (e.g, 24.04) Default: 24.04.1') parser.add_argument('-s', '--serial-only', action='store_true', help='Run QEMU with serial only (no display)') + parser.add_argument( + '-t', '--root', + help='Pass the given root device to linux via root=xxx') + parser.add_argument( + '-U', '--uuid', + help='Pass the given root device to linux via root=/dev/disk/by-uuid/') parser.add_argument('-w', '--word-32bit', action='store_true', help='Use 32-bit version for the build/architecture') -- 2.43.0

From: Simon Glass <sjg@chromium.org> These two concepts are used in both scripts, so move them to the helper. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-efi | 19 +++++++------------ scripts/build-qemu | 13 ++++--------- scripts/build_helper.py | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/scripts/build-efi b/scripts/build-efi index eb92372ef09..5dc58f1512e 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -58,24 +58,22 @@ def parse_args(): class BuildEfi: """Class to collect together the various bits of state while running""" def __init__(self, args): - self.helper = build_helper.Helper() + self.helper = build_helper.Helper(args) self.helper.read_settings() self.img = self.helper.get_setting('efi_image_file', 'efi.img') self.build_dir = self.helper.get_setting("build_dir", '/tmp') self.args = args self.imagedir = Path(self.helper.get_setting('image_dir', '~/dev')) - def run_qemu(self, bitness, serial_only): + def run_qemu(self, serial_only): """Run QEMU Args: - bitness (int): Bitness to use, 32 or 64 serial_only (bool): True to run without a display """ extra = [] efi_dir = self.helper.get_setting('efi_dir') if self.args.arch == 'arm': - os_arch = 'arm64' qemu_arch = 'aarch64' extra += ['--machine', 'virt', '-cpu', 'max'] bios = os.path.join(efi_dir, 'OVMF-pure-efi.aarch64.fd.64m') @@ -88,14 +86,12 @@ class BuildEfi: f'id=hd0,file={self.img},if=none,format=raw', '-device', 'virtio-blk-device,drive=hd0'] else: # x86 - if bitness == 64: + if self.helper.bitness == 64: qemu_arch = 'x86_64' bios = 'OVMF_CODE_4M.fd' - os_arch = 'amd64' else: qemu_arch = 'i386' bios = 'OVMF-pure-efi.i386.fd' - os_arch = 'i386' bios = os.path.join(efi_dir, bios) var_store = os.path.join(efi_dir, 'OVMF_VARS_4M.fd') extra += [ @@ -119,7 +115,7 @@ class BuildEfi: os_path = None if self.args.os == 'ubuntu': - img_name = f'{self.args.os}-{self.args.release}-desktop-{os_arch}.iso' + img_name = f'{self.args.os}-{self.args.release}-desktop-{self.helper.os_arch}.iso' os_path = self.imagedir / self.args.os / img_name if not os_path.exists(): tout.error(f'OS image {os_path} specified but not found') @@ -182,15 +178,14 @@ class BuildEfi: def start(self): """This does all the work""" args = self.args - bitness = 32 if args.word_32bit else 64 arch = 'arm' if self.args.arch == 'arm' else 'x86' build_type = 'payload' if args.payload else 'app' - build = f'efi-{arch}_{build_type}{bitness}' + build = f'efi-{arch}_{build_type}{self.helper.bitness}' if not args.no_build: self.do_build(build) - if args.old and bitness == 32: + if args.old and self.helper.bitness == 32: build = f'efi-{arch}_{build_type}' with self.helper.make_disk(self.img, fs_type='vfat', @@ -201,7 +196,7 @@ class BuildEfi: command.run('cp', bzimage, f'{dirpath}/vmlinuz') if args.run: - self.run_qemu(bitness, args.serial_only) + self.run_qemu(args.serial_only) def main(): diff --git a/scripts/build-qemu b/scripts/build-qemu index 2309d1277e0..ac077203e39 100755 --- a/scripts/build-qemu +++ b/scripts/build-qemu @@ -67,7 +67,7 @@ class BuildQemu: """Set up arguments and configure paths""" self.args = args - self.helper = build_helper.Helper() + self.helper = build_helper.Helper(args) self.helper.read_settings() self.imagedir = Path(self.helper.get_setting('image_dir', '~/dev')) self.ubdir = Path(self.helper.get_setting('build_dir', '/tmp/b')) @@ -77,7 +77,6 @@ class BuildQemu: self.qboot = Path(self.helper.get_setting('qboot_dir', '~/dev/qboot')) self.mnt = Path(self.helper.get_setting('sct_mnt', '/mnt/sct')) - self.bitness = 32 if args.word_32bit else 64 self.qemu_extra = [] self.mem = '512M' # Default QEMU memory @@ -143,30 +142,26 @@ class BuildQemu: self.qemu_extra.extend(['-machine', 'virt']) if not args.kvm: self.qemu_extra.extend(['-accel', 'tcg']) - os_arch = 'arm' - if self.bitness == 64: + if self.helper.bitness == 64: if args.xpl: self.board = 'qemu_arm64_spl' else: self.board = 'qemu_arm64' self.qemu = 'qemu-system-aarch64' self.qemu_extra.extend(['-cpu', 'cortex-a57']) - os_arch = 'arm64' elif args.arch == 'x86': self.board = 'qemu-x86' default_bios = 'u-boot.rom' self.qemu = 'qemu-system-i386' - os_arch = 'i386' # For OS image naming - if self.bitness == 64: + if self.helper.bitness == 64: self.board = 'qemu-x86_64' self.qemu = 'qemu-system-x86_64' - os_arch = 'amd64' else: raise ValueError(f"Invalid arch '{args.arch}'") self.os_path = None if args.os == 'ubuntu': - img_name = (f'{args.os}-{args.release}-desktop-{os_arch}.iso') + img_name = (f'{args.os}-{args.release}-desktop-{self.helper.os_arch}.iso') self.os_path = self.imagedir / args.os / img_name self.build_dir = self.ubdir / self.board diff --git a/scripts/build_helper.py b/scripts/build_helper.py index 6231500f34a..d00ccb86328 100644 --- a/scripts/build_helper.py +++ b/scripts/build_helper.py @@ -26,8 +26,21 @@ import fs_helper class Helper: - def __init__(self): + def __init__(self, args): self.settings = None + self.imagedir = None + self.args = args + self.bitness = 32 if args.word_32bit else 64 + if self.args.arch == 'arm': + if self.bitness == 64: + self.os_arch = 'arm64' + else: + self.os_arch = 'arm' + else: # x86 + if self.bitness == 64: + self.os_arch = 'amd64' + else: + self.os_arch = 'i386' def read_settings(self): """Get settings from the settings file""" -- 2.43.0

From: Simon Glass <sjg@chromium.org> Both scripts allow booting from an ISO containing an OS, so move this handling into the common helper. Signed-off-by: Simon Glass <sjg@chromium.org> --- scripts/build-efi | 11 ----------- scripts/build-qemu | 12 ------------ scripts/build_helper.py | 14 ++++++++++++++ 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/scripts/build-efi b/scripts/build-efi index 5dc58f1512e..0ec1e63c950 100755 --- a/scripts/build-efi +++ b/scripts/build-efi @@ -113,17 +113,6 @@ class BuildEfi: if self.args.kvm: extra.extend(['-enable-kvm', '-cpu', 'host']) - os_path = None - if self.args.os == 'ubuntu': - img_name = f'{self.args.os}-{self.args.release}-desktop-{self.helper.os_arch}.iso' - os_path = self.imagedir / self.args.os / img_name - if not os_path.exists(): - tout.error(f'OS image {os_path} specified but not found') - else: - extra.extend([ - '-drive', - f'if=virtio,file={os_path},format=raw,id=hd0,readonly=on']) - img_fname = Path(self.args.disk) if self.args.disk else None if img_fname: if img_fname.exists(): diff --git a/scripts/build-qemu b/scripts/build-qemu index ac077203e39..a6676eca350 100755 --- a/scripts/build-qemu +++ b/scripts/build-qemu @@ -69,7 +69,6 @@ class BuildQemu: self.helper = build_helper.Helper(args) self.helper.read_settings() - self.imagedir = Path(self.helper.get_setting('image_dir', '~/dev')) self.ubdir = Path(self.helper.get_setting('build_dir', '/tmp/b')) self.sctdir = Path(self.helper.get_setting('sct_dir', '~/dev/efi/sct')) self.tiano = Path(self.helper.get_setting('tianocore_dir', @@ -159,11 +158,6 @@ class BuildQemu: else: raise ValueError(f"Invalid arch '{args.arch}'") - self.os_path = None - if args.os == 'ubuntu': - img_name = (f'{args.os}-{args.release}-desktop-{self.helper.os_arch}.iso') - self.os_path = self.imagedir / args.os / img_name - self.build_dir = self.ubdir / self.board self.bios = (bios_override if bios_override else self.build_dir / default_bios) @@ -289,12 +283,6 @@ class BuildQemu: # Add other parameters gathered from options qemu_cmd.extend(self.qemu_extra) - if self.os_path: - if not self.os_path.exists(): - tout.error(f'OS image {self.os_path} specified but not found') - qemu_cmd.extend([ - '-drive', - f'if=virtio,file={self.os_path},format=raw,id=hd0,readonly=on']) if self.img_fname: if self.img_fname.exists(): diff --git a/scripts/build_helper.py b/scripts/build_helper.py index d00ccb86328..09fac2d2335 100644 --- a/scripts/build_helper.py +++ b/scripts/build_helper.py @@ -7,6 +7,7 @@ import configparser import contextlib import os +from pathlib import Path import shutil import subprocess import sys @@ -22,6 +23,7 @@ sys.path.insert(2, os.path.join(OUR1_PATH, 'test/py/tests')) from u_boot_pylib import command from u_boot_pylib import tools +from u_boot_pylib import tout import fs_helper @@ -75,6 +77,7 @@ sct_dir = ~/dev/efi/sct sct_mnt = /mnt/sct ''', binary=False) self.settings.read(fname) + self.imagedir = Path(self.get_setting('image_dir', '~/dev')) def get_setting(self, name, fallback=None): """Get a setting by name @@ -146,6 +149,17 @@ sct_mnt = /mnt/sct if cmdline: cmd.extend(['-append'] + [' '.join(cmdline)]) + os_path = None + if args.os == 'ubuntu': + img_name = f'{args.os}-{args.release}-desktop-{self.os_arch}.iso' + os_path = self.imagedir / args.os / img_name + if not os_path.exists(): + tout.error(f'OS image {os_path} specified but not found') + else: + cmd.extend([ + '-drive', + f'if=virtio,file={os_path},format=raw,id=hd0,readonly=on']) + def add_common_args(parser): """Add some arguments which are common to build-efi/qemu scripts -- 2.43.0

From: Simon Glass <sjg@chromium.org> Print a line that indicates if this is the app, to match the line shown for the payload, i.e.: Model: EFI x86 Application or: Model: EFI x86 Payload or: Model: EFI ARM Application Drop CONFIG_DISPLAY_BOARDINFO_LATE as it is not needed. Note that there is no (generic) stub for ARM. Signed-off-by: Simon Glass <sjg@chromium.org> --- configs/efi-arm_app64_defconfig | 1 - configs/efi-x86_app32_defconfig | 1 - configs/efi-x86_app64_defconfig | 1 - configs/efi-x86_payload32_defconfig | 1 - configs/efi-x86_payload64_defconfig | 1 - lib/efi_client/Kconfig | 1 + 6 files changed, 1 insertion(+), 5 deletions(-) diff --git a/configs/efi-arm_app64_defconfig b/configs/efi-arm_app64_defconfig index f2ed6069d74..5298f2d84b0 100644 --- a/configs/efi-arm_app64_defconfig +++ b/configs/efi-arm_app64_defconfig @@ -17,7 +17,6 @@ CONFIG_USE_BOOTARGS=y CONFIG_SYS_PBSIZE=532 CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_LOG=y -CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_MEMINFO=y diff --git a/configs/efi-x86_app32_defconfig b/configs/efi-x86_app32_defconfig index de97cb64ce7..d17f0f8c208 100644 --- a/configs/efi-x86_app32_defconfig +++ b/configs/efi-x86_app32_defconfig @@ -18,7 +18,6 @@ CONFIG_BOOTCOMMAND="bootflow scan -lbp" CONFIG_SYS_PBSIZE=532 CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_LOG=y -CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_BOARD_EARLY_INIT_R=y CONFIG_CMD_LSBLK=y CONFIG_CMD_CAT=y diff --git a/configs/efi-x86_app64_defconfig b/configs/efi-x86_app64_defconfig index 55daf7bec2a..ea9a2068565 100644 --- a/configs/efi-x86_app64_defconfig +++ b/configs/efi-x86_app64_defconfig @@ -20,7 +20,6 @@ CONFIG_BOOTCOMMAND="bootflow scan -lbp" CONFIG_SYS_PBSIZE=532 CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_LOG=y -CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_BOARD_EARLY_INIT_R=y CONFIG_CMD_LSBLK=y CONFIG_CMD_CAT=y diff --git a/configs/efi-x86_payload32_defconfig b/configs/efi-x86_payload32_defconfig index cf827fefd45..972608fca14 100644 --- a/configs/efi-x86_payload32_defconfig +++ b/configs/efi-x86_payload32_defconfig @@ -17,7 +17,6 @@ CONFIG_BOOTCOMMAND="ext2load scsi 0:3 01000000 /boot/vmlinuz; zboot 01000000" CONFIG_SYS_PBSIZE=532 CONFIG_PRE_CONSOLE_BUFFER=y CONFIG_SYS_CONSOLE_INFO_QUIET=y -CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_HUSH_PARSER=y CONFIG_CMD_IDE=y CONFIG_CMD_MMC=y diff --git a/configs/efi-x86_payload64_defconfig b/configs/efi-x86_payload64_defconfig index bdf61e204a3..aacb043b294 100644 --- a/configs/efi-x86_payload64_defconfig +++ b/configs/efi-x86_payload64_defconfig @@ -18,7 +18,6 @@ CONFIG_BOOTARGS="root=/dev/sdb3 init=/sbin/init rootwait ro" CONFIG_SYS_PBSIZE=532 CONFIG_PRE_CONSOLE_BUFFER=y CONFIG_SYS_CONSOLE_INFO_QUIET=y -CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_CMD_IDE=y CONFIG_CMD_MMC=y CONFIG_CMD_USB=y diff --git a/lib/efi_client/Kconfig b/lib/efi_client/Kconfig index f05647f5144..743181834bf 100644 --- a/lib/efi_client/Kconfig +++ b/lib/efi_client/Kconfig @@ -4,6 +4,7 @@ menu "U-Boot as UEFI application" config EFI_CLIENT bool "Support running U-Boot from EFI" depends on X86 || ARM + imply DISPLAY_BOARDINFO imply X86_TSC_READ_BASE select EFI help -- 2.43.0

From: Simon Glass <sjg@chromium.org> This variable is a bit confusing as it looks like a filename. Use stub_obj instead. Signed-off-by: Simon Glass <sjg@chromium.org> --- lib/efi_client/Makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/efi_client/Makefile b/lib/efi_client/Makefile index 5081d71a19f..4de540df0db 100644 --- a/lib/efi_client/Makefile +++ b/lib/efi_client/Makefile @@ -7,22 +7,22 @@ obj-$(CONFIG_EFI_APP) += sdram.o obj-$(CONFIG_EFI_STUB) += efi_info.o ifeq ($(CONFIG_ARM64),y) -efi_stub.o := efi_stub_arm64.o +stub_obj := efi_stub_arm64.o else -efi_stub.o := efi_stub_x86.o +stub_obj := efi_stub_x86.o ifeq ($(CONFIG_EFI_STUB_64BIT),y) # && !CONFIG_ARM64 -CFLAGS_REMOVE_$(efi_stub.o) := -march=i386 -m32 -CFLAGS_$(efi_stub.o) := -m64 +CFLAGS_REMOVE_$(stub_obj) := -march=i386 -m32 +CFLAGS_$(stub_obj) := -m64 CFLAGS_REMOVE_efi.o := -march=i386 -m32 CFLAGS_efi.o := -fpic -m64 endif endif -CFLAGS_REMOVE_$(efi_stub.o) += -mregparm=3 -CFLAGS_$(efi_stub.o) += -fpic -fshort-wchar +CFLAGS_REMOVE_$(stub_obj) += -mregparm=3 +CFLAGS_$(stub_obj) += -fpic -fshort-wchar CFLAGS_REMOVE_efi.o += -mregparm=3 CFLAGS_efi.o += -fpic -fshort-wchar -$(info removing flags $(CFLAGS_REMOVE_$(efi_stub.o))) -extra-$(CONFIG_EFI_STUB) += $(efi_stub.o) efi.o +$(info removing flags $(CFLAGS_REMOVE_$(stub_obj))) +extra-$(CONFIG_EFI_STUB) += $(stub_obj) efi.o -- 2.43.0

From: Simon Glass <sjg@chromium.org> These are already in the lib/efi/ directory so the extra efi_ prefix is redundant and makes files harder to find. Drop it. Signed-off-by: Simon Glass <sjg@chromium.org> --- Makefile | 2 +- lib/efi_client/Makefile | 4 ++-- lib/efi_client/{efi_stub_arm64.c => stub_arm64.c} | 0 lib/efi_client/{efi_stub_x86.c => stub_x86.c} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename lib/efi_client/{efi_stub_arm64.c => stub_arm64.c} (100%) rename lib/efi_client/{efi_stub_x86.c => stub_x86.c} (100%) diff --git a/Makefile b/Makefile index 0be9c0dc685..f70f6ab3d44 100644 --- a/Makefile +++ b/Makefile @@ -1696,7 +1696,7 @@ EFI_STUB_ARCH := $(if $(CONFIG_ARM64),arm64,$(if $(CONFIG_X86_64),x86,$(ARCH))) quiet_cmd_u-boot_payload ?= LD $@ cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \ -T u-boot-payload.lds $(if $(CONFIG_X86),arch/x86/cpu/call32.o,) \ - lib/efi_client/efi.o lib/efi_client/efi_stub_$(EFI_STUB_ARCH).o \ + lib/efi_client/efi.o lib/efi_client/stub_$(EFI_STUB_ARCH).o \ u-boot.bin.o $(addprefix arch/$(ARCH)/lib/,$(EFISTUB)) quiet_cmd_u-boot_payload_arm64.efi ?= OBJCOPY $@ diff --git a/lib/efi_client/Makefile b/lib/efi_client/Makefile index 4de540df0db..5a11ca58018 100644 --- a/lib/efi_client/Makefile +++ b/lib/efi_client/Makefile @@ -7,9 +7,9 @@ obj-$(CONFIG_EFI_APP) += sdram.o obj-$(CONFIG_EFI_STUB) += efi_info.o ifeq ($(CONFIG_ARM64),y) -stub_obj := efi_stub_arm64.o +stub_obj := stub_arm64.o else -stub_obj := efi_stub_x86.o +stub_obj := stub_x86.o ifeq ($(CONFIG_EFI_STUB_64BIT),y) # && !CONFIG_ARM64 CFLAGS_REMOVE_$(stub_obj) := -march=i386 -m32 diff --git a/lib/efi_client/efi_stub_arm64.c b/lib/efi_client/stub_arm64.c similarity index 100% rename from lib/efi_client/efi_stub_arm64.c rename to lib/efi_client/stub_arm64.c diff --git a/lib/efi_client/efi_stub_x86.c b/lib/efi_client/stub_x86.c similarity index 100% rename from lib/efi_client/efi_stub_x86.c rename to lib/efi_client/stub_x86.c -- 2.43.0

From: Simon Glass <sjg@chromium.org> There is some duplicated code across x86 and ARM even though they have slightly different implementations. They both call efi_stub_exit_boot_services() and this function does not relate to the app, so belongs better outside the general-purpose efi.c file. Create a new efi_stub C file containing this function. Leave out the efi_ prefix since this is obvious from the directory name. Signed-off-by: Simon Glass <sjg@chromium.org> --- Makefile | 1 + include/efi.h | 4 ++-- lib/efi_client/Makefile | 6 +++++- lib/efi_client/efi.c | 24 ------------------------ lib/efi_client/stub.c | 37 +++++++++++++++++++++++++++++++++++++ lib/efi_client/stub_arm64.c | 2 +- lib/efi_client/stub_x86.c | 2 +- 7 files changed, 47 insertions(+), 29 deletions(-) create mode 100644 lib/efi_client/stub.c diff --git a/Makefile b/Makefile index f70f6ab3d44..c256b4094fc 100644 --- a/Makefile +++ b/Makefile @@ -1697,6 +1697,7 @@ quiet_cmd_u-boot_payload ?= LD $@ cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \ -T u-boot-payload.lds $(if $(CONFIG_X86),arch/x86/cpu/call32.o,) \ lib/efi_client/efi.o lib/efi_client/stub_$(EFI_STUB_ARCH).o \ + lib/efi_client/stub.o \ u-boot.bin.o $(addprefix arch/$(ARCH)/lib/,$(EFISTUB)) quiet_cmd_u-boot_payload_arm64.efi ?= OBJCOPY $@ diff --git a/include/efi.h b/include/efi.h index 6ba2f2b7c85..99a209e86c6 100644 --- a/include/efi.h +++ b/include/efi.h @@ -664,13 +664,13 @@ void efi_putc(struct efi_priv *priv, const char ch); int efi_store_memory_map(struct efi_priv *priv); /** - * efi_call_exit_boot_services() - Handle the exit-boot-service procedure + * efi_stub_exit_boot_services() - Handle the exit-boot-service procedure * * Tell EFI we don't want their boot services anymore * * Return: 0 if OK, non-zero on error */ -int efi_call_exit_boot_services(void); +int efi_stub_exit_boot_services(void); /** * efi_get_mmap() - Get the memory map from EFI diff --git a/lib/efi_client/Makefile b/lib/efi_client/Makefile index 5a11ca58018..d7a3232c6bb 100644 --- a/lib/efi_client/Makefile +++ b/lib/efi_client/Makefile @@ -14,6 +14,8 @@ stub_obj := stub_x86.o ifeq ($(CONFIG_EFI_STUB_64BIT),y) # && !CONFIG_ARM64 CFLAGS_REMOVE_$(stub_obj) := -march=i386 -m32 CFLAGS_$(stub_obj) := -m64 +CFLAGS_REMOVE_stub.o := -march=i386 -m32 +CFLAGS_stub.o := -m64 CFLAGS_REMOVE_efi.o := -march=i386 -m32 CFLAGS_efi.o := -fpic -m64 endif @@ -21,8 +23,10 @@ endif CFLAGS_REMOVE_$(stub_obj) += -mregparm=3 CFLAGS_$(stub_obj) += -fpic -fshort-wchar +CFLAGS_REMOVE_stub.o += -mregparm=3 +CFLAGS_stub.o += -fpic -fshort-wchar CFLAGS_REMOVE_efi.o += -mregparm=3 CFLAGS_efi.o += -fpic -fshort-wchar $(info removing flags $(CFLAGS_REMOVE_$(stub_obj))) -extra-$(CONFIG_EFI_STUB) += $(stub_obj) efi.o +extra-$(CONFIG_EFI_STUB) += $(stub_obj) stub.o efi.o diff --git a/lib/efi_client/efi.c b/lib/efi_client/efi.c index 8b825c7a66e..6b1b6b10e2a 100644 --- a/lib/efi_client/efi.c +++ b/lib/efi_client/efi.c @@ -219,27 +219,3 @@ int efi_store_memory_map(struct efi_priv *priv) return 0; } - -int efi_call_exit_boot_services(void) -{ - struct efi_priv *priv = efi_get_priv(); - const struct efi_boot_services *boot = priv->boot; - efi_uintn_t size; - u32 version; - efi_status_t ret; - - size = priv->memmap_alloc; - ret = boot->get_memory_map(&size, priv->memmap_desc, - &priv->memmap_key, - &priv->memmap_desc_size, &version); - if (ret) { - printhex2(ret); - puts(" Can't get memory map\n"); - return ret; - } - ret = boot->exit_boot_services(priv->parent_image, priv->memmap_key); - if (ret) - return ret; - - return 0; -} diff --git a/lib/efi_client/stub.c b/lib/efi_client/stub.c new file mode 100644 index 00000000000..fed256e68ee --- /dev/null +++ b/lib/efi_client/stub.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2015 Google, Inc + * + * EFI information obtained here: + * http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES + * + * Provides helper functions for use with the stub + */ + +#include <debug_uart.h> +#include <efi.h> +#include <efi_api.h> + +int efi_stub_exit_boot_services(void) +{ + struct efi_priv *priv = efi_get_priv(); + const struct efi_boot_services *boot = priv->boot; + efi_uintn_t size; + u32 version; + efi_status_t ret; + + size = priv->memmap_alloc; + ret = boot->get_memory_map(&size, priv->memmap_desc, + &priv->memmap_key, + &priv->memmap_desc_size, &version); + if (ret) { + printhex2(ret); + puts(" Can't get memory map\n"); + return ret; + } + ret = boot->exit_boot_services(priv->parent_image, priv->memmap_key); + if (ret) + return ret; + + return 0; +} diff --git a/lib/efi_client/stub_arm64.c b/lib/efi_client/stub_arm64.c index 2cabb16f241..47b9705acca 100644 --- a/lib/efi_client/stub_arm64.c +++ b/lib/efi_client/stub_arm64.c @@ -203,7 +203,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, table.sys_table = (ulong)sys_table; add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0); - ret = efi_call_exit_boot_services(); + ret = efi_stub_exit_boot_services(); if (ret) return ret; diff --git a/lib/efi_client/stub_x86.c b/lib/efi_client/stub_x86.c index ea1993f745d..25c9159f320 100644 --- a/lib/efi_client/stub_x86.c +++ b/lib/efi_client/stub_x86.c @@ -347,7 +347,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, table.sys_table = (ulong)sys_table; add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0); - ret = efi_call_exit_boot_services(); + ret = efi_stub_exit_boot_services(); if (ret) return ret; -- 2.43.0

From: Simon Glass <sjg@chromium.org> Pull in several functions which are identical in the ARM and x86 files. Signed-off-by: Simon Glass <sjg@chromium.org> --- include/efi_stub.h | 36 +++++++++++++++ lib/efi_client/stub.c | 75 ++++++++++++++++++++++++++++++ lib/efi_client/stub_arm64.c | 91 ------------------------------------- lib/efi_client/stub_x86.c | 90 ------------------------------------ 4 files changed, 111 insertions(+), 181 deletions(-) diff --git a/include/efi_stub.h b/include/efi_stub.h index 343c8443597..eb2da6a76d3 100644 --- a/include/efi_stub.h +++ b/include/efi_stub.h @@ -10,6 +10,8 @@ #include <linux/types.h> +struct efi_priv; + enum efi_entry_t { EFIET_END, /* Signals this is the last (empty) entry */ EFIET_MEMORY_MAP, @@ -64,4 +66,38 @@ int dram_init_banksize_from_efi(void); */ void efi_add_known_memory_from_efi(void); +/** + * setup_info_table() - sets up a table containing information from EFI + * + * We must call exit_boot_services() before jumping out of the stub into U-Boot + * proper, so that U-Boot has full control of peripherals, memory, etc. + * + * Once we do this, we cannot call any boot-services functions so we must find + * out everything we need to before doing that. + * + * Set up a struct efi_info_hdr table which can hold various records (e.g. + * struct efi_entry_memmap) with information obtained from EFI. + * + * @priv: Pointer to our private information which contains the list + * @size: Size of the table to allocate + * Return: 0 if OK, non-zero on error + */ +int setup_info_table(struct efi_priv *priv, int size); + +/** + * add_entry_addr() - Add a new entry to the efi_info list + * + * This adds an entry, consisting of a tag and two lots of data. This avoids the + * caller having to coalesce the data first + * + * @priv: Pointer to our private information which contains the list + * @type: Type of the entry to add + * @ptr1: Pointer to first data block to add + * @size1: Size of first data block in bytes (can be 0) + * @ptr2: Pointer to second data block to add + * @size2: Size of second data block in bytes (can be 0) + */ +void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type, void *ptr1, + int size1, void *ptr2, int size2); + #endif /* _EFI_STUB_H */ diff --git a/lib/efi_client/stub.c b/lib/efi_client/stub.c index fed256e68ee..cf0314ba6a6 100644 --- a/lib/efi_client/stub.c +++ b/lib/efi_client/stub.c @@ -11,6 +11,7 @@ #include <debug_uart.h> #include <efi.h> #include <efi_api.h> +#include <efi_stub.h> int efi_stub_exit_boot_services(void) { @@ -35,3 +36,77 @@ int efi_stub_exit_boot_services(void) return 0; } + +void *memcpy(void *dest, const void *src, size_t size) +{ + unsigned char *dptr = dest; + const unsigned char *ptr = src; + const unsigned char *end = src + size; + + while (ptr < end) + *dptr++ = *ptr++; + + return dest; +} + +void *memset(void *inptr, int ch, size_t size) +{ + char *ptr = inptr; + char *end = ptr + size; + + while (ptr < end) + *ptr++ = ch; + + return ptr; +} + +int setup_info_table(struct efi_priv *priv, int size) +{ + struct efi_info_hdr *info; + efi_status_t ret; + + /* Get some memory for our info table */ + priv->info_size = size; + info = efi_malloc(priv, priv->info_size, &ret); + if (ret) { + printhex2(ret); + puts(" No memory for info table: "); + return ret; + } + + memset(info, '\0', sizeof(*info)); + info->version = EFI_TABLE_VERSION; + info->hdr_size = sizeof(*info); + priv->info = info; + priv->next_hdr = (char *)info + info->hdr_size; + + return 0; +} + +/** + * add_entry_addr() - Add a new entry to the efi_info list + * + * This adds an entry, consisting of a tag and two lots of data. This avoids the + * caller having to coalesce the data first + * + * @priv: Pointer to our private information which contains the list + * @type: Type of the entry to add + * @ptr1: Pointer to first data block to add + * @size1: Size of first data block in bytes (can be 0) + * @ptr2: Pointer to second data block to add + * @size2: Size of second data block in bytes (can be 0) + */ +void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type, void *ptr1, + int size1, void *ptr2, int size2) +{ + struct efi_entry_hdr *hdr = priv->next_hdr; + + hdr->type = type; + hdr->size = size1 + size2; + hdr->addr = 0; + hdr->link = ALIGN(sizeof(*hdr) + hdr->size, 16); + priv->next_hdr += hdr->link; + memcpy(hdr + 1, ptr1, size1); + memcpy((void *)(hdr + 1) + size1, ptr2, size2); + priv->info->total_size = (ulong)priv->next_hdr - (ulong)priv->info; +} diff --git a/lib/efi_client/stub_arm64.c b/lib/efi_client/stub_arm64.c index 47b9705acca..22c5f23865d 100644 --- a/lib/efi_client/stub_arm64.c +++ b/lib/efi_client/stub_arm64.c @@ -50,97 +50,6 @@ void puts(const char *str) putc(*str++); } - -void *memcpy(void *dest, const void *src, size_t size) -{ - unsigned char *dptr = dest; - const unsigned char *ptr = src; - const unsigned char *end = src + size; - - while (ptr < end) - *dptr++ = *ptr++; - - return dest; -} - -void *memset(void *inptr, int ch, size_t size) -{ - char *ptr = inptr; - char *end = ptr + size; - - while (ptr < end) - *ptr++ = ch; - - return ptr; -} - -/** - * setup_info_table() - sets up a table containing information from EFI - * - * We must call exit_boot_services() before jumping out of the stub into U-Boot - * proper, so that U-Boot has full control of peripherals, memory, etc. - * - * Once we do this, we cannot call any boot-services functions so we must find - * out everything we need to before doing that. - * - * Set up a struct efi_info_hdr table which can hold various records (e.g. - * struct efi_entry_memmap) with information obtained from EFI. - * - * @priv: Pointer to our private information which contains the list - * @size: Size of the table to allocate - * Return: 0 if OK, non-zero on error - */ -static int setup_info_table(struct efi_priv *priv, int size) -{ - struct efi_info_hdr *info; - efi_status_t ret; - - /* Get some memory for our info table */ - priv->info_size = size; - info = efi_malloc(priv, priv->info_size, &ret); - if (ret) { - printhex2(ret); - puts(" No memory for info table: "); - return ret; - } - - memset(info, '\0', sizeof(*info)); - info->version = EFI_TABLE_VERSION; - info->hdr_size = sizeof(*info); - priv->info = info; - priv->next_hdr = (char *)info + info->hdr_size; - - return 0; -} - -/** - * add_entry_addr() - Add a new entry to the efi_info list - * - * This adds an entry, consisting of a tag and two lots of data. This avoids the - * caller having to coalesce the data first - * - * @priv: Pointer to our private information which contains the list - * @type: Type of the entry to add - * @ptr1: Pointer to first data block to add - * @size1: Size of first data block in bytes (can be 0) - * @ptr2: Pointer to second data block to add - * @size2: Size of second data block in bytes (can be 0) - */ -static void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type, - void *ptr1, int size1, void *ptr2, int size2) -{ - struct efi_entry_hdr *hdr = priv->next_hdr; - - hdr->type = type; - hdr->size = size1 + size2; - hdr->addr = 0; - hdr->link = ALIGN(sizeof(*hdr) + hdr->size, 16); - priv->next_hdr += hdr->link; - memcpy(hdr + 1, ptr1, size1); - memcpy((void *)(hdr + 1) + size1, ptr2, size2); - priv->info->total_size = (ulong)priv->next_hdr - (ulong)priv->info; -} - /** * efi_main() - Start an EFI image * diff --git a/lib/efi_client/stub_x86.c b/lib/efi_client/stub_x86.c index 25c9159f320..a7b48eb7c09 100644 --- a/lib/efi_client/stub_x86.c +++ b/lib/efi_client/stub_x86.c @@ -91,29 +91,6 @@ static void _debug_uart_putc(int ch) DEBUG_UART_FUNCS -void *memcpy(void *dest, const void *src, size_t size) -{ - unsigned char *dptr = dest; - const unsigned char *ptr = src; - const unsigned char *end = src + size; - - while (ptr < end) - *dptr++ = *ptr++; - - return dest; -} - -void *memset(void *inptr, int ch, size_t size) -{ - char *ptr = inptr; - char *end = ptr + size; - - while (ptr < end) - *ptr++ = ch; - - return ptr; -} - static void jump_to_uboot(ulong cs32, ulong addr, ulong info) { #ifdef CONFIG_EFI_STUB_32BIT @@ -226,73 +203,6 @@ static int get_codeseg32(void) return cs32; } -/** - * setup_info_table() - sets up a table containing information from EFI - * - * We must call exit_boot_services() before jumping out of the stub into U-Boot - * proper, so that U-Boot has full control of peripherals, memory, etc. - * - * Once we do this, we cannot call any boot-services functions so we must find - * out everything we need to before doing that. - * - * Set up a struct efi_info_hdr table which can hold various records (e.g. - * struct efi_entry_memmap) with information obtained from EFI. - * - * @priv: Pointer to our private information which contains the list - * @size: Size of the table to allocate - * Return: 0 if OK, non-zero on error - */ -static int setup_info_table(struct efi_priv *priv, int size) -{ - struct efi_info_hdr *info; - efi_status_t ret; - - /* Get some memory for our info table */ - priv->info_size = size; - info = efi_malloc(priv, priv->info_size, &ret); - if (ret) { - printhex2(ret); - puts(" No memory for info table: "); - return ret; - } - - memset(info, '\0', sizeof(*info)); - info->version = EFI_TABLE_VERSION; - info->hdr_size = sizeof(*info); - priv->info = info; - priv->next_hdr = (char *)info + info->hdr_size; - - return 0; -} - -/** - * add_entry_addr() - Add a new entry to the efi_info list - * - * This adds an entry, consisting of a tag and two lots of data. This avoids the - * caller having to coalesce the data first - * - * @priv: Pointer to our private information which contains the list - * @type: Type of the entry to add - * @ptr1: Pointer to first data block to add - * @size1: Size of first data block in bytes (can be 0) - * @ptr2: Pointer to second data block to add - * @size2: Size of second data block in bytes (can be 0) - */ -static void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type, - void *ptr1, int size1, void *ptr2, int size2) -{ - struct efi_entry_hdr *hdr = priv->next_hdr; - - hdr->type = type; - hdr->size = size1 + size2; - hdr->addr = 0; - hdr->link = ALIGN(sizeof(*hdr) + hdr->size, 16); - priv->next_hdr += hdr->link; - memcpy(hdr + 1, ptr1, size1); - memcpy((void *)(hdr + 1) + size1, ptr2, size2); - priv->info->total_size = (ulong)priv->next_hdr - (ulong)priv->info; -} - /** * efi_main() - Start an EFI image * -- 2.43.0

From: Simon Glass <sjg@chromium.org> The x86 and ARM implementations use a different variable for the same thing, just inverted. Invent a third name for this, adjust both files to use it and store it in the common stub.c file. Signed-off-by: Simon Glass <sjg@chromium.org> --- include/efi_stub.h | 3 +++ lib/efi_client/stub.c | 9 +++++++++ lib/efi_client/stub_arm64.c | 8 +++----- lib/efi_client/stub_x86.c | 6 ++---- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/include/efi_stub.h b/include/efi_stub.h index eb2da6a76d3..d788ce4984e 100644 --- a/include/efi_stub.h +++ b/include/efi_stub.h @@ -100,4 +100,7 @@ int setup_info_table(struct efi_priv *priv, int size); void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type, void *ptr1, int size1, void *ptr2, int size2); +/* true if we must use the hardware UART directory (EFI not available) */ +extern bool use_hw_uart; + #endif /* _EFI_STUB_H */ diff --git a/lib/efi_client/stub.c b/lib/efi_client/stub.c index cf0314ba6a6..fad669cb64d 100644 --- a/lib/efi_client/stub.c +++ b/lib/efi_client/stub.c @@ -13,6 +13,15 @@ #include <efi_api.h> #include <efi_stub.h> +/* + * true if we must use the hardware UART directory (EFI not available). This + * is normally false, meaning that character output is sent to the efi_putc() + * routine. Once exit-boot-services is called, we must either not use character + * output at all, or use a hardware UART directly, if there is a driver + * available. + */ +bool use_hw_uart; + int efi_stub_exit_boot_services(void) { struct efi_priv *priv = efi_get_priv(); diff --git a/lib/efi_client/stub_arm64.c b/lib/efi_client/stub_arm64.c index 22c5f23865d..b8f6d6e73c0 100644 --- a/lib/efi_client/stub_arm64.c +++ b/lib/efi_client/stub_arm64.c @@ -18,8 +18,6 @@ #include <linux/err.h> #include <linux/types.h> -static bool ebs_called; - void _debug_uart_putc(int ch) { struct efi_priv *priv = efi_get_priv(); @@ -31,7 +29,7 @@ void _debug_uart_putc(int ch) * NOTE: for development it is possible to re-implement * your boards debug uart here like in efi_stub.c for x86. */ - if (!ebs_called) + if (!use_hw_uart) efi_putc(priv, ch); } @@ -68,7 +66,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; efi_status_t ret; - ebs_called = false; + use_hw_uart = false; ret = efi_init(priv, "Payload", image, sys_table); if (ret) { @@ -117,7 +115,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, return ret; /* The EFI console won't work now :( */ - ebs_called = true; + use_hw_uart = true; map.version = priv->memmap_version; map.desc_size = priv->memmap_desc_size; diff --git a/lib/efi_client/stub_x86.c b/lib/efi_client/stub_x86.c index a7b48eb7c09..e9276ee825d 100644 --- a/lib/efi_client/stub_x86.c +++ b/lib/efi_client/stub_x86.c @@ -31,8 +31,6 @@ #error "This file needs to be ported for use on architectures" #endif -static bool use_uart; - struct __packed desctab_info { uint16_t limit; uint64_t addr; @@ -67,7 +65,7 @@ void putc(const char ch) if (ch == '\n') putc('\r'); - if (use_uart) { + if (use_hw_uart) { struct ns16550 *com_port = (struct ns16550 *)0x3f8; while ((inb((ulong)&com_port->lsr) & UART_LSR_THRE) == 0) @@ -262,7 +260,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, return ret; /* The EFI UART won't work now, switch to a debug one */ - use_uart = true; + use_hw_uart = true; map.version = priv->memmap_version; map.desc_size = priv->memmap_desc_size; -- 2.43.0

From: Simon Glass <sjg@chromium.org> At present x86 and ARM have different implementations, but they are similar enough that it is not too hard to unify them. Create a new common function, with arch-specific pieces at the start (setting up the address to which to copy U-Boot) and end (to jump to U-Boot). For now, nothing uses this code. Signed-off-by: Simon Glass <sjg@chromium.org> --- include/efi.h | 2 + include/efi_stub.h | 20 +++++++++ lib/efi_client/stub.c | 94 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/include/efi.h b/include/efi.h index 99a209e86c6..7a725343616 100644 --- a/include/efi.h +++ b/include/efi.h @@ -473,6 +473,7 @@ static inline struct efi_mem_desc *efi_get_next_mem_desc( * to U-Boot * @info_size: Size of the info list @info in bytes * @next_hdr: Pointer to where to put the next header when adding to the list + * @jump_addr: Address to jump to to start U-Boot */ struct efi_priv { efi_handle_t parent_image; @@ -496,6 +497,7 @@ struct efi_priv { struct efi_info_hdr *info; unsigned int info_size; void *next_hdr; + ulong jump_addr; }; /* diff --git a/include/efi_stub.h b/include/efi_stub.h index d788ce4984e..8dcde1b61d1 100644 --- a/include/efi_stub.h +++ b/include/efi_stub.h @@ -8,6 +8,7 @@ #ifndef _EFI_STUB_H #define _EFI_STUB_H +#include <efi.h> #include <linux/types.h> struct efi_priv; @@ -100,6 +101,25 @@ int setup_info_table(struct efi_priv *priv, int size); void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type, void *ptr1, int size1, void *ptr2, int size2); +/** + * arch_efi_main_init() - Set up the stub ready for use + * + * @priv: Pointer to private information + * @boot: Boot-services table + * Return: 0 if OK, or EFI error code + */ +efi_status_t arch_efi_main_init(struct efi_priv *priv, + struct efi_boot_services *boot); + +/** + * arch_efi_jump_to_payload() - Jump to the U-Boot payload + * + * Jumps to U-Boot in an arch-specific way + * + * @priv: Pointer to private information + */ +void arch_efi_jump_to_payload(struct efi_priv *priv); + /* true if we must use the hardware UART directory (EFI not available) */ extern bool use_hw_uart; diff --git a/lib/efi_client/stub.c b/lib/efi_client/stub.c index fad669cb64d..2681714d068 100644 --- a/lib/efi_client/stub.c +++ b/lib/efi_client/stub.c @@ -119,3 +119,97 @@ void add_entry_addr(struct efi_priv *priv, enum efi_entry_t type, void *ptr1, memcpy((void *)(hdr + 1) + size1, ptr2, size2); priv->info->total_size = (ulong)priv->next_hdr - (ulong)priv->info; } + +static void efi_copy_code(struct efi_priv *priv) +{ + memcpy((void *)priv->jump_addr, _binary_u_boot_bin_start, + (ulong)_binary_u_boot_bin_end - + (ulong)_binary_u_boot_bin_start); +} + +/** + * efi_main_common() - Start an EFI image + * + * This function is called by our EFI start-up code. It handles running + * U-Boot. If it returns, EFI will continue. + */ +efi_status_t EFIAPI efi_main_common(efi_handle_t image, + struct efi_system_table *sys_table) +{ + struct efi_priv local_priv, *priv = &local_priv; + struct efi_boot_services *boot = sys_table->boottime; + struct efi_entry_memmap map; + struct efi_gop *gop; + struct efi_entry_gopmode mode; + struct efi_entry_systable table; + efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + efi_status_t ret; + + /* initially we can use the EFI UART */ + use_hw_uart = false; + + ret = efi_init(priv, "Payload", image, sys_table); + if (ret) { + printhex2(ret); + puts(" efi_init() failed\n"); + return ret; + } + efi_set_priv(priv); + +#if 0 /* to be enabled */ + ret = arch_efi_main_init(priv, boot); + if (ret) + return ret; +#endif + ret = efi_store_memory_map(priv); + if (ret) + return ret; + + ret = setup_info_table(priv, priv->memmap_size + 128); + if (ret) + return ret; + + ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop); + if (ret) { + puts(" GOP unavailable\n"); + } else { + mode.fb_base = gop->mode->fb_base; + mode.fb_size = gop->mode->fb_size; + mode.info_size = gop->mode->info_size; + add_entry_addr(priv, EFIET_GOP_MODE, &mode, sizeof(mode), + gop->mode->info, + sizeof(struct efi_gop_mode_info)); + } + + table.sys_table = (ulong)sys_table; + add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0); + + ret = efi_stub_exit_boot_services(); + if (ret) + return ret; + + /* The EFI UART won't work now, switch to a debug one */ + use_hw_uart = true; + + map.version = priv->memmap_version; + map.desc_size = priv->memmap_desc_size; + add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), + priv->memmap_desc, priv->memmap_size); + add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0); + + efi_copy_code(priv); + +/* This will only work if you patched your own debug uart into this file. */ +#ifdef DEBUG + puts("EFI table at "); + printhex8((ulong)priv->info); + puts(" size "); + printhex8(priv->info->total_size); + putc('\n'); +#endif +#if 0 /* to be enabled */ + arch_efi_jump_to_payload(priv); +#endif + + return EFI_LOAD_ERROR; +} -- 2.43.0

From: Simon Glass <sjg@chromium.org> Fill in the required helper functions and call efi_main_common() to do everything else. Delete the old efi_main() function. Signed-off-by: Simon Glass <sjg@chromium.org> --- include/efi.h | 2 + include/efi_stub.h | 3 ++ lib/efi_client/stub.c | 4 +- lib/efi_client/stub_x86.c | 85 +++++++-------------------------------- 4 files changed, 21 insertions(+), 73 deletions(-) diff --git a/include/efi.h b/include/efi.h index 7a725343616..302c662a8a7 100644 --- a/include/efi.h +++ b/include/efi.h @@ -474,6 +474,7 @@ static inline struct efi_mem_desc *efi_get_next_mem_desc( * @info_size: Size of the info list @info in bytes * @next_hdr: Pointer to where to put the next header when adding to the list * @jump_addr: Address to jump to to start U-Boot + * @x86_cs32: x86 code-segment to use for U-Boot */ struct efi_priv { efi_handle_t parent_image; @@ -498,6 +499,7 @@ struct efi_priv { unsigned int info_size; void *next_hdr; ulong jump_addr; + int x86_cs32; }; /* diff --git a/include/efi_stub.h b/include/efi_stub.h index 8dcde1b61d1..17637a8845d 100644 --- a/include/efi_stub.h +++ b/include/efi_stub.h @@ -120,6 +120,9 @@ efi_status_t arch_efi_main_init(struct efi_priv *priv, */ void arch_efi_jump_to_payload(struct efi_priv *priv); +efi_status_t EFIAPI efi_main_common(efi_handle_t image, + struct efi_system_table *sys_table); + /* true if we must use the hardware UART directory (EFI not available) */ extern bool use_hw_uart; diff --git a/lib/efi_client/stub.c b/lib/efi_client/stub.c index 2681714d068..0ee6e0135bb 100644 --- a/lib/efi_client/stub.c +++ b/lib/efi_client/stub.c @@ -156,7 +156,7 @@ efi_status_t EFIAPI efi_main_common(efi_handle_t image, } efi_set_priv(priv); -#if 0 /* to be enabled */ +#ifdef CONFIG_X86 ret = arch_efi_main_init(priv, boot); if (ret) return ret; @@ -207,7 +207,7 @@ efi_status_t EFIAPI efi_main_common(efi_handle_t image, printhex8(priv->info->total_size); putc('\n'); #endif -#if 0 /* to be enabled */ +#ifdef CONFIG_X86 arch_efi_jump_to_payload(priv); #endif diff --git a/lib/efi_client/stub_x86.c b/lib/efi_client/stub_x86.c index e9276ee825d..66349136e44 100644 --- a/lib/efi_client/stub_x86.c +++ b/lib/efi_client/stub_x86.c @@ -201,85 +201,28 @@ static int get_codeseg32(void) return cs32; } -/** - * efi_main() - Start an EFI image - * - * This function is called by our EFI start-up code. It handles running - * U-Boot. If it returns, EFI will continue. - */ -efi_status_t EFIAPI efi_main(efi_handle_t image, - struct efi_system_table *sys_table) +efi_status_t arch_efi_main_init(struct efi_priv *priv, + struct efi_boot_services *boot) { - struct efi_priv local_priv, *priv = &local_priv; - struct efi_boot_services *boot = sys_table->boottime; - struct efi_entry_memmap map; - struct efi_gop *gop; - struct efi_entry_gopmode mode; - struct efi_entry_systable table; - efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - efi_status_t ret; int cs32; - ret = efi_init(priv, "Payload", image, sys_table); - if (ret) { - printhex2(ret); - puts(" efi_init() failed\n"); - return ret; - } - efi_set_priv(priv); - cs32 = get_codeseg32(); if (cs32 < 0) return EFI_UNSUPPORTED; + priv->x86_cs32 = cs32; - ret = efi_store_memory_map(priv); - if (ret) - return ret; - - ret = setup_info_table(priv, priv->memmap_size + 128); - if (ret) - return ret; - - ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop); - if (ret) { - puts(" GOP unavailable\n"); - } else { - mode.fb_base = gop->mode->fb_base; - mode.fb_size = gop->mode->fb_size; - mode.info_size = gop->mode->info_size; - add_entry_addr(priv, EFIET_GOP_MODE, &mode, sizeof(mode), - gop->mode->info, - sizeof(struct efi_gop_mode_info)); - } - - table.sys_table = (ulong)sys_table; - add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0); + priv->jump_addr = CONFIG_TEXT_BASE; - ret = efi_stub_exit_boot_services(); - if (ret) - return ret; - - /* The EFI UART won't work now, switch to a debug one */ - use_hw_uart = true; - - map.version = priv->memmap_version; - map.desc_size = priv->memmap_desc_size; - add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), - priv->memmap_desc, priv->memmap_size); - add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0); - - memcpy((void *)CONFIG_TEXT_BASE, _binary_u_boot_bin_start, - (ulong)_binary_u_boot_bin_end - - (ulong)_binary_u_boot_bin_start); + return 0; +} -#ifdef DEBUG - puts("EFI table at "); - printhex8((ulong)priv->info); - puts(" size "); - printhex8(priv->info->total_size); -#endif - putc('\n'); - jump_to_uboot(cs32, CONFIG_TEXT_BASE, (ulong)priv->info); +void arch_efi_jump_to_payload(struct efi_priv *priv) +{ + jump_to_uboot(priv->x86_cs32, priv->jump_addr, (ulong)priv->info); +} - return EFI_LOAD_ERROR; +efi_status_t EFIAPI efi_main(efi_handle_t image, + struct efi_system_table *sys_table) +{ + return efi_main_common(image, sys_table); } -- 2.43.0

From: Simon Glass <sjg@chromium.org> Fill in the required helper functions and call efi_main_common() to do everything else. Delete the old efi_main() function. Signed-off-by: Simon Glass <sjg@chromium.org> --- lib/efi_client/stub.c | 5 +- lib/efi_client/stub_arm64.c | 92 ++++++------------------------------- 2 files changed, 16 insertions(+), 81 deletions(-) diff --git a/lib/efi_client/stub.c b/lib/efi_client/stub.c index 0ee6e0135bb..b51f8160ec7 100644 --- a/lib/efi_client/stub.c +++ b/lib/efi_client/stub.c @@ -156,11 +156,10 @@ efi_status_t EFIAPI efi_main_common(efi_handle_t image, } efi_set_priv(priv); -#ifdef CONFIG_X86 ret = arch_efi_main_init(priv, boot); if (ret) return ret; -#endif + ret = efi_store_memory_map(priv); if (ret) return ret; @@ -207,9 +206,7 @@ efi_status_t EFIAPI efi_main_common(efi_handle_t image, printhex8(priv->info->total_size); putc('\n'); #endif -#ifdef CONFIG_X86 arch_efi_jump_to_payload(priv); -#endif return EFI_LOAD_ERROR; } diff --git a/lib/efi_client/stub_arm64.c b/lib/efi_client/stub_arm64.c index b8f6d6e73c0..af78c518422 100644 --- a/lib/efi_client/stub_arm64.c +++ b/lib/efi_client/stub_arm64.c @@ -48,35 +48,12 @@ void puts(const char *str) putc(*str++); } -/** - * efi_main() - Start an EFI image - * - * This function is called by our EFI start-up code. It handles running - * U-Boot. If it returns, EFI will continue. - */ -efi_status_t EFIAPI efi_main(efi_handle_t image, - struct efi_system_table *sys_table) +efi_status_t arch_efi_main_init(struct efi_priv *priv, + struct efi_boot_services *boot) { - struct efi_priv local_priv, *priv = &local_priv; - struct efi_boot_services *boot = sys_table->boottime; - struct efi_entry_memmap map; - struct efi_gop *gop; - struct efi_entry_gopmode mode; - struct efi_entry_systable table; - efi_guid_t efi_gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - efi_status_t ret; - - use_hw_uart = false; - - ret = efi_init(priv, "Payload", image, sys_table); - if (ret) { - printhex2(ret); - puts(" efi_init() failed\n"); - return ret; - } - efi_set_priv(priv); - phys_addr_t reloc_addr = ULONG_MAX; + int ret; + ret = boot->allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_CODE, (phys_addr_t)_binary_u_boot_bin_size / EFI_PAGE_SIZE, &reloc_addr); @@ -86,59 +63,20 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, putc('\n'); return ret; } + priv->jump_addr = reloc_addr; - ret = efi_store_memory_map(priv); - if (ret) - return ret; - - ret = setup_info_table(priv, priv->memmap_size + 128); - if (ret) - return ret; - - ret = boot->locate_protocol(&efi_gop_guid, NULL, (void **)&gop); - if (ret) { - puts(" GOP unavailable\n"); - } else { - mode.fb_base = gop->mode->fb_base; - mode.fb_size = gop->mode->fb_size; - mode.info_size = gop->mode->info_size; - add_entry_addr(priv, EFIET_GOP_MODE, &mode, sizeof(mode), - gop->mode->info, - sizeof(struct efi_gop_mode_info)); - } - - table.sys_table = (ulong)sys_table; - add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0); - - ret = efi_stub_exit_boot_services(); - if (ret) - return ret; - - /* The EFI console won't work now :( */ - use_hw_uart = true; - - map.version = priv->memmap_version; - map.desc_size = priv->memmap_desc_size; - add_entry_addr(priv, EFIET_MEMORY_MAP, &map, sizeof(map), - priv->memmap_desc, priv->memmap_size); - add_entry_addr(priv, EFIET_END, NULL, 0, 0, 0); - - memcpy((void *)reloc_addr, _binary_u_boot_bin_start, - (ulong)_binary_u_boot_bin_end - - (ulong)_binary_u_boot_bin_start); + return 0; +} -/* This will only work if you patched your own debug uart into this file. */ -#ifdef DEBUG - puts("EFI table at "); - printhex8((ulong)priv->info); - puts(" size "); - printhex8(priv->info->total_size); - putc('\n'); -#endif +void arch_efi_jump_to_payload(struct efi_priv *priv) +{ typedef void (*func_t)(u64 x0, u64 x1, u64 x2, u64 x3); - puts("Jumping to U-Boot\n"); - ((func_t)reloc_addr)((phys_addr_t)priv->info, 0, 0, 0); + ((func_t)priv->jump_addr)((phys_addr_t)priv->info, 0, 0, 0); +} - return EFI_LOAD_ERROR; +efi_status_t EFIAPI efi_main(efi_handle_t image, + struct efi_system_table *sys_table) +{ + return efi_main_common(image, sys_table); } -- 2.43.0

From: Simon Glass <sjg@chromium.org> Now that the stub code is unified, switch over to it, dropping the individual efi_main() functions. Signed-off-by: Simon Glass <sjg@chromium.org> --- include/efi_stub.h | 3 --- lib/efi_client/stub.c | 6 +++--- lib/efi_client/stub_arm64.c | 6 ------ lib/efi_client/stub_x86.c | 6 ------ 4 files changed, 3 insertions(+), 18 deletions(-) diff --git a/include/efi_stub.h b/include/efi_stub.h index 17637a8845d..8dcde1b61d1 100644 --- a/include/efi_stub.h +++ b/include/efi_stub.h @@ -120,9 +120,6 @@ efi_status_t arch_efi_main_init(struct efi_priv *priv, */ void arch_efi_jump_to_payload(struct efi_priv *priv); -efi_status_t EFIAPI efi_main_common(efi_handle_t image, - struct efi_system_table *sys_table); - /* true if we must use the hardware UART directory (EFI not available) */ extern bool use_hw_uart; diff --git a/lib/efi_client/stub.c b/lib/efi_client/stub.c index b51f8160ec7..27366937c18 100644 --- a/lib/efi_client/stub.c +++ b/lib/efi_client/stub.c @@ -128,13 +128,13 @@ static void efi_copy_code(struct efi_priv *priv) } /** - * efi_main_common() - Start an EFI image + * efi_main() - Start an EFI image * * This function is called by our EFI start-up code. It handles running * U-Boot. If it returns, EFI will continue. */ -efi_status_t EFIAPI efi_main_common(efi_handle_t image, - struct efi_system_table *sys_table) +efi_status_t EFIAPI efi_main(efi_handle_t image, + struct efi_system_table *sys_table) { struct efi_priv local_priv, *priv = &local_priv; struct efi_boot_services *boot = sys_table->boottime; diff --git a/lib/efi_client/stub_arm64.c b/lib/efi_client/stub_arm64.c index af78c518422..0e579a17a75 100644 --- a/lib/efi_client/stub_arm64.c +++ b/lib/efi_client/stub_arm64.c @@ -74,9 +74,3 @@ void arch_efi_jump_to_payload(struct efi_priv *priv) ((func_t)priv->jump_addr)((phys_addr_t)priv->info, 0, 0, 0); } - -efi_status_t EFIAPI efi_main(efi_handle_t image, - struct efi_system_table *sys_table) -{ - return efi_main_common(image, sys_table); -} diff --git a/lib/efi_client/stub_x86.c b/lib/efi_client/stub_x86.c index 66349136e44..fac55fa8f32 100644 --- a/lib/efi_client/stub_x86.c +++ b/lib/efi_client/stub_x86.c @@ -220,9 +220,3 @@ void arch_efi_jump_to_payload(struct efi_priv *priv) { jump_to_uboot(priv->x86_cs32, priv->jump_addr, (ulong)priv->info); } - -efi_status_t EFIAPI efi_main(efi_handle_t image, - struct efi_system_table *sys_table) -{ - return efi_main_common(image, sys_table); -} -- 2.43.0
participants (1)
-
Simon Glass