Files
2026-04-24 12:40:01 +02:00

365 lines
16 KiB
Plaintext

*** Settings ***
Resource ../keywords.robot
Resource custom_bootentries.robot
*** Keywords ***
Flash Via Internal Programmer With Args
[Documentation] Execute flashrom write operation on the given binary,
... using extra arguments.
[Arguments] ${fw_file_path} ${args} ${timeout}=5m
IF '${OPTIONS_LIB}' == 'options-lib_dcu'
# Then the platform configuration depends on the bootorder to stay the same.
# We must copy the current smmstore to the target binary in order to prevent
# it being overwritten.
VAR ${smm_file}= /tmp/smmstore.rom
VAR ${replaced_bootorder_file}= replaced_bootorder_coreboot.rom
${custom_bootname}= Get Custom Bootentry Name ${DEFAULT_BOOT_OS_ID}
@{custom_bootid}= Get Bootnums For Label ${custom_bootname}
Should Not Be Empty
... ${custom_bootid}
... Basic Platform Setup was not run, Custom DEFAULT_BOOT bootentry does not exist.
Execute Command In Terminal flashrom -p internal -r ${smm_file} --fmap -i FMAP -i SMMSTORE
END
# Always flash FD first in case the layout changes
${out_flash}= Execute Command In Terminal
... flashrom -p internal -c "${INTERNAL_PROGRAMMER_CHIPNAME}" -w ${fw_file_path} --ifd -i fd
... timeout=${timeout}
${out_flash}= Execute Command In Terminal
... flashrom -p internal -c "${INTERNAL_PROGRAMMER_CHIPNAME}" -w ${fw_file_path} ${args}
... timeout=${timeout}
IF "Warning: Chip content is identical to the requested image." in """${out_flash}"""
RETURN
END
Should Contain ${out_flash} VERIFIED
IF '${OPTIONS_LIB}' == 'options-lib_dcu'
# Then restore smmstore (UEFI variables)
${out_flash}= Execute Command In Terminal
... flashrom -p internal -c "${INTERNAL_PROGRAMMER_CHIPNAME}" -w ${smm_file} --fmap -i FMAP -i SMMSTORE
... timeout=${timeout}
END
Flash Via Internal Programmer
[Arguments] ${fw_file_path} @{regions}
${out_flashrom_probe}= Execute Command In Terminal flashrom -p internal
${read_only}= Run Keyword And Return Status
... Should Contain ${out_flashrom_probe} read-only
${filename}= Evaluate os.path.basename(r"${fw_file_path}")
Send File To DUT ${fw_file_path} /tmp/${filename}
# TODO: automatically check and seck locs - reuse keywords from this suite, but it does not exist it seems
IF ${read_only}
Fail Make sure that SPI locks are disabled prior flashing internally
END
# If no region is given, flash the whole binary
IF @{regions}
VAR ${args}= -N --ifd
FOR ${region} IN @{regions}
VAR ${args}= ${args} -i ${region}
END
ELSE
VAR ${args}= ${EMPTY}
END
Wait Until Keyword Succeeds 2x
... 1s
... Flash Via Internal Programmer With Args /tmp/${filename} ${args}
Check If RW SECTION B Is Present In A Firmware File
[Documentation] Parses ROM with cbfstool to check if A or A + B sections are there
[Arguments] ${fw_file_path}
${layout}= Execute Command In Terminal cbfstool ${fw_file_path} layout -w
${section_b_present}= Run Keyword And Return Status
... Should Contain ${layout} RW_SECTION_B
Should Contain ${layout} RW_SECTION_A msg=RW_SECTION_A is not present. Is the firmware image correct?
RETURN ${section_b_present}
Flash RW Sections Via Internal Programmer
[Documentation] Flash RW_SECTION_A and RW_SECTION_B (if possible) region
... of flash using internal programmer. Requires that vboot-enabled
... firmware is already flashed.
[Arguments] ${fw_file_path}
${section_b_present}= Check If RW SECTION B Is Present In A Firmware File ${fw_file_path}
IF ${section_b_present}
Flash Via Internal Programmer With Args ${fw_file_path} -N --fmap -i RW_SECTION_A -i RW_SECTION_B
ELSE
Flash Via Internal Programmer With Args ${fw_file_path} -N --fmap -i RW_SECTION_A
END
# TODO: below keywords are simply copied from keywords.robot. They might require some
# more cleanup/reduction.
Flash Firmware
[Documentation] Flash platform with firmware file specified in the
... argument. Keyword fails if file size doesn't match target
... chip size.
[Arguments] ${fw_file}
IF '${FLASHING_METHOD}'=='none' RETURN
${file_size}= Run ls -l ${fw_file} | awk '{print $5}'
IF '''${file_size}''' != '''${FLASH_SIZE}'''
FAIL Image size doesn't match the flash chip's size!
END
IF '${FLASHING_METHOD}' == 'external'
Rte Flash Write ${fw_file}
ELSE IF '${FLASHING_METHOD}' == 'internal'
Make Sure That Flash Locks Are Disabled
Power On
Boot System Or From Connected Disk ${BOOTED_OS_ID}
Login To Linux
Switch To Root User
VAR @{regions}= bios
IF ${INTEL_CBNT_BOOTGUARD_FUSING_SUPPORT}
VAR @{regions}= @{regions} me
END
Flash Via Internal Programmer ${fw_file} @{regions}
END
IF '''${POWER_CTRL}''' == '''none'''
Power On
Boot System Or From Connected Disk ${BOOTED_OS_ID}
Login To Linux
Switch To Root User
Execute Reboot Command
Sleep 30s Additional sleep for RAM training etc. after flashing
END
# First boot after flashing may take longer than usual
Set DUT Response Timeout 300s
Replace Logo In Firmware
[Documentation] Swap to custom logo in firmware on DUT using cbfstool according
... to: https://docs.dasharo.com/guides/logo-customization
[Arguments] ${logo_file}
Execute Command In Terminal flashrom -p internal -r /tmp/firmware.rom
# Remove the existing logo from the firmware image
${out}= Execute Command In Terminal cbfstool /tmp/firmware.rom remove -r BOOTSPLASH -n logo.bmp
# Add your desired bootlogo to the firmware image
${out}= Execute Command In Terminal
... cbfstool /tmp/firmware.rom add -f ${logo_file} -r BOOTSPLASH -n logo.bmp -t raw -c lzma
Should Not Contain ${out} Image is missing 'BOOTSPLASH' region
Write BOOTSPLASH Region Internally /tmp/firmware.rom
Read FMAP And BOOTSPLASH Regions Internally
[Documentation] Read BOOTSPLASH firmware on DUT using flashrom.
[Arguments] ${fw_file}
${out}= Execute Linux Command flashrom -p internal --fmap -i FMAP -i BOOTSPLASH -r ${fw_file} 180
Should Contain ${out} Reading flash... done
Write BOOTSPLASH Region Internally
[Documentation] Flash BOOTSPLASH firmware region on DUT using flashrom.
[Arguments] ${fw_file}
${out}= Execute Linux Command flashrom -p internal --fmap -i BOOTSPLASH -N -w ${fw_file} 180
Should Contain Any ${out} VERIFIED Chip content is identical to the requested image
Check Write Protection Availability
[Documentation] Check whether it is possible to set Write Protection
... on the DUT.
${out}= Execute Linux Command ./flashrom -p internal --wp-list
Should Not Contain ${out} write protect support is not implemented for this flash chip
Should Contain ${out} Available write protection ranges:
Should Contain ${out} all
Erase Write Protection
[Documentation] Erase write protection from the flash chip.
${out}= Execute Linux Command ./flashrom -p internal --wp-disable 180
Should Contain ${out} Successfully set the requested mode
${out}= Execute Linux Command ./flashrom -p internal --wp-range=0,0 180
Should Contain ${out} Successfully set the requested protection range
Set Write Protection
[Documentation] Set protection range as defined by the parameters:
... `${start_adress}` - protection start address,
... `${length}` - flash protected range length.
[Arguments] ${start_adress} ${length}
${out}= Execute Linux Command ./flashrom -p internal --wp-range=${start_adress},${length} 180
Should Contain ${out} Successfully set the requested protection range
${out}= Execute Linux Command ./flashrom -p internal --wp-enable 180
Should Contain ${out} Successfully set the requested mode
Check Write Protection Status
[Documentation] Check whether Write Protection mechanism is active.
${out}= Execute Linux Command ./flashrom -p internal --wp-status 180
Should Contain ${out} Protection mode: hardware
Compare Write Protection Ranges
[Documentation] Allows to compare Protection Range: declared and
... currently set.
[Arguments] ${start_adress} ${length}
${out}= Execute Linux Command ./flashrom -p internal --wp-status 180
${protection_range}= Get Lines Containing String ${out} Protection range:
${protection_range}= Split String ${protection_range}
${set_start_adress}= Get From List ${protection_range} 2
${set_start_adress}= Fetch From Right ${set_start_adress} =
${set_length}= Get From List ${protection_range} 3
${set_length}= Fetch From Right ${set_length} =
IF ${set_start_adress}!=${start_adress}
FAIL Declared and currently set protection start addresses are not the same
END
IF ${set_length}!=${length}
FAIL Declared and currently set protection lengths are not the same
END
Read Firmware
[Documentation] Read platform firmware to file specified in the argument.
[Arguments] ${file}
IF '${FLASHING_METHOD}' == 'external'
IF '${APU_FLASH_WP_GPIO}' != '${TBD}'
Rte Gpio Set ${APU_FLASH_WP_GPIO} low
END
Rte Flash Read ${file}
IF '${APU_FLASH_WP_GPIO}' != '${TBD}'
Rte Gpio Set ${APU_FLASH_WP_GPIO} high-z
END
ELSE IF '${FLASHING_METHOD}' == 'internal'
# TODO
Power On
Boot System Or From Connected Disk ${DEFAULT_BOOT_OS_ID}
Login To Linux
Switch To Root User
Execute Command In Terminal flashrom -p internal --ifd -i fd -i bios -i me -r coreboot.rom
Get File From DUT coreboot.rom ${file}
ELSE
Fail Read firmware not implemented for platform config ${CONFIG}
END
Get Flashrom FMAP Regions
${output}= Execute Command In Terminal flashrom -p internal -r coreboot.rom timeout=300s
${output}= Execute Command In Terminal cbfstool coreboot.rom layout -w
${lines}= Split To Lines ${output}
VAR &{dict}= &{EMPTY}
FOR ${l} IN @{lines}
${m}= Get Regexp Matches
... ${l}
... ^'([A-Z_]+)' \\(([a-zA-Z_\-]+, )?size ([0-9]+), offset ([0-9]+)\\)$
... 1
... 2
... 3
... 4
IF ${m} != []
VAR ${name}= ${m}[0][0]
VAR ${type}= ${m}[0][1]
VAR ${size}= ${m}[0][2]
VAR ${offset}= ${m}[0][3]
${start}= Evaluate ${offset}
${end}= Evaluate ${start} + ${size}
VAR &{region}= start=${start} end=${end} type=${type}
Set To Dictionary ${dict} ${name}=${region}
END
END
RETURN ${dict}
Get Flashrom Regions
${output}= Execute Command In Terminal flashrom -p internal
${lines}= Split To Lines ${output}
VAR &{dict}= &{EMPTY}
FOR ${l} IN @{lines}
${m}= Get Regexp Matches
... ${l}
... FREG[0-9]+: (.+) region \\((0x[0-9a-f]+)-(0x[0-9a-f]+)\\) is (.+)
... 1
... 2
... 3
... 4
IF ${m} != []
VAR ${name}= ${m}[0][0]
VAR ${start}= ${m}[0][1]
VAR ${end}= ${m}[0][2]
VAR ${state}= ${m}[0][3]
${start}= Evaluate int(${start})
${end}= Evaluate int(${end})
VAR &{region}= start=${start} end=${end} state=${state}
Set To Dictionary ${dict} ${name}=${region}
END
END
RETURN ${dict}
Get Flashrom Readonly Offsets
${output}= Execute Command In Terminal flashrom -p internal
${lines}= Split To Lines ${output}
VAR @{list}= @{EMPTY}
FOR ${l} IN @{lines}
${m}= Get Regexp Matches ${l} Warning: (0x[0-9a-f]+)-(0x[0-9a-f]+) is read-only 1 2
IF ${m} != []
${start}= Evaluate int(${m[0][0]})
${end}= Evaluate int(${m[0][1]}) + 1 # inclusive
VAR &{region}= start=${start} end=${end}
Append To List ${list} ${region}
END
END
RETURN ${list}
Calculate Expected Flashrom Readonly Region
[Tags] robot:private
[Arguments] ${region_name} ${start_offset} ${end_offset}
${flashrom_regions}= Get Flashrom Regions
${bios_start}= Get From Dictionary ${flashrom_regions['${region_name}']} start
${bios_end}= Get From Dictionary ${flashrom_regions['${region_name}']} end
${expected_readonly_start}= Evaluate ${bios_start} + ${COREBOOT_REDUNDANT_BOOT_BOOTBLOCK_OFFSET.start}
${expected_readonly_end}= Evaluate ${bios_start} + ${COREBOOT_REDUNDANT_BOOT_BOOTBLOCK_OFFSET.end}
VAR &{expected_readonly}= start=${expected_readonly_start} end=${expected_readonly_end}
RETURN ${expected_readonly}
Verify Region Range Protected
[Arguments] ${region_name} ${expected_start} ${expected_end}
${readonly_regions}= Get Flashrom Readonly Offsets
IF len(${readonly_regions}) == 0
Fail No readonly regions found in flashrom output
END
${expected_readonly_bootblock}= Calculate Expected Flashrom Readonly Region
... region_name=${region_name}
... start_offset=${expected_start}
... end_offset=${expected_end}
VAR ${expected_readonly_found}= ${FALSE}
FOR ${region} IN @{readonly_regions}
Log To Console Found readonly region: ${region}
Log To Console Expected readonly region: ${expected_readonly_bootblock}
${start_matches}= Evaluate ${region['start']} == ${expected_readonly_bootblock['start']}
${end_matches}= Evaluate ${region['end']} == ${expected_readonly_bootblock['end']}
IF ${start_matches} and ${end_matches}
VAR ${expected_readonly_found}= ${TRUE}
BREAK
END
END
IF not ${expected_readonly_found}
Fail Expected readonly region ${expected_readonly_bootblock} not found in flashrom output
END
Flashrom Verify FMAP Regions Protected
[Arguments] @{region_names}
${fmap_regions}= Get Flashrom FMAP Regions
${protected_offsets}= Get Flashrom Readonly Offsets
VAR @{failed_regions}= @{EMPTY}
FOR ${region_name} IN @{region_names}
${region}= Get From Dictionary ${fmap_regions} ${region_name} default=${None}
IF $region is ${None}
Fail Region ${region_name} does not exist in the FMAP
END
VAR ${protected}= ${FALSE}
FOR ${offsets} IN @{protected_offsets}
IF ${offsets.start} <= ${region.start} and ${offsets.end} >= ${region.end}
VAR ${protected}= ${TRUE}
BREAK
END
END
IF not ${protected}
Set To Dictionary ${region} name=${region_name}
Append To List ${failed_regions} ${region}
END
END
IF len($failed_regions) > 0
FOR ${region} IN @{failed_regions}
Log To Console Region ${region.name}(${region.start}-${region.end}) is not protected!
END
Log To Console Protected ranges: ${protected_offsets}
Fail Not every region is protected.
END