Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-net
[platform/kernel/u-boot.git] / test / py / tests / test_efi_capsule / test_capsule_firmware.py
1 # SPDX-License-Identifier:      GPL-2.0+
2 # Copyright (c) 2020, Linaro Limited
3 # Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
4 #
5 # U-Boot UEFI: Firmware Update Test
6
7 """
8 This test verifies capsule-on-disk firmware update
9 """
10
11 from subprocess import check_call, check_output, CalledProcessError
12 import pytest
13 from capsule_defs import *
14
15
16 @pytest.mark.boardspec('sandbox')
17 @pytest.mark.buildconfigspec('efi_capsule_firmware_fit')
18 @pytest.mark.buildconfigspec('efi_capsule_firmware_raw')
19 @pytest.mark.buildconfigspec('efi_capsule_on_disk')
20 @pytest.mark.buildconfigspec('dfu')
21 @pytest.mark.buildconfigspec('dfu_sf')
22 @pytest.mark.buildconfigspec('cmd_efidebug')
23 @pytest.mark.buildconfigspec('cmd_fat')
24 @pytest.mark.buildconfigspec('cmd_memory')
25 @pytest.mark.buildconfigspec('cmd_nvedit_efi')
26 @pytest.mark.buildconfigspec('cmd_sf')
27 @pytest.mark.slow
28 class TestEfiCapsuleFirmwareFit(object):
29     def test_efi_capsule_fw1(
30             self, u_boot_config, u_boot_console, efi_capsule_data):
31         """
32         Test Case 1 - Update U-Boot and U-Boot environment on SPI Flash
33                       but with OsIndications unset
34                       No update should happen
35                       0x100000-0x150000: U-Boot binary (but dummy)
36                       0x150000-0x200000: U-Boot environment (but dummy)
37         """
38         disk_img = efi_capsule_data
39         with u_boot_console.log.section('Test Case 1-a, before reboot'):
40             output = u_boot_console.run_command_list([
41                 'host bind 0 %s' % disk_img,
42                 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
43                 'efidebug boot order 1',
44                 'env set -e OsIndications',
45                 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
46                 'env save'])
47
48             # initialize contents
49             output = u_boot_console.run_command_list([
50                 'sf probe 0:0',
51                 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
52                 'sf write 4000000 100000 10',
53                 'sf read 5000000 100000 10',
54                 'md.b 5000000 10'])
55             assert 'Old' in ''.join(output)
56             output = u_boot_console.run_command_list([
57                 'sf probe 0:0',
58                 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR,
59                 'sf write 4000000 150000 10',
60                 'sf read 5000000 150000 10',
61                 'md.b 5000000 10'])
62             assert 'Old' in ''.join(output)
63
64             # place a capsule file
65             output = u_boot_console.run_command_list([
66                 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR,
67                 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR,
68                 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
69             assert 'Test01' in ''.join(output)
70
71         # reboot
72         u_boot_console.restart_uboot()
73
74         capsule_early = u_boot_config.buildconfig.get(
75             'config_efi_capsule_on_disk_early')
76         with u_boot_console.log.section('Test Case 1-b, after reboot'):
77             if not capsule_early:
78                 # make sure that dfu_alt_info exists even persistent variables
79                 # are not available.
80                 output = u_boot_console.run_command_list([
81                     'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
82                     'host bind 0 %s' % disk_img,
83                     'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
84                 assert 'Test01' in ''.join(output)
85
86                 # need to run uefi command to initiate capsule handling
87                 output = u_boot_console.run_command(
88                     'env print -e Capsule0000')
89
90             output = u_boot_console.run_command_list([
91                 'host bind 0 %s' % disk_img,
92                 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
93             assert 'Test01' in ''.join(output)
94
95             output = u_boot_console.run_command_list([
96                 'sf probe 0:0',
97                 'sf read 4000000 100000 10',
98                 'md.b 4000000 10'])
99             assert 'u-boot:Old' in ''.join(output)
100
101             output = u_boot_console.run_command_list([
102                 'sf read 4000000 150000 10',
103                 'md.b 4000000 10'])
104             assert 'u-boot-env:Old' in ''.join(output)
105
106     def test_efi_capsule_fw2(
107             self, u_boot_config, u_boot_console, efi_capsule_data):
108         """
109         Test Case 2 - Update U-Boot and U-Boot environment on SPI Flash
110                       0x100000-0x150000: U-Boot binary (but dummy)
111                       0x150000-0x200000: U-Boot environment (but dummy)
112         """
113         disk_img = efi_capsule_data
114         with u_boot_console.log.section('Test Case 2-a, before reboot'):
115             output = u_boot_console.run_command_list([
116                 'host bind 0 %s' % disk_img,
117                 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
118                 'efidebug boot order 1',
119                 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
120                 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
121                 'env save'])
122
123             # initialize contents
124             output = u_boot_console.run_command_list([
125                 'sf probe 0:0',
126                 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
127                 'sf write 4000000 100000 10',
128                 'sf read 5000000 100000 10',
129                 'md.b 5000000 10'])
130             assert 'Old' in ''.join(output)
131             output = u_boot_console.run_command_list([
132                 'sf probe 0:0',
133                 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR,
134                 'sf write 4000000 150000 10',
135                 'sf read 5000000 150000 10',
136                 'md.b 5000000 10'])
137             assert 'Old' in ''.join(output)
138
139             # place a capsule file
140             output = u_boot_console.run_command_list([
141                 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR,
142                 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR,
143                 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
144             assert 'Test01' in ''.join(output)
145
146         capsule_early = u_boot_config.buildconfig.get(
147             'config_efi_capsule_on_disk_early')
148         capsule_auth = u_boot_config.buildconfig.get(
149             'config_efi_capsule_authenticate')
150
151         # reboot
152         u_boot_console.restart_uboot(expect_reset = capsule_early)
153
154         with u_boot_console.log.section('Test Case 2-b, after reboot'):
155             if not capsule_early:
156                 # make sure that dfu_alt_info exists even persistent variables
157                 # are not available.
158                 output = u_boot_console.run_command_list([
159                     'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
160                     'host bind 0 %s' % disk_img,
161                     'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
162                 assert 'Test01' in ''.join(output)
163
164                 # need to run uefi command to initiate capsule handling
165                 output = u_boot_console.run_command(
166                     'env print -e Capsule0000', wait_for_reboot = True)
167
168             output = u_boot_console.run_command_list([
169                 'host bind 0 %s' % disk_img,
170                 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
171             assert 'Test01' not in ''.join(output)
172
173             output = u_boot_console.run_command_list([
174                 'sf probe 0:0',
175                 'sf read 4000000 100000 10',
176                 'md.b 4000000 10'])
177             if capsule_auth:
178                 assert 'u-boot:Old' in ''.join(output)
179             else:
180                 assert 'u-boot:New' in ''.join(output)
181
182             output = u_boot_console.run_command_list([
183                 'sf read 4000000 150000 10',
184                 'md.b 4000000 10'])
185             if capsule_auth:
186                 assert 'u-boot-env:Old' in ''.join(output)
187             else:
188                 assert 'u-boot-env:New' in ''.join(output)
189
190     def test_efi_capsule_fw3(
191             self, u_boot_config, u_boot_console, efi_capsule_data):
192         """
193         Test Case 3 - Update U-Boot on SPI Flash, raw image format
194                       0x100000-0x150000: U-Boot binary (but dummy)
195         """
196         disk_img = efi_capsule_data
197         with u_boot_console.log.section('Test Case 3-a, before reboot'):
198             output = u_boot_console.run_command_list([
199                 'host bind 0 %s' % disk_img,
200                 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
201                 'efidebug boot order 1',
202                 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
203                 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
204                 'env save'])
205
206             # initialize content
207             output = u_boot_console.run_command_list([
208                 'sf probe 0:0',
209                 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
210                 'sf write 4000000 100000 10',
211                 'sf read 5000000 100000 10',
212                 'md.b 5000000 10'])
213             assert 'Old' in ''.join(output)
214
215             # place a capsule file
216             output = u_boot_console.run_command_list([
217                 'fatload host 0:1 4000000 %s/Test02' % CAPSULE_DATA_DIR,
218                 'fatwrite host 0:1 4000000 %s/Test02 $filesize' % CAPSULE_INSTALL_DIR,
219                 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
220             assert 'Test02' in ''.join(output)
221
222         capsule_early = u_boot_config.buildconfig.get(
223             'config_efi_capsule_on_disk_early')
224         capsule_auth = u_boot_config.buildconfig.get(
225             'config_efi_capsule_authenticate')
226
227         # reboot
228         u_boot_console.restart_uboot(expect_reset = capsule_early)
229
230         with u_boot_console.log.section('Test Case 3-b, after reboot'):
231             if not capsule_early:
232                 # make sure that dfu_alt_info exists even persistent variables
233                 # are not available.
234                 output = u_boot_console.run_command_list([
235                     'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
236                     'host bind 0 %s' % disk_img,
237                     'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
238                 assert 'Test02' in ''.join(output)
239
240                 # need to run uefi command to initiate capsule handling
241                 output = u_boot_console.run_command(
242                     'env print -e Capsule0000', wait_for_reboot = True)
243
244             # make sure the dfu_alt_info exists because it is required for making ESRT.
245             output = u_boot_console.run_command_list([
246                 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
247                 'efidebug capsule esrt'])
248
249             # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID is in the ESRT.
250             assert 'AE13FF2D-9AD4-4E25-9AC8-6D80B3B22147' in ''.join(output)
251
252             # ensure that  EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT.
253             assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output)
254
255             output = u_boot_console.run_command_list([
256                 'host bind 0 %s' % disk_img,
257                 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
258             assert 'Test02' not in ''.join(output)
259
260             output = u_boot_console.run_command_list([
261                 'sf probe 0:0',
262                 'sf read 4000000 100000 10',
263                 'md.b 4000000 10'])
264             if capsule_auth:
265                 assert 'u-boot:Old' in ''.join(output)
266             else:
267                 assert 'u-boot:New' in ''.join(output)
268
269     def test_efi_capsule_fw4(
270             self, u_boot_config, u_boot_console, efi_capsule_data):
271         """
272         Test Case 4 - Test "--guid" option of mkeficapsule
273                       The test scenario is the same as Case 3.
274         """
275         disk_img = efi_capsule_data
276         with u_boot_console.log.section('Test Case 4-a, before reboot'):
277             output = u_boot_console.run_command_list([
278                 'host bind 0 %s' % disk_img,
279                 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""',
280                 'efidebug boot order 1',
281                 'env set -e -nv -bs -rt OsIndications =0x0000000000000004',
282                 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
283                 'env save'])
284
285             # initialize content
286             output = u_boot_console.run_command_list([
287                 'sf probe 0:0',
288                 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR,
289                 'sf write 4000000 100000 10',
290                 'sf read 5000000 100000 10',
291                 'md.b 5000000 10'])
292             assert 'Old' in ''.join(output)
293
294             # place a capsule file
295             output = u_boot_console.run_command_list([
296                 'fatload host 0:1 4000000 %s/Test03' % CAPSULE_DATA_DIR,
297                 'fatwrite host 0:1 4000000 %s/Test03 $filesize' % CAPSULE_INSTALL_DIR,
298                 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
299             assert 'Test03' in ''.join(output)
300
301         capsule_early = u_boot_config.buildconfig.get(
302             'config_efi_capsule_on_disk_early')
303         capsule_auth = u_boot_config.buildconfig.get(
304             'config_efi_capsule_authenticate')
305
306         # reboot
307         u_boot_console.restart_uboot(expect_reset = capsule_early)
308
309         with u_boot_console.log.section('Test Case 4-b, after reboot'):
310             if not capsule_early:
311                 # make sure that dfu_alt_info exists even persistent variables
312                 # are not available.
313                 output = u_boot_console.run_command_list([
314                     'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
315                     'host bind 0 %s' % disk_img,
316                     'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
317                 assert 'Test03' in ''.join(output)
318
319                 # need to run uefi command to initiate capsule handling
320                 output = u_boot_console.run_command(
321                     'env print -e Capsule0000', wait_for_reboot = True)
322
323             # make sure the dfu_alt_info exists because it is required for making ESRT.
324             output = u_boot_console.run_command_list([
325                 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
326                 'efidebug capsule esrt'])
327
328             # ensure that  EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT.
329             assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output)
330
331             output = u_boot_console.run_command_list([
332                 'host bind 0 %s' % disk_img,
333                 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
334             assert 'Test03' not in ''.join(output)
335
336             output = u_boot_console.run_command_list([
337                 'sf probe 0:0',
338                 'sf read 4000000 100000 10',
339                 'md.b 4000000 10'])
340             if capsule_auth:
341                 assert 'u-boot:Old' in ''.join(output)
342             else:
343                 assert 'u-boot:New' in ''.join(output)