1# SPDX-License-Identifier: GPL-2.0 2# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 3# Copyright (c) 2016, Alexander Graf <agraf@suse.de> 4# 5# based on test_net.py. 6 7# Test efi loader implementation 8 9import pytest 10import u_boot_utils 11 12""" 13Note: This test relies on boardenv_* containing configuration values to define 14which network environment is available for testing. Without this, the parts 15that rely on network will be automatically skipped. 16 17For example: 18 19# Boolean indicating whether the Ethernet device is attached to USB, and hence 20# USB enumeration needs to be performed prior to network tests. 21# This variable may be omitted if its value is False. 22env__net_uses_usb = False 23 24# Boolean indicating whether the Ethernet device is attached to PCI, and hence 25# PCI enumeration needs to be performed prior to network tests. 26# This variable may be omitted if its value is False. 27env__net_uses_pci = True 28 29# True if a DHCP server is attached to the network, and should be tested. 30# If DHCP testing is not possible or desired, this variable may be omitted or 31# set to False. 32env__net_dhcp_server = True 33 34# A list of environment variables that should be set in order to configure a 35# static IP. If solely relying on DHCP, this variable may be omitted or set to 36# an empty list. 37env__net_static_env_vars = [ 38 ('ipaddr', '10.0.0.100'), 39 ('netmask', '255.255.255.0'), 40 ('serverip', '10.0.0.1'), 41] 42 43# Details regarding a file that may be read from a TFTP server. This variable 44# may be omitted or set to None if TFTP testing is not possible or desired. 45env__efi_loader_helloworld_file = { 46 'fn': 'lib/efi_loader/helloworld.efi', 47 'size': 5058624, 48 'crc32': 'c2244b26', 49} 50""" 51 52net_set_up = False 53 54def test_efi_pre_commands(u_boot_console): 55 """Execute any commands required to enable network hardware. 56 57 These commands are provided by the boardenv_* file; see the comment at the 58 beginning of this file. 59 """ 60 61 init_usb = u_boot_console.config.env.get('env__net_uses_usb', False) 62 if init_usb: 63 u_boot_console.run_command('usb start') 64 65 init_pci = u_boot_console.config.env.get('env__net_uses_pci', False) 66 if init_pci: 67 u_boot_console.run_command('pci enum') 68 69@pytest.mark.buildconfigspec('cmd_dhcp') 70def test_efi_dhcp(u_boot_console): 71 """Test the dhcp command. 72 73 The boardenv_* file may be used to enable/disable this test; see the 74 comment at the beginning of this file. 75 """ 76 77 test_dhcp = u_boot_console.config.env.get('env__net_dhcp_server', False) 78 if not test_dhcp: 79 pytest.skip('No DHCP server available') 80 81 u_boot_console.run_command('setenv autoload no') 82 output = u_boot_console.run_command('dhcp') 83 assert 'DHCP client bound to address ' in output 84 85 global net_set_up 86 net_set_up = True 87 88@pytest.mark.buildconfigspec('net') 89def test_efi_setup_static(u_boot_console): 90 """Set up a static IP configuration. 91 92 The configuration is provided by the boardenv_* file; see the comment at 93 the beginning of this file. 94 """ 95 96 env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None) 97 if not env_vars: 98 pytest.skip('No static network configuration is defined') 99 100 for (var, val) in env_vars: 101 u_boot_console.run_command('setenv %s %s' % (var, val)) 102 103 global net_set_up 104 net_set_up = True 105 106def fetch_tftp_file(u_boot_console, env_conf): 107 """Grab an env described file via TFTP and return its address 108 109 A file as described by an env config <env_conf> is downloaded from the TFTP 110 server. The address to that file is returned. 111 """ 112 if not net_set_up: 113 pytest.skip('Network not initialized') 114 115 f = u_boot_console.config.env.get(env_conf, None) 116 if not f: 117 pytest.skip('No %s binary specified in environment' % env_conf) 118 119 addr = f.get('addr', None) 120 if not addr: 121 addr = u_boot_utils.find_ram_base(u_boot_console) 122 123 fn = f['fn'] 124 output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn)) 125 expected_text = 'Bytes transferred = ' 126 sz = f.get('size', None) 127 if sz: 128 expected_text += '%d' % sz 129 assert expected_text in output 130 131 expected_crc = f.get('crc32', None) 132 if not expected_crc: 133 return addr 134 135 if u_boot_console.config.buildconfig.get('config_cmd_crc32', 'n') != 'y': 136 return addr 137 138 output = u_boot_console.run_command('crc32 %x $filesize' % addr) 139 assert expected_crc in output 140 141 return addr 142 143@pytest.mark.buildconfigspec('cmd_bootefi_hello_compile') 144def test_efi_helloworld_net(u_boot_console): 145 """Run the helloworld.efi binary via TFTP. 146 147 The helloworld.efi file is downloaded from the TFTP server and gets 148 executed. 149 """ 150 151 addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file') 152 153 output = u_boot_console.run_command('bootefi %x' % addr) 154 expected_text = 'Hello, world' 155 assert expected_text in output 156 expected_text = '## Application terminated, r = 0' 157 assert expected_text in output 158 159@pytest.mark.buildconfigspec('cmd_bootefi_hello') 160def test_efi_helloworld_builtin(u_boot_console): 161 """Run the builtin helloworld.efi binary. 162 163 The helloworld.efi file is included in U-Boot, execute it using the 164 special "bootefi hello" command. 165 """ 166 167 output = u_boot_console.run_command('bootefi hello') 168 expected_text = 'Hello, world' 169 assert expected_text in output 170 171@pytest.mark.buildconfigspec('cmd_bootefi') 172def test_efi_grub_net(u_boot_console): 173 """Run the grub.efi binary via TFTP. 174 175 The grub.efi file is downloaded from the TFTP server and gets 176 executed. 177 """ 178 179 addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_grub_file') 180 181 u_boot_console.run_command('bootefi %x' % addr, wait_for_prompt=False) 182 183 # Verify that we have an SMBIOS table 184 check_smbios = u_boot_console.config.env.get('env__efi_loader_check_smbios', False) 185 if check_smbios: 186 u_boot_console.wait_for('grub>') 187 output = u_boot_console.run_command('lsefisystab', wait_for_prompt=False, wait_for_echo=False) 188 u_boot_console.wait_for('SMBIOS') 189 190 # Then exit cleanly 191 u_boot_console.wait_for('grub>') 192 output = u_boot_console.run_command('exit', wait_for_prompt=False, wait_for_echo=False) 193 u_boot_console.wait_for('r = 0') 194 195 # And give us our U-Boot prompt back 196 u_boot_console.run_command('') 197