183d290c5STom Rini# SPDX-License-Identifier: GPL-2.0
24ca4b265SAlexander Graf# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
34ca4b265SAlexander Graf# Copyright (c) 2016, Alexander Graf <agraf@suse.de>
44ca4b265SAlexander Graf#
54ca4b265SAlexander Graf# based on test_net.py.
64ca4b265SAlexander Graf
74ca4b265SAlexander Graf# Test efi loader implementation
84ca4b265SAlexander Graf
94ca4b265SAlexander Grafimport pytest
104ca4b265SAlexander Grafimport u_boot_utils
114ca4b265SAlexander Graf
124ca4b265SAlexander Graf"""
134ca4b265SAlexander GrafNote: This test relies on boardenv_* containing configuration values to define
1483dee949SHeinrich Schuchardtwhich network environment is available for testing. Without this, the parts
154ca4b265SAlexander Grafthat rely on network will be automatically skipped.
164ca4b265SAlexander Graf
174ca4b265SAlexander GrafFor example:
184ca4b265SAlexander Graf
194ca4b265SAlexander Graf# Boolean indicating whether the Ethernet device is attached to USB, and hence
204ca4b265SAlexander Graf# USB enumeration needs to be performed prior to network tests.
214ca4b265SAlexander Graf# This variable may be omitted if its value is False.
224ca4b265SAlexander Grafenv__net_uses_usb = False
234ca4b265SAlexander Graf
244ca4b265SAlexander Graf# Boolean indicating whether the Ethernet device is attached to PCI, and hence
254ca4b265SAlexander Graf# PCI enumeration needs to be performed prior to network tests.
264ca4b265SAlexander Graf# This variable may be omitted if its value is False.
274ca4b265SAlexander Grafenv__net_uses_pci = True
284ca4b265SAlexander Graf
294ca4b265SAlexander Graf# True if a DHCP server is attached to the network, and should be tested.
304ca4b265SAlexander Graf# If DHCP testing is not possible or desired, this variable may be omitted or
314ca4b265SAlexander Graf# set to False.
324ca4b265SAlexander Grafenv__net_dhcp_server = True
334ca4b265SAlexander Graf
344ca4b265SAlexander Graf# A list of environment variables that should be set in order to configure a
354ca4b265SAlexander Graf# static IP. If solely relying on DHCP, this variable may be omitted or set to
364ca4b265SAlexander Graf# an empty list.
374ca4b265SAlexander Grafenv__net_static_env_vars = [
38*871bf7d9SSimon Glass    ('ipaddr', '10.0.0.100'),
39*871bf7d9SSimon Glass    ('netmask', '255.255.255.0'),
40*871bf7d9SSimon Glass    ('serverip', '10.0.0.1'),
414ca4b265SAlexander Graf]
424ca4b265SAlexander Graf
434ca4b265SAlexander Graf# Details regarding a file that may be read from a TFTP server. This variable
444ca4b265SAlexander Graf# may be omitted or set to None if TFTP testing is not possible or desired.
454ca4b265SAlexander Grafenv__efi_loader_helloworld_file = {
46*871bf7d9SSimon Glass    'fn': 'lib/efi_loader/helloworld.efi',
47*871bf7d9SSimon Glass    'size': 5058624,
48*871bf7d9SSimon Glass    'crc32': 'c2244b26',
494ca4b265SAlexander Graf}
504ca4b265SAlexander Graf"""
514ca4b265SAlexander Graf
524ca4b265SAlexander Grafnet_set_up = False
534ca4b265SAlexander Graf
544ca4b265SAlexander Grafdef test_efi_pre_commands(u_boot_console):
554ca4b265SAlexander Graf    """Execute any commands required to enable network hardware.
564ca4b265SAlexander Graf
574ca4b265SAlexander Graf    These commands are provided by the boardenv_* file; see the comment at the
584ca4b265SAlexander Graf    beginning of this file.
594ca4b265SAlexander Graf    """
604ca4b265SAlexander Graf
614ca4b265SAlexander Graf    init_usb = u_boot_console.config.env.get('env__net_uses_usb', False)
624ca4b265SAlexander Graf    if init_usb:
634ca4b265SAlexander Graf        u_boot_console.run_command('usb start')
644ca4b265SAlexander Graf
654ca4b265SAlexander Graf    init_pci = u_boot_console.config.env.get('env__net_uses_pci', False)
664ca4b265SAlexander Graf    if init_pci:
674ca4b265SAlexander Graf        u_boot_console.run_command('pci enum')
684ca4b265SAlexander Graf
694ca4b265SAlexander Graf@pytest.mark.buildconfigspec('cmd_dhcp')
704ca4b265SAlexander Grafdef test_efi_dhcp(u_boot_console):
714ca4b265SAlexander Graf    """Test the dhcp command.
724ca4b265SAlexander Graf
734ca4b265SAlexander Graf    The boardenv_* file may be used to enable/disable this test; see the
744ca4b265SAlexander Graf    comment at the beginning of this file.
754ca4b265SAlexander Graf    """
764ca4b265SAlexander Graf
774ca4b265SAlexander Graf    test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False)
784ca4b265SAlexander Graf    if not test_dhcp:
794ca4b265SAlexander Graf        pytest.skip('No DHCP server available')
804ca4b265SAlexander Graf
814ca4b265SAlexander Graf    u_boot_console.run_command('setenv autoload no')
824ca4b265SAlexander Graf    output = u_boot_console.run_command('dhcp')
834ca4b265SAlexander Graf    assert 'DHCP client bound to address ' in output
844ca4b265SAlexander Graf
854ca4b265SAlexander Graf    global net_set_up
864ca4b265SAlexander Graf    net_set_up = True
874ca4b265SAlexander Graf
884ca4b265SAlexander Graf@pytest.mark.buildconfigspec('net')
894ca4b265SAlexander Grafdef test_efi_setup_static(u_boot_console):
904ca4b265SAlexander Graf    """Set up a static IP configuration.
914ca4b265SAlexander Graf
924ca4b265SAlexander Graf    The configuration is provided by the boardenv_* file; see the comment at
934ca4b265SAlexander Graf    the beginning of this file.
944ca4b265SAlexander Graf    """
954ca4b265SAlexander Graf
964ca4b265SAlexander Graf    env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None)
974ca4b265SAlexander Graf    if not env_vars:
984ca4b265SAlexander Graf        pytest.skip('No static network configuration is defined')
994ca4b265SAlexander Graf
1004ca4b265SAlexander Graf    for (var, val) in env_vars:
1014ca4b265SAlexander Graf        u_boot_console.run_command('setenv %s %s' % (var, val))
1024ca4b265SAlexander Graf
1034ca4b265SAlexander Graf    global net_set_up
1044ca4b265SAlexander Graf    net_set_up = True
1054ca4b265SAlexander Graf
1060e4e38aeSAlexander Grafdef fetch_tftp_file(u_boot_console, env_conf):
1070e4e38aeSAlexander Graf    """Grab an env described file via TFTP and return its address
1084ca4b265SAlexander Graf
1090e4e38aeSAlexander Graf    A file as described by an env config <env_conf> is downloaded from the TFTP
1100e4e38aeSAlexander Graf    server. The address to that file is returned.
1114ca4b265SAlexander Graf    """
1124ca4b265SAlexander Graf    if not net_set_up:
1134ca4b265SAlexander Graf        pytest.skip('Network not initialized')
1144ca4b265SAlexander Graf
1150e4e38aeSAlexander Graf    f = u_boot_console.config.env.get(env_conf, None)
1164ca4b265SAlexander Graf    if not f:
1170e4e38aeSAlexander Graf        pytest.skip('No %s binary specified in environment' % env_conf)
1184ca4b265SAlexander Graf
1194ca4b265SAlexander Graf    addr = f.get('addr', None)
1204ca4b265SAlexander Graf    if not addr:
121f4eef40bSQuentin Schulz        addr = u_boot_utils.find_ram_base(u_boot_console)
1224ca4b265SAlexander Graf
1234ca4b265SAlexander Graf    fn = f['fn']
1244ca4b265SAlexander Graf    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
1254ca4b265SAlexander Graf    expected_text = 'Bytes transferred = '
1264ca4b265SAlexander Graf    sz = f.get('size', None)
1274ca4b265SAlexander Graf    if sz:
1284ca4b265SAlexander Graf        expected_text += '%d' % sz
1294ca4b265SAlexander Graf    assert expected_text in output
1304ca4b265SAlexander Graf
1314ca4b265SAlexander Graf    expected_crc = f.get('crc32', None)
1324ca4b265SAlexander Graf    if not expected_crc:
1330e4e38aeSAlexander Graf        return addr
1344ca4b265SAlexander Graf
1354ca4b265SAlexander Graf    if u_boot_console.config.buildconfig.get('config_cmd_crc32', 'n') != 'y':
1360e4e38aeSAlexander Graf        return addr
1374ca4b265SAlexander Graf
1384ca4b265SAlexander Graf    output = u_boot_console.run_command('crc32 %x $filesize' % addr)
1394ca4b265SAlexander Graf    assert expected_crc in output
1404ca4b265SAlexander Graf
1410e4e38aeSAlexander Graf    return addr
1420e4e38aeSAlexander Graf
1430e4e38aeSAlexander Graf@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
1440e4e38aeSAlexander Grafdef test_efi_helloworld_net(u_boot_console):
1450e4e38aeSAlexander Graf    """Run the helloworld.efi binary via TFTP.
1460e4e38aeSAlexander Graf
1470e4e38aeSAlexander Graf    The helloworld.efi file is downloaded from the TFTP server and gets
1480e4e38aeSAlexander Graf    executed.
1490e4e38aeSAlexander Graf    """
1500e4e38aeSAlexander Graf
1510e4e38aeSAlexander Graf    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
1520e4e38aeSAlexander Graf
1534ca4b265SAlexander Graf    output = u_boot_console.run_command('bootefi %x' % addr)
1544ca4b265SAlexander Graf    expected_text = 'Hello, world'
1554ca4b265SAlexander Graf    assert expected_text in output
15645055aacSHeinrich Schuchardt    expected_text = '## Application terminated, r = 0'
15745055aacSHeinrich Schuchardt    assert expected_text in output
1584ca4b265SAlexander Graf
1594ca4b265SAlexander Graf@pytest.mark.buildconfigspec('cmd_bootefi_hello')
1604ca4b265SAlexander Grafdef test_efi_helloworld_builtin(u_boot_console):
1614ca4b265SAlexander Graf    """Run the builtin helloworld.efi binary.
1624ca4b265SAlexander Graf
1634ca4b265SAlexander Graf    The helloworld.efi file is included in U-Boot, execute it using the
1644ca4b265SAlexander Graf    special "bootefi hello" command.
1654ca4b265SAlexander Graf    """
1664ca4b265SAlexander Graf
1674ca4b265SAlexander Graf    output = u_boot_console.run_command('bootefi hello')
1684ca4b265SAlexander Graf    expected_text = 'Hello, world'
1694ca4b265SAlexander Graf    assert expected_text in output
1700e4e38aeSAlexander Graf
1710e4e38aeSAlexander Graf@pytest.mark.buildconfigspec('cmd_bootefi')
1720e4e38aeSAlexander Grafdef test_efi_grub_net(u_boot_console):
1730e4e38aeSAlexander Graf    """Run the grub.efi binary via TFTP.
1740e4e38aeSAlexander Graf
1750e4e38aeSAlexander Graf    The grub.efi file is downloaded from the TFTP server and gets
1760e4e38aeSAlexander Graf    executed.
1770e4e38aeSAlexander Graf    """
1780e4e38aeSAlexander Graf
1790e4e38aeSAlexander Graf    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
1800e4e38aeSAlexander Graf
1810e4e38aeSAlexander Graf    u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)
1820e4e38aeSAlexander Graf
1830e4e38aeSAlexander Graf    # Verify that we have an SMBIOS table
1840e4e38aeSAlexander Graf    check_smbios = u_boot_console.config.env.get('env__efi_loader_check_smbios', False)
1850e4e38aeSAlexander Graf    if check_smbios:
1860e4e38aeSAlexander Graf        u_boot_console.wait_for('grub>')
1870e4e38aeSAlexander Graf        output = u_boot_console.run_command('lsefisystab', wait_for_prompt=False, wait_for_echo=False)
1880e4e38aeSAlexander Graf        u_boot_console.wait_for('SMBIOS')
1890e4e38aeSAlexander Graf
1900e4e38aeSAlexander Graf    # Then exit cleanly
1910e4e38aeSAlexander Graf    u_boot_console.wait_for('grub>')
1920e4e38aeSAlexander Graf    output = u_boot_console.run_command('exit', wait_for_prompt=False, wait_for_echo=False)
1930e4e38aeSAlexander Graf    u_boot_console.wait_for('r = 0')
1940e4e38aeSAlexander Graf
1950e4e38aeSAlexander Graf    # And give us our U-Boot prompt back
1960e4e38aeSAlexander Graf    u_boot_console.run_command('')
197