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