SPDX: Convert all of our single license tags to Linux Kernel style
[platform/kernel/u-boot.git] / test / py / tests / test_efi_loader.py
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 import pytest
10 import u_boot_utils
11
12 """
13 Note: This test relies on boardenv_* containing configuration values to define
14 which network environment is available for testing. Without this, the parts
15 that rely on network will be automatically skipped.
16
17 For 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.
22 env__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.
27 env__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.
32 env__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.
37 env__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.
45 env__efi_loader_helloworld_file = {
46     "fn": "lib/efi_loader/helloworld.efi",
47     "size": 5058624,
48     "crc32": "c2244b26",
49 }
50 """
51
52 net_set_up = False
53
54 def 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')
70 def 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')
89 def 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
106 def 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) + (1024 * 1024 * 4)
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')
144 def 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')
160 def 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')
172 def 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('')