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