14ca4b265SAlexander Graf# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
24ca4b265SAlexander Graf# Copyright (c) 2016, Alexander Graf <agraf@suse.de>
34ca4b265SAlexander Graf#
44ca4b265SAlexander Graf# based on test_net.py.
54ca4b265SAlexander Graf#
64ca4b265SAlexander Graf# SPDX-License-Identifier: GPL-2.0
74ca4b265SAlexander Graf
84ca4b265SAlexander Graf# Test efi loader implementation
94ca4b265SAlexander Graf
104ca4b265SAlexander Grafimport pytest
114ca4b265SAlexander Grafimport u_boot_utils
124ca4b265SAlexander Graf
134ca4b265SAlexander Graf"""
144ca4b265SAlexander GrafNote: This test relies on boardenv_* containing configuration values to define
154ca4b265SAlexander Grafwhich the network environment available for testing. Without this, the parts
164ca4b265SAlexander Grafthat rely on network will be automatically skipped.
174ca4b265SAlexander Graf
184ca4b265SAlexander GrafFor example:
194ca4b265SAlexander Graf
204ca4b265SAlexander Graf# Boolean indicating whether the Ethernet device is attached to USB, and hence
214ca4b265SAlexander Graf# USB enumeration needs to be performed prior to network tests.
224ca4b265SAlexander Graf# This variable may be omitted if its value is False.
234ca4b265SAlexander Grafenv__net_uses_usb = False
244ca4b265SAlexander Graf
254ca4b265SAlexander Graf# Boolean indicating whether the Ethernet device is attached to PCI, and hence
264ca4b265SAlexander Graf# PCI enumeration needs to be performed prior to network tests.
274ca4b265SAlexander Graf# This variable may be omitted if its value is False.
284ca4b265SAlexander Grafenv__net_uses_pci = True
294ca4b265SAlexander Graf
304ca4b265SAlexander Graf# True if a DHCP server is attached to the network, and should be tested.
314ca4b265SAlexander Graf# If DHCP testing is not possible or desired, this variable may be omitted or
324ca4b265SAlexander Graf# set to False.
334ca4b265SAlexander Grafenv__net_dhcp_server = True
344ca4b265SAlexander Graf
354ca4b265SAlexander Graf# A list of environment variables that should be set in order to configure a
364ca4b265SAlexander Graf# static IP. If solely relying on DHCP, this variable may be omitted or set to
374ca4b265SAlexander Graf# an empty list.
384ca4b265SAlexander Grafenv__net_static_env_vars = [
394ca4b265SAlexander Graf    ("ipaddr", "10.0.0.100"),
404ca4b265SAlexander Graf    ("netmask", "255.255.255.0"),
414ca4b265SAlexander Graf    ("serverip", "10.0.0.1"),
424ca4b265SAlexander Graf]
434ca4b265SAlexander Graf
444ca4b265SAlexander Graf# Details regarding a file that may be read from a TFTP server. This variable
454ca4b265SAlexander Graf# may be omitted or set to None if TFTP testing is not possible or desired.
464ca4b265SAlexander Grafenv__efi_loader_helloworld_file = {
474ca4b265SAlexander Graf    "fn": "lib/efi_loader/helloworld.efi",
484ca4b265SAlexander Graf    "size": 5058624,
494ca4b265SAlexander Graf    "crc32": "c2244b26",
504ca4b265SAlexander Graf}
514ca4b265SAlexander Graf"""
524ca4b265SAlexander Graf
534ca4b265SAlexander Grafnet_set_up = False
544ca4b265SAlexander Graf
554ca4b265SAlexander Grafdef test_efi_pre_commands(u_boot_console):
564ca4b265SAlexander Graf    """Execute any commands required to enable network hardware.
574ca4b265SAlexander Graf
584ca4b265SAlexander Graf    These commands are provided by the boardenv_* file; see the comment at the
594ca4b265SAlexander Graf    beginning of this file.
604ca4b265SAlexander Graf    """
614ca4b265SAlexander Graf
624ca4b265SAlexander Graf    init_usb = u_boot_console.config.env.get('env__net_uses_usb', False)
634ca4b265SAlexander Graf    if init_usb:
644ca4b265SAlexander Graf        u_boot_console.run_command('usb start')
654ca4b265SAlexander Graf
664ca4b265SAlexander Graf    init_pci = u_boot_console.config.env.get('env__net_uses_pci', False)
674ca4b265SAlexander Graf    if init_pci:
684ca4b265SAlexander Graf        u_boot_console.run_command('pci enum')
694ca4b265SAlexander Graf
704ca4b265SAlexander Graf@pytest.mark.buildconfigspec('cmd_dhcp')
714ca4b265SAlexander Grafdef test_efi_dhcp(u_boot_console):
724ca4b265SAlexander Graf    """Test the dhcp command.
734ca4b265SAlexander Graf
744ca4b265SAlexander Graf    The boardenv_* file may be used to enable/disable this test; see the
754ca4b265SAlexander Graf    comment at the beginning of this file.
764ca4b265SAlexander Graf    """
774ca4b265SAlexander Graf
784ca4b265SAlexander Graf    test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False)
794ca4b265SAlexander Graf    if not test_dhcp:
804ca4b265SAlexander Graf        pytest.skip('No DHCP server available')
814ca4b265SAlexander Graf
824ca4b265SAlexander Graf    u_boot_console.run_command('setenv autoload no')
834ca4b265SAlexander Graf    output = u_boot_console.run_command('dhcp')
844ca4b265SAlexander Graf    assert 'DHCP client bound to address ' in output
854ca4b265SAlexander Graf
864ca4b265SAlexander Graf    global net_set_up
874ca4b265SAlexander Graf    net_set_up = True
884ca4b265SAlexander Graf
894ca4b265SAlexander Graf@pytest.mark.buildconfigspec('net')
904ca4b265SAlexander Grafdef test_efi_setup_static(u_boot_console):
914ca4b265SAlexander Graf    """Set up a static IP configuration.
924ca4b265SAlexander Graf
934ca4b265SAlexander Graf    The configuration is provided by the boardenv_* file; see the comment at
944ca4b265SAlexander Graf    the beginning of this file.
954ca4b265SAlexander Graf    """
964ca4b265SAlexander Graf
974ca4b265SAlexander Graf    env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None)
984ca4b265SAlexander Graf    if not env_vars:
994ca4b265SAlexander Graf        pytest.skip('No static network configuration is defined')
1004ca4b265SAlexander Graf
1014ca4b265SAlexander Graf    for (var, val) in env_vars:
1024ca4b265SAlexander Graf        u_boot_console.run_command('setenv %s %s' % (var, val))
1034ca4b265SAlexander Graf
1044ca4b265SAlexander Graf    global net_set_up
1054ca4b265SAlexander Graf    net_set_up = True
1064ca4b265SAlexander Graf
107*0e4e38aeSAlexander Grafdef fetch_tftp_file(u_boot_console, env_conf):
108*0e4e38aeSAlexander Graf    """Grab an env described file via TFTP and return its address
1094ca4b265SAlexander Graf
110*0e4e38aeSAlexander Graf    A file as described by an env config <env_conf> is downloaded from the TFTP
111*0e4e38aeSAlexander Graf    server. The address to that file is returned.
1124ca4b265SAlexander Graf    """
1134ca4b265SAlexander Graf    if not net_set_up:
1144ca4b265SAlexander Graf        pytest.skip('Network not initialized')
1154ca4b265SAlexander Graf
116*0e4e38aeSAlexander Graf    f = u_boot_console.config.env.get(env_conf, None)
1174ca4b265SAlexander Graf    if not f:
118*0e4e38aeSAlexander Graf        pytest.skip('No %s binary specified in environment' % env_conf)
1194ca4b265SAlexander Graf
1204ca4b265SAlexander Graf    addr = f.get('addr', None)
1214ca4b265SAlexander Graf    if not addr:
1224ca4b265SAlexander Graf        addr = u_boot_utils.find_ram_base(u_boot_console) + (1024 * 1024 * 4)
1234ca4b265SAlexander Graf
1244ca4b265SAlexander Graf    fn = f['fn']
1254ca4b265SAlexander Graf    output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
1264ca4b265SAlexander Graf    expected_text = 'Bytes transferred = '
1274ca4b265SAlexander Graf    sz = f.get('size', None)
1284ca4b265SAlexander Graf    if sz:
1294ca4b265SAlexander Graf        expected_text += '%d' % sz
1304ca4b265SAlexander Graf    assert expected_text in output
1314ca4b265SAlexander Graf
1324ca4b265SAlexander Graf    expected_crc = f.get('crc32', None)
1334ca4b265SAlexander Graf    if not expected_crc:
134*0e4e38aeSAlexander Graf        return addr
1354ca4b265SAlexander Graf
1364ca4b265SAlexander Graf    if u_boot_console.config.buildconfig.get('config_cmd_crc32', 'n') != 'y':
137*0e4e38aeSAlexander Graf        return addr
1384ca4b265SAlexander Graf
1394ca4b265SAlexander Graf    output = u_boot_console.run_command('crc32 %x $filesize' % addr)
1404ca4b265SAlexander Graf    assert expected_crc in output
1414ca4b265SAlexander Graf
142*0e4e38aeSAlexander Graf    return addr
143*0e4e38aeSAlexander Graf
144*0e4e38aeSAlexander Graf@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile')
145*0e4e38aeSAlexander Grafdef test_efi_helloworld_net(u_boot_console):
146*0e4e38aeSAlexander Graf    """Run the helloworld.efi binary via TFTP.
147*0e4e38aeSAlexander Graf
148*0e4e38aeSAlexander Graf    The helloworld.efi file is downloaded from the TFTP server and gets
149*0e4e38aeSAlexander Graf    executed.
150*0e4e38aeSAlexander Graf    """
151*0e4e38aeSAlexander Graf
152*0e4e38aeSAlexander Graf    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file')
153*0e4e38aeSAlexander Graf
1544ca4b265SAlexander Graf    output = u_boot_console.run_command('bootefi %x' % addr)
1554ca4b265SAlexander Graf    expected_text = 'Hello, world'
1564ca4b265SAlexander Graf    assert expected_text in output
1574ca4b265SAlexander Graf
1584ca4b265SAlexander Graf@pytest.mark.buildconfigspec('cmd_bootefi_hello')
1594ca4b265SAlexander Grafdef test_efi_helloworld_builtin(u_boot_console):
1604ca4b265SAlexander Graf    """Run the builtin helloworld.efi binary.
1614ca4b265SAlexander Graf
1624ca4b265SAlexander Graf    The helloworld.efi file is included in U-Boot, execute it using the
1634ca4b265SAlexander Graf    special "bootefi hello" command.
1644ca4b265SAlexander Graf    """
1654ca4b265SAlexander Graf
1664ca4b265SAlexander Graf    output = u_boot_console.run_command('bootefi hello')
1674ca4b265SAlexander Graf    expected_text = 'Hello, world'
1684ca4b265SAlexander Graf    assert expected_text in output
169*0e4e38aeSAlexander Graf
170*0e4e38aeSAlexander Graf@pytest.mark.buildconfigspec('cmd_bootefi')
171*0e4e38aeSAlexander Grafdef test_efi_grub_net(u_boot_console):
172*0e4e38aeSAlexander Graf    """Run the grub.efi binary via TFTP.
173*0e4e38aeSAlexander Graf
174*0e4e38aeSAlexander Graf    The grub.efi file is downloaded from the TFTP server and gets
175*0e4e38aeSAlexander Graf    executed.
176*0e4e38aeSAlexander Graf    """
177*0e4e38aeSAlexander Graf
178*0e4e38aeSAlexander Graf    addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file')
179*0e4e38aeSAlexander Graf
180*0e4e38aeSAlexander Graf    u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False)
181*0e4e38aeSAlexander Graf
182*0e4e38aeSAlexander Graf    # Verify that we have an SMBIOS table
183*0e4e38aeSAlexander Graf    check_smbios = u_boot_console.config.env.get('env__efi_loader_check_smbios', False)
184*0e4e38aeSAlexander Graf    if check_smbios:
185*0e4e38aeSAlexander Graf        u_boot_console.wait_for('grub>')
186*0e4e38aeSAlexander Graf        output = u_boot_console.run_command('lsefisystab', wait_for_prompt=False, wait_for_echo=False)
187*0e4e38aeSAlexander Graf        u_boot_console.wait_for('SMBIOS')
188*0e4e38aeSAlexander Graf
189*0e4e38aeSAlexander Graf    # Then exit cleanly
190*0e4e38aeSAlexander Graf    u_boot_console.wait_for('grub>')
191*0e4e38aeSAlexander Graf    output = u_boot_console.run_command('exit', wait_for_prompt=False, wait_for_echo=False)
192*0e4e38aeSAlexander Graf    u_boot_console.wait_for('r = 0')
193*0e4e38aeSAlexander Graf
194*0e4e38aeSAlexander Graf    # And give us our U-Boot prompt back
195*0e4e38aeSAlexander Graf    u_boot_console.run_command('')
196