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 9""" 10Note: This test relies on boardenv_* containing configuration values to define 11which network environment is available for testing. Without this, the parts 12that rely on network will be automatically skipped. 13 14For example: 15 16.. code-block:: python 17 18 # Boolean indicating whether the Ethernet device is attached to USB, and hence 19 # USB enumeration needs to be performed prior to network tests. 20 # This variable may be omitted if its value is False. 21 env__net_uses_usb = False 22 23 # Boolean indicating whether the Ethernet device is attached to PCI, and hence 24 # PCI enumeration needs to be performed prior to network tests. 25 # This variable may be omitted if its value is False. 26 env__net_uses_pci = True 27 28 # True if a DHCP server is attached to the network, and should be tested. 29 # If DHCP testing is not possible or desired, this variable may be omitted or 30 # set to False. 31 env__net_dhcp_server = True 32 33 # A list of environment variables that should be set in order to configure a 34 # static IP. If solely relying on DHCP, this variable may be omitted or set to 35 # an empty list. 36 env__net_static_env_vars = [ 37 ('ipaddr', '10.0.0.100'), 38 ('netmask', '255.255.255.0'), 39 ('serverip', '10.0.0.1'), 40 ] 41 42 # Details regarding a file that may be read from a TFTP server. This variable 43 # may be omitted or set to None if TFTP testing is not possible or desired. 44 env__efi_loader_helloworld_file = { 45 'fn': 'lib/efi_loader/helloworld.efi', # file name 46 'size': 5058624, # file length in bytes 47 'crc32': 'c2244b26', # CRC32 check sum 48 'addr': 0x40400000, # load address 49 } 50 51 # False if the helloworld EFI over HTTP boot test should be performed. 52 # If HTTP boot testing is not possible or desired, set this variable to True or 53 # ommit it. 54 env__efi_helloworld_net_http_test_skip = True 55""" 56 57import pytest 58import utils 59 60PROTO_TFTP, PROTO_HTTP = range(0, 2) 61 62net_set_up = False 63 64def test_efi_pre_commands(ubman): 65 """Execute any commands required to enable network hardware. 66 67 These commands are provided by the boardenv_* file; see the comment at the 68 beginning of this file. 69 """ 70 71 init_usb = ubman.config.env.get('env__net_uses_usb', False) 72 if init_usb: 73 ubman.run_command('usb start') 74 75 init_pci = ubman.config.env.get('env__net_uses_pci', False) 76 if init_pci: 77 ubman.run_command('pci enum') 78 79@pytest.mark.buildconfigspec('cmd_dhcp') 80def test_efi_setup_dhcp(ubman): 81 """Set up the network using DHCP. 82 83 The boardenv_* file may be used to enable/disable this test; see the 84 comment at the beginning of this file. 85 """ 86 87 test_dhcp = ubman.config.env.get('env__net_dhcp_server', False) 88 if not test_dhcp: 89 env_vars = ubman.config.env.get('env__net_static_env_vars', None) 90 if not env_vars: 91 pytest.skip('No DHCP server available') 92 return 93 94 ubman.run_command('setenv autoload no') 95 output = ubman.run_command('dhcp') 96 assert 'DHCP client bound to address ' in output 97 98 global net_set_up 99 net_set_up = True 100 101@pytest.mark.buildconfigspec('net', 'net_lwip') 102def test_efi_setup_static(ubman): 103 """Set up the network using a static IP configuration. 104 105 The configuration is provided by the boardenv_* file; see the comment at 106 the beginning of this file. 107 """ 108 109 env_vars = ubman.config.env.get('env__net_static_env_vars', None) 110 if not env_vars: 111 test_dhcp = ubman.config.env.get('env__net_dhcp_server', False) 112 if not test_dhcp: 113 pytest.skip('No static network configuration is defined') 114 return None 115 116 for (var, val) in env_vars: 117 ubman.run_command('setenv %s %s' % (var, val)) 118 119 global net_set_up 120 net_set_up = True 121 122def fetch_file(ubman, env_conf, proto): 123 """Grab an env described file via TFTP or HTTP and return its address 124 125 A file as described by an env config <env_conf> is downloaded from the 126 server. The address to that file is returned. 127 """ 128 if not net_set_up: 129 pytest.skip('Network not initialized') 130 131 f = ubman.config.env.get(env_conf, None) 132 if not f: 133 pytest.skip('No %s binary specified in environment' % env_conf) 134 135 addr = f.get('addr', None) 136 if not addr: 137 addr = utils.find_ram_base(ubman) 138 139 fn = f['fn'] 140 if proto == PROTO_TFTP: 141 cmd = 'tftpboot' 142 elif proto == PROTO_HTTP: 143 cmd = 'wget' 144 else: 145 assert False 146 output = ubman.run_command('%s %x %s' % (cmd, addr, fn)) 147 expected_text = 'Bytes transferred = ' 148 sz = f.get('size', None) 149 if sz: 150 expected_text += '%d' % sz 151 assert expected_text in output 152 153 expected_crc = f.get('crc32', None) 154 if not expected_crc: 155 return addr 156 157 if ubman.config.buildconfig.get('config_cmd_crc32', 'n') != 'y': 158 return addr 159 160 output = ubman.run_command('crc32 %x $filesize' % addr) 161 assert expected_crc in output 162 163 return addr 164 165def do_test_efi_helloworld_net(ubman, proto): 166 """Download and execute the helloworld appliation 167 168 The helloworld.efi file is downloaded based on the value passed to us as a 169 protocol and is executed using the fallback device tree at $fdtcontroladdr. 170 """ 171 addr = fetch_file(ubman, 'env__efi_loader_helloworld_file', proto) 172 173 output = ubman.run_command('bootefi %x' % addr) 174 expected_text = 'Hello, world' 175 assert expected_text in output 176 expected_text = '## Application failed' 177 assert expected_text not in output 178 179@pytest.mark.buildconfigspec('of_control') 180@pytest.mark.buildconfigspec('bootefi_hello_compile') 181@pytest.mark.buildconfigspec('cmd_tftpboot') 182def test_efi_helloworld_net_tftp(ubman): 183 """Run the helloworld.efi binary via TFTP. 184 185 Call the do_test_efi_helloworld_net function to execute the test via TFTP. 186 """ 187 188 do_test_efi_helloworld_net(ubman, PROTO_TFTP); 189 190@pytest.mark.buildconfigspec('of_control') 191@pytest.mark.buildconfigspec('bootefi_hello_compile') 192@pytest.mark.buildconfigspec('cmd_wget') 193def test_efi_helloworld_net_http(ubman): 194 """Run the helloworld.efi binary via HTTP. 195 196 Call the do_test_efi_helloworld_net function to execute the test via HTTP. 197 """ 198 if ubman.config.env.get('env__efi_helloworld_net_http_test_skip', True): 199 pytest.skip('helloworld.efi HTTP test is not enabled!') 200 201 do_test_efi_helloworld_net(ubman, PROTO_HTTP); 202 203@pytest.mark.buildconfigspec('cmd_bootefi_hello') 204def test_efi_helloworld_builtin(ubman): 205 """Run the builtin helloworld.efi binary. 206 207 The helloworld.efi file is included in U-Boot, execute it using the 208 special "bootefi hello" command. 209 """ 210 211 output = ubman.run_command('bootefi hello') 212 expected_text = 'Hello, world' 213 assert expected_text in output 214 215@pytest.mark.buildconfigspec('of_control') 216@pytest.mark.buildconfigspec('cmd_bootefi') 217@pytest.mark.buildconfigspec('cmd_tftpboot') 218def test_efi_grub_net(ubman): 219 """Run the grub.efi binary via TFTP. 220 221 The grub.efi file is downloaded from the TFTP server and gets 222 executed. 223 """ 224 225 addr = fetch_file(ubman, 'env__efi_loader_grub_file', PROTO_TFTP) 226 227 ubman.run_command('bootefi %x' % addr, wait_for_prompt=False) 228 229 # Verify that we have an SMBIOS table 230 check_smbios = ubman.config.env.get('env__efi_loader_check_smbios', False) 231 if check_smbios: 232 ubman.wait_for('grub>') 233 ubman.run_command('lsefisystab', wait_for_prompt=False, wait_for_echo=False) 234 ubman.wait_for('SMBIOS') 235 236 # Then exit cleanly 237 ubman.wait_for('grub>') 238 ubman.run_command('exit', wait_for_prompt=False, wait_for_echo=False) 239 ubman.wait_for(ubman.prompt) 240 # And give us our U-Boot prompt back 241 ubman.run_command('') 242