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 6This test verifies capsule-on-disk firmware update for raw images 7""" 8 9import pytest 10from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR 11 12@pytest.mark.boardspec('sandbox') 13@pytest.mark.buildconfigspec('efi_capsule_firmware_raw') 14@pytest.mark.buildconfigspec('efi_capsule_on_disk') 15@pytest.mark.buildconfigspec('dfu') 16@pytest.mark.buildconfigspec('dfu_sf') 17@pytest.mark.buildconfigspec('cmd_efidebug') 18@pytest.mark.buildconfigspec('cmd_fat') 19@pytest.mark.buildconfigspec('cmd_memory') 20@pytest.mark.buildconfigspec('cmd_nvedit_efi') 21@pytest.mark.buildconfigspec('cmd_sf') 22@pytest.mark.slow 23class TestEfiCapsuleFirmwareRaw: 24 """ Tests verifying capsule-on-disk firmware update for raw images 25 """ 26 27 def test_efi_capsule_fw1( 28 self, u_boot_config, u_boot_console, efi_capsule_data): 29 """ Test Case 1 30 Update U-Boot and U-Boot environment on SPI Flash 31 but with an incorrect GUID value in the capsule 32 No update should happen 33 0x100000-0x150000: U-Boot binary (but dummy) 34 0x150000-0x200000: U-Boot environment (but dummy) 35 """ 36 37 # other tests might have run and the 38 # system might not be in a clean state. 39 # Restart before starting the tests. 40 u_boot_console.restart_uboot() 41 42 disk_img = efi_capsule_data 43 with u_boot_console.log.section('Test Case 1-a, before reboot'): 44 output = u_boot_console.run_command_list([ 45 'host bind 0 %s' % disk_img, 46 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""', 47 'efidebug boot order 1', 48 'env set -e -nv -bs -rt OsIndications =0x0000000000000004', 49 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', 50 'env save']) 51 52 # initialize contents 53 output = u_boot_console.run_command_list([ 54 'sf probe 0:0', 55 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR, 56 'sf write 4000000 100000 10', 57 'sf read 5000000 100000 10', 58 'md.b 5000000 10']) 59 assert 'Old' in ''.join(output) 60 output = u_boot_console.run_command_list([ 61 'sf probe 0:0', 62 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR, 63 'sf write 4000000 150000 10', 64 'sf read 5000000 150000 10', 65 'md.b 5000000 10']) 66 assert 'Old' in ''.join(output) 67 68 # place a capsule file 69 output = u_boot_console.run_command_list([ 70 'fatload host 0:1 4000000 %s/Test03' % CAPSULE_DATA_DIR, 71 'fatwrite host 0:1 4000000 %s/Test03 $filesize' % CAPSULE_INSTALL_DIR, 72 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 73 assert 'Test03' in ''.join(output) 74 75 # reboot 76 u_boot_console.restart_uboot() 77 78 capsule_early = u_boot_config.buildconfig.get( 79 'config_efi_capsule_on_disk_early') 80 81 with u_boot_console.log.section('Test Case 1-b, after reboot'): 82 if not capsule_early: 83 # make sure that dfu_alt_info exists even persistent variables 84 # are not available. 85 output = u_boot_console.run_command_list([ 86 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', 87 'host bind 0 %s' % disk_img, 88 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 89 assert 'Test03' in ''.join(output) 90 91 # need to run uefi command to initiate capsule handling 92 output = u_boot_console.run_command( 93 'env print -e Capsule0000', wait_for_reboot = True) 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 """ Test Case 2 109 Update U-Boot and U-Boot environment on SPI Flash but with OsIndications unset 110 No update should happen 111 0x100000-0x150000: U-Boot binary (but dummy) 112 0x150000-0x200000: U-Boot environment (but dummy) 113 """ 114 disk_img = efi_capsule_data 115 with u_boot_console.log.section('Test Case 2-a, before reboot'): 116 output = u_boot_console.run_command_list([ 117 'host bind 0 %s' % disk_img, 118 'printenv -e PlatformLangCodes', # workaround for terminal size determination 119 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""', 120 'efidebug boot order 1', 121 'env set -e OsIndications', 122 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', 123 'env save']) 124 125 # initialize contents 126 output = u_boot_console.run_command_list([ 127 'sf probe 0:0', 128 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR, 129 'sf write 4000000 100000 10', 130 'sf read 5000000 100000 10', 131 'md.b 5000000 10']) 132 assert 'Old' in ''.join(output) 133 output = u_boot_console.run_command_list([ 134 'sf probe 0:0', 135 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR, 136 'sf write 4000000 150000 10', 137 'sf read 5000000 150000 10', 138 'md.b 5000000 10']) 139 assert 'Old' in ''.join(output) 140 141 # place the capsule files 142 output = u_boot_console.run_command_list([ 143 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR, 144 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR, 145 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 146 assert 'Test01' in ''.join(output) 147 148 output = u_boot_console.run_command_list([ 149 'fatload host 0:1 4000000 %s/Test02' % CAPSULE_DATA_DIR, 150 'fatwrite host 0:1 4000000 %s/Test02 $filesize' % CAPSULE_INSTALL_DIR, 151 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 152 assert 'Test02' in ''.join(output) 153 154 # reboot 155 u_boot_console.restart_uboot() 156 157 capsule_early = u_boot_config.buildconfig.get( 158 'config_efi_capsule_on_disk_early') 159 with u_boot_console.log.section('Test Case 2-b, after reboot'): 160 if not capsule_early: 161 # make sure that dfu_alt_info exists even persistent variables 162 # are not available. 163 output = u_boot_console.run_command_list([ 164 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', 165 'host bind 0 %s' % disk_img, 166 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 167 assert 'Test01' in ''.join(output) 168 assert 'Test02' in ''.join(output) 169 170 # need to run uefi command to initiate capsule handling 171 output = u_boot_console.run_command( 172 'env print -e Capsule0000') 173 174 output = u_boot_console.run_command_list([ 175 'host bind 0 %s' % disk_img, 176 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 177 assert 'Test01' in ''.join(output) 178 assert 'Test02' in ''.join(output) 179 180 output = u_boot_console.run_command_list([ 181 'sf probe 0:0', 182 'sf read 4000000 100000 10', 183 'md.b 4000000 10']) 184 assert 'u-boot:Old' in ''.join(output) 185 186 output = u_boot_console.run_command_list([ 187 'sf read 4000000 150000 10', 188 'md.b 4000000 10']) 189 assert 'u-boot-env:Old' in ''.join(output) 190 191 def test_efi_capsule_fw3( 192 self, u_boot_config, u_boot_console, efi_capsule_data): 193 """ Test Case 3 194 Update U-Boot on SPI Flash, raw image format 195 0x100000-0x150000: U-Boot binary (but dummy) 196 """ 197 disk_img = efi_capsule_data 198 with u_boot_console.log.section('Test Case 3-a, before reboot'): 199 output = u_boot_console.run_command_list([ 200 'host bind 0 %s' % disk_img, 201 'printenv -e PlatformLangCodes', # workaround for terminal size determination 202 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""', 203 'efidebug boot order 1', 204 'env set -e -nv -bs -rt OsIndications =0x0000000000000004', 205 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', 206 'env save']) 207 208 # initialize contents 209 output = u_boot_console.run_command_list([ 210 'sf probe 0:0', 211 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR, 212 'sf write 4000000 100000 10', 213 'sf read 5000000 100000 10', 214 'md.b 5000000 10']) 215 assert 'Old' in ''.join(output) 216 217 output = u_boot_console.run_command_list([ 218 'sf probe 0:0', 219 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR, 220 'sf write 4000000 150000 10', 221 'sf read 5000000 100000 10', 222 'md.b 5000000 10']) 223 assert 'Old' in ''.join(output) 224 225 # place the capsule files 226 output = u_boot_console.run_command_list([ 227 'fatload host 0:1 4000000 %s/Test01' % CAPSULE_DATA_DIR, 228 'fatwrite host 0:1 4000000 %s/Test01 $filesize' % CAPSULE_INSTALL_DIR, 229 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 230 assert 'Test01' in ''.join(output) 231 232 output = u_boot_console.run_command_list([ 233 'fatload host 0:1 4000000 %s/Test02' % CAPSULE_DATA_DIR, 234 'fatwrite host 0:1 4000000 %s/Test02 $filesize' % CAPSULE_INSTALL_DIR, 235 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 236 assert 'Test02' in ''.join(output) 237 238 capsule_early = u_boot_config.buildconfig.get( 239 'config_efi_capsule_on_disk_early') 240 capsule_auth = u_boot_config.buildconfig.get( 241 'config_efi_capsule_authenticate') 242 243 # reboot 244 u_boot_console.restart_uboot(expect_reset = capsule_early) 245 246 with u_boot_console.log.section('Test Case 3-b, after reboot'): 247 if not capsule_early: 248 # make sure that dfu_alt_info exists even persistent variables 249 # are not available. 250 output = u_boot_console.run_command_list([ 251 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', 252 'host bind 0 %s' % disk_img, 253 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 254 assert 'Test01' in ''.join(output) 255 assert 'Test02' in ''.join(output) 256 257 # need to run uefi command to initiate capsule handling 258 output = u_boot_console.run_command( 259 'env print -e Capsule0000', wait_for_reboot = True) 260 261 # make sure the dfu_alt_info exists because it is required for making ESRT. 262 output = u_boot_console.run_command_list([ 263 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', 264 'efidebug capsule esrt']) 265 266 # ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT. 267 assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output) 268 269 # ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT. 270 assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output) 271 272 output = u_boot_console.run_command_list([ 273 'host bind 0 %s' % disk_img, 274 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) 275 assert 'Test01' not in ''.join(output) 276 assert 'Test02' not in ''.join(output) 277 278 output = u_boot_console.run_command_list([ 279 'sf probe 0:0', 280 'sf read 4000000 100000 10', 281 'md.b 4000000 10']) 282 if capsule_auth: 283 assert 'u-boot:Old' in ''.join(output) 284 else: 285 assert 'u-boot:New' in ''.join(output) 286 287 output = u_boot_console.run_command_list([ 288 'sf probe 0:0', 289 'sf read 4000000 150000 10', 290 'md.b 4000000 10']) 291 if capsule_auth: 292 assert 'u-boot-env:Old' in ''.join(output) 293 else: 294 assert 'u-boot-env:New' in ''.join(output) 295