mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
Merge branch '2024-01-29-pytest-enhancements'
- Update pygit2 version and add a number of additional hardware pytests
This commit is contained in:
commit
ce54325c42
8 changed files with 1983 additions and 2 deletions
|
@ -11,10 +11,10 @@ more-itertools==7.2.0
|
|||
packaging==23.2
|
||||
pbr==5.4.3
|
||||
pluggy==0.13.0
|
||||
py==1.10.0
|
||||
py==1.11.0
|
||||
pycryptodomex==3.19.1
|
||||
pyelftools==0.27
|
||||
pygit2==1.9.2
|
||||
pygit2==1.13.3
|
||||
pyparsing==3.0.7
|
||||
pytest==6.2.5
|
||||
pytest-xdist==2.5.0
|
||||
|
|
|
@ -85,6 +85,13 @@ env__gpio_dev_config = {
|
|||
'gpio_ip_pin_clear':'66',
|
||||
'gpio_clear_value': 'value is 0',
|
||||
'gpio_set_value': 'value is 1',
|
||||
# GPIO pin list to test gpio functionality for each pins, pin should be
|
||||
# pin names (str)
|
||||
'gpio_pin_list': ['gpio@1000031', 'gpio@1000032', 'gpio@20000033'],
|
||||
# GPIO input output list for shorted gpio pins to test gpio
|
||||
# functionality for each of pairs, where the first element is
|
||||
# configured as input and second as output
|
||||
'gpio_ip_op_list': [['gpio0', 'gpio1'], ['gpio2', 'gpio3']],
|
||||
}
|
||||
"""
|
||||
|
||||
|
@ -223,3 +230,86 @@ def test_gpio_input_generic(u_boot_console):
|
|||
response = u_boot_console.run_command(cmd)
|
||||
good_response = gpio_set_value
|
||||
assert good_response in response
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_gpio')
|
||||
def test_gpio_pins_generic(u_boot_console):
|
||||
"""Test various gpio related functionality, such as the input, set, clear,
|
||||
and toggle for the set of gpio pin list.
|
||||
|
||||
Specific set of gpio pins (by mentioning gpio pin name) configured as
|
||||
input (mentioned as 'gpio_pin_list') to be tested for multiple gpio
|
||||
commands.
|
||||
"""
|
||||
|
||||
f = u_boot_console.config.env.get('env__gpio_dev_config', False)
|
||||
if not f:
|
||||
pytest.skip('gpio not configured')
|
||||
|
||||
gpio_pins = f.get('gpio_pin_list', None)
|
||||
if not gpio_pins:
|
||||
pytest.skip('gpio pin list are not configured')
|
||||
|
||||
for gpin in gpio_pins:
|
||||
# gpio input
|
||||
u_boot_console.run_command(f'gpio input {gpin}')
|
||||
expected_response = f'{gpin}: input:'
|
||||
response = u_boot_console.run_command(f'gpio status -a {gpin}')
|
||||
assert expected_response in response
|
||||
|
||||
# gpio set
|
||||
u_boot_console.run_command(f'gpio set {gpin}')
|
||||
expected_response = f'{gpin}: output: 1'
|
||||
response = u_boot_console.run_command(f'gpio status -a {gpin}')
|
||||
assert expected_response in response
|
||||
|
||||
# gpio clear
|
||||
u_boot_console.run_command(f'gpio clear {gpin}')
|
||||
expected_response = f'{gpin}: output: 0'
|
||||
response = u_boot_console.run_command(f'gpio status -a {gpin}')
|
||||
assert expected_response in response
|
||||
|
||||
# gpio toggle
|
||||
u_boot_console.run_command(f'gpio toggle {gpin}')
|
||||
expected_response = f'{gpin}: output: 1'
|
||||
response = u_boot_console.run_command(f'gpio status -a {gpin}')
|
||||
assert expected_response in response
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_gpio')
|
||||
def test_gpio_pins_input_output_generic(u_boot_console):
|
||||
"""Test gpio related functionality such as input and output for the list of
|
||||
shorted gpio pins provided as a pair of input and output pins. This test
|
||||
will fail, if the gpio pins are not shorted properly.
|
||||
|
||||
Specific set of shorted gpio pins (by mentioning gpio pin name)
|
||||
configured as input and output (mentioned as 'gpio_ip_op_list') as a
|
||||
pair to be tested for gpio input output case.
|
||||
"""
|
||||
|
||||
f = u_boot_console.config.env.get('env__gpio_dev_config', False)
|
||||
if not f:
|
||||
pytest.skip('gpio not configured')
|
||||
|
||||
gpio_pins = f.get('gpio_ip_op_list', None)
|
||||
if not gpio_pins:
|
||||
pytest.skip('gpio pin list for input and output are not configured')
|
||||
|
||||
for gpins in gpio_pins:
|
||||
u_boot_console.run_command(f'gpio input {gpins[0]}')
|
||||
expected_response = f'{gpins[0]}: input:'
|
||||
response = u_boot_console.run_command(f'gpio status -a {gpins[0]}')
|
||||
assert expected_response in response
|
||||
|
||||
u_boot_console.run_command(f'gpio set {gpins[1]}')
|
||||
expected_response = f'{gpins[1]}: output:'
|
||||
response = u_boot_console.run_command(f'gpio status -a {gpins[1]}')
|
||||
assert expected_response in response
|
||||
|
||||
u_boot_console.run_command(f'gpio clear {gpins[1]}')
|
||||
expected_response = f'{gpins[0]}: input: 0'
|
||||
response = u_boot_console.run_command(f'gpio status -a {gpins[0]}')
|
||||
assert expected_response in response
|
||||
|
||||
u_boot_console.run_command(f'gpio set {gpins[1]}')
|
||||
expected_response = f'{gpins[0]}: input: 1'
|
||||
response = u_boot_console.run_command(f'gpio status -a {gpins[0]}')
|
||||
assert expected_response in response
|
||||
|
|
671
test/py/tests/test_mmc.py
Normal file
671
test/py/tests/test_mmc.py
Normal file
|
@ -0,0 +1,671 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# (C) Copyright 2023, Advanced Micro Devices, Inc.
|
||||
|
||||
import pytest
|
||||
import random
|
||||
import re
|
||||
import u_boot_utils
|
||||
|
||||
"""
|
||||
Note: This test doesn't rely on boardenv_* configuration values but it can
|
||||
change the test behavior. To test MMC file system cases (fat32, ext2, ext4),
|
||||
MMC device should be formatted and valid partitions should be created for
|
||||
different file system, otherwise it may leads to failure. This test will be
|
||||
skipped if the MMC device is not detected.
|
||||
|
||||
For example:
|
||||
|
||||
# Setup env__mmc_device_test_skip to not skipping the test. By default, its
|
||||
# value is set to True. Set it to False to run all tests for MMC device.
|
||||
env__mmc_device_test_skip = False
|
||||
"""
|
||||
|
||||
mmc_set_up = False
|
||||
controllers = 0
|
||||
devices = {}
|
||||
|
||||
def setup_mmc(u_boot_console):
|
||||
if u_boot_console.config.env.get('env__mmc_device_test_skip', True):
|
||||
pytest.skip('MMC device test is not enabled')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
def test_mmc_list(u_boot_console):
|
||||
setup_mmc(u_boot_console)
|
||||
output = u_boot_console.run_command('mmc list')
|
||||
if 'No MMC device available' in output:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if 'Card did not respond to voltage select' in output:
|
||||
pytest.skip('No SD/MMC card present')
|
||||
|
||||
array = output.split()
|
||||
global devices
|
||||
global controllers
|
||||
controllers = int(len(array) / 2)
|
||||
for x in range(0, controllers):
|
||||
y = x * 2
|
||||
devices[x] = {}
|
||||
devices[x]['name'] = array[y]
|
||||
|
||||
global mmc_set_up
|
||||
mmc_set_up = True
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
def test_mmc_dev(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
fail = 0
|
||||
for x in range(0, controllers):
|
||||
devices[x]['detected'] = 'yes'
|
||||
output = u_boot_console.run_command('mmc dev %d' % x)
|
||||
|
||||
# Some sort of switch here
|
||||
if 'Card did not respond to voltage select' in output:
|
||||
fail = 1
|
||||
devices[x]['detected'] = 'no'
|
||||
|
||||
if 'no mmc device at slot' in output:
|
||||
devices[x]['detected'] = 'no'
|
||||
|
||||
if 'MMC: no card present' in output:
|
||||
devices[x]['detected'] = 'no'
|
||||
|
||||
if fail:
|
||||
pytest.fail('Card not present')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
def test_mmcinfo(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
output = u_boot_console.run_command('mmcinfo')
|
||||
if 'busy timeout' in output:
|
||||
pytest.skip('No SD/MMC/eMMC device present')
|
||||
|
||||
obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output)
|
||||
try:
|
||||
capacity = float(obj.groups()[0])
|
||||
print(capacity)
|
||||
devices[x]['capacity'] = capacity
|
||||
print('Capacity of dev %d is: %g GiB' % (x, capacity))
|
||||
except ValueError:
|
||||
pytest.fail('MMC capacity not recognized')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
def test_mmc_info(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
|
||||
output = u_boot_console.run_command('mmc info')
|
||||
|
||||
obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output)
|
||||
try:
|
||||
capacity = float(obj.groups()[0])
|
||||
print(capacity)
|
||||
if devices[x]['capacity'] != capacity:
|
||||
pytest.fail("MMC capacity doesn't match mmcinfo")
|
||||
|
||||
except ValueError:
|
||||
pytest.fail('MMC capacity not recognized')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
def test_mmc_rescan(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
output = u_boot_console.run_command('mmc rescan')
|
||||
if output:
|
||||
pytest.fail('mmc rescan has something to check')
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
def test_mmc_part(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
output = u_boot_console.run_command('mmc part')
|
||||
|
||||
lines = output.split('\n')
|
||||
part_fat = []
|
||||
part_ext = []
|
||||
for line in lines:
|
||||
obj = re.search(
|
||||
r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line)
|
||||
if obj:
|
||||
part_id = int(obj.groups()[0])
|
||||
part_type = obj.groups()[1]
|
||||
print('part_id:%d, part_type:%s' % (part_id, part_type))
|
||||
|
||||
if part_type in ['0c', '0b', '0e']:
|
||||
print('Fat detected')
|
||||
part_fat.append(part_id)
|
||||
elif part_type == '83':
|
||||
print('ext detected')
|
||||
part_ext.append(part_id)
|
||||
else:
|
||||
pytest.fail('Unsupported Filesystem on device %d' % x)
|
||||
devices[x]['ext4'] = part_ext
|
||||
devices[x]['ext2'] = part_ext
|
||||
devices[x]['fat'] = part_fat
|
||||
|
||||
if not part_ext and not part_fat:
|
||||
pytest.fail('No partition detected on device %d' % x)
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_fat')
|
||||
def test_mmc_fatls_fatinfo(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'fat'
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
output = u_boot_console.run_command(
|
||||
'fatls mmc %d:%s' % (x, part))
|
||||
if 'Unrecognized filesystem type' in output:
|
||||
partitions.remove(part)
|
||||
pytest.fail('Unrecognized filesystem')
|
||||
|
||||
if not re.search(r'\d file\(s\), \d dir\(s\)', output):
|
||||
pytest.fail('%s read failed on device %d' % (fs.upper, x))
|
||||
output = u_boot_console.run_command(
|
||||
'fatinfo mmc %d:%s' % (x, part))
|
||||
string = 'Filesystem: %s' % fs.upper
|
||||
if re.search(string, output):
|
||||
pytest.fail('%s FS failed on device %d' % (fs.upper(), x))
|
||||
part_detect = 1
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_fat')
|
||||
@pytest.mark.buildconfigspec('cmd_memory')
|
||||
def test_mmc_fatload_fatwrite(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'fat'
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
devices[x]['addr_%d' % part] = addr
|
||||
size = random.randint(4, 1 * 1024 * 1024)
|
||||
devices[x]['size_%d' % part] = size
|
||||
# count CRC32
|
||||
output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
|
||||
m = re.search('==> (.+?)', output)
|
||||
if not m:
|
||||
pytest.fail('CRC32 failed')
|
||||
expected_crc32 = m.group(1)
|
||||
devices[x]['expected_crc32_%d' % part] = expected_crc32
|
||||
# do write
|
||||
file = '%s_%d' % ('uboot_test', size)
|
||||
devices[x]['file_%d' % part] = file
|
||||
output = u_boot_console.run_command(
|
||||
'%swrite mmc %d:%s %x %s %x' % (fs, x, part, addr, file, size)
|
||||
)
|
||||
assert 'Unable to write' not in output
|
||||
assert 'Error' not in output
|
||||
assert 'overflow' not in output
|
||||
expected_text = '%d bytes written' % size
|
||||
assert expected_text in output
|
||||
|
||||
alignment = int(
|
||||
u_boot_console.config.buildconfig.get(
|
||||
'config_sys_cacheline_size', 128
|
||||
)
|
||||
)
|
||||
offset = random.randrange(alignment, 1024, alignment)
|
||||
output = u_boot_console.run_command(
|
||||
'%sload mmc %d:%s %x %s' % (fs, x, part, addr + offset, file)
|
||||
)
|
||||
assert 'Invalid FAT entry' not in output
|
||||
assert 'Unable to read file' not in output
|
||||
assert 'Misaligned buffer address' not in output
|
||||
expected_text = '%d bytes read' % size
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr + offset)
|
||||
)
|
||||
assert expected_crc32 in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_ext4')
|
||||
def test_mmc_ext4ls(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'ext4'
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
for part in partitions:
|
||||
output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part))
|
||||
if 'Unrecognized filesystem type' in output:
|
||||
partitions.remove(part)
|
||||
pytest.fail('Unrecognized filesystem')
|
||||
part_detect = 1
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_ext4')
|
||||
@pytest.mark.buildconfigspec('ext4_write')
|
||||
@pytest.mark.buildconfigspec('cmd_memory')
|
||||
def test_mmc_ext4load_ext4write(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'ext4'
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
devices[x]['addr_%d' % part] = addr
|
||||
size = random.randint(4, 1 * 1024 * 1024)
|
||||
devices[x]['size_%d' % part] = size
|
||||
# count CRC32
|
||||
output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
|
||||
m = re.search('==> (.+?)', output)
|
||||
if not m:
|
||||
pytest.fail('CRC32 failed')
|
||||
expected_crc32 = m.group(1)
|
||||
devices[x]['expected_crc32_%d' % part] = expected_crc32
|
||||
# do write
|
||||
|
||||
file = '%s_%d' % ('uboot_test', size)
|
||||
devices[x]['file_%d' % part] = file
|
||||
output = u_boot_console.run_command(
|
||||
'%swrite mmc %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
|
||||
)
|
||||
assert 'Unable to write' not in output
|
||||
assert 'Error' not in output
|
||||
assert 'overflow' not in output
|
||||
expected_text = '%d bytes written' % size
|
||||
assert expected_text in output
|
||||
|
||||
offset = random.randrange(128, 1024, 128)
|
||||
output = u_boot_console.run_command(
|
||||
'%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file)
|
||||
)
|
||||
expected_text = '%d bytes read' % size
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr + offset)
|
||||
)
|
||||
assert expected_crc32 in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_ext2')
|
||||
def test_mmc_ext2ls(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'ext2'
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part))
|
||||
if 'Unrecognized filesystem type' in output:
|
||||
partitions.remove(part)
|
||||
pytest.fail('Unrecognized filesystem')
|
||||
part_detect = 1
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_ext2')
|
||||
@pytest.mark.buildconfigspec('cmd_ext4')
|
||||
@pytest.mark.buildconfigspec('ext4_write')
|
||||
@pytest.mark.buildconfigspec('cmd_memory')
|
||||
def test_mmc_ext2load(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'ext2'
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = devices[x]['addr_%d' % part]
|
||||
size = devices[x]['size_%d' % part]
|
||||
expected_crc32 = devices[x]['expected_crc32_%d' % part]
|
||||
file = devices[x]['file_%d' % part]
|
||||
|
||||
offset = random.randrange(128, 1024, 128)
|
||||
output = u_boot_console.run_command(
|
||||
'%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file)
|
||||
)
|
||||
expected_text = '%d bytes read' % size
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr + offset)
|
||||
)
|
||||
assert expected_crc32 in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_fs_generic')
|
||||
def test_mmc_ls(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
for fs in ['fat', 'ext4']:
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
output = u_boot_console.run_command('ls mmc %d:%s' % (x, part))
|
||||
if re.search(r'No \w+ table on this device', output):
|
||||
pytest.fail(
|
||||
'%s: Partition table not found %d' % (fs.upper(), x)
|
||||
)
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No partition detected')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_fs_generic')
|
||||
def test_mmc_load(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
for fs in ['fat', 'ext4']:
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = devices[x]['addr_%d' % part]
|
||||
size = devices[x]['size_%d' % part]
|
||||
expected_crc32 = devices[x]['expected_crc32_%d' % part]
|
||||
file = devices[x]['file_%d' % part]
|
||||
|
||||
offset = random.randrange(128, 1024, 128)
|
||||
output = u_boot_console.run_command(
|
||||
'load mmc %d:%s %x /%s' % (x, part, addr + offset, file)
|
||||
)
|
||||
expected_text = '%d bytes read' % size
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr + offset)
|
||||
)
|
||||
assert expected_crc32 in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No partition detected')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_fs_generic')
|
||||
def test_mmc_save(u_boot_console):
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
for fs in ['fat', 'ext4']:
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = devices[x]['addr_%d' % part]
|
||||
size = 0
|
||||
file = devices[x]['file_%d' % part]
|
||||
|
||||
offset = random.randrange(128, 1024, 128)
|
||||
output = u_boot_console.run_command(
|
||||
'save mmc %d:%s %x /%s %d'
|
||||
% (x, part, addr + offset, file, size)
|
||||
)
|
||||
expected_text = '%d bytes written' % size
|
||||
assert expected_text in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No partition detected')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_mmc')
|
||||
@pytest.mark.buildconfigspec('cmd_fat')
|
||||
@pytest.mark.buildconfigspec('cmd_memory')
|
||||
def test_mmc_fat_read_write_files(u_boot_console):
|
||||
test_mmc_list(u_boot_console)
|
||||
test_mmc_dev(u_boot_console)
|
||||
test_mmcinfo(u_boot_console)
|
||||
test_mmc_part(u_boot_console)
|
||||
if not mmc_set_up:
|
||||
pytest.skip('No SD/MMC/eMMC controller available')
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'fat'
|
||||
|
||||
# Number of files to be written/read in MMC card
|
||||
num_files = 100
|
||||
|
||||
for x in range(0, controllers):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('mmc dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
count_f = 0
|
||||
addr_l = []
|
||||
size_l = []
|
||||
file_l = []
|
||||
crc32_l = []
|
||||
offset_l = []
|
||||
addr_l.append(addr)
|
||||
|
||||
while count_f < num_files:
|
||||
size_l.append(random.randint(4, 1 * 1024 * 1024))
|
||||
|
||||
# CRC32 count
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x %x' % (addr_l[count_f], size_l[count_f])
|
||||
)
|
||||
m = re.search('==> (.+?)', output)
|
||||
if not m:
|
||||
pytest.fail('CRC32 failed')
|
||||
crc32_l.append(m.group(1))
|
||||
|
||||
# Write operation
|
||||
file_l.append('%s_%d_%d' % ('uboot_test', count_f, size_l[count_f]))
|
||||
output = u_boot_console.run_command(
|
||||
'%swrite mmc %d:%s %x %s %x'
|
||||
% (
|
||||
fs,
|
||||
x,
|
||||
part,
|
||||
addr_l[count_f],
|
||||
file_l[count_f],
|
||||
size_l[count_f],
|
||||
)
|
||||
)
|
||||
assert 'Unable to write' not in output
|
||||
assert 'Error' not in output
|
||||
assert 'overflow' not in output
|
||||
expected_text = '%d bytes written' % size_l[count_f]
|
||||
assert expected_text in output
|
||||
|
||||
addr_l.append(addr_l[count_f] + size_l[count_f] + 1048576)
|
||||
count_f += 1
|
||||
|
||||
count_f = 0
|
||||
while count_f < num_files:
|
||||
alignment = int(
|
||||
u_boot_console.config.buildconfig.get(
|
||||
'config_sys_cacheline_size', 128
|
||||
)
|
||||
)
|
||||
offset_l.append(random.randrange(alignment, 1024, alignment))
|
||||
|
||||
# Read operation
|
||||
output = u_boot_console.run_command(
|
||||
'%sload mmc %d:%s %x %s'
|
||||
% (
|
||||
fs,
|
||||
x,
|
||||
part,
|
||||
addr_l[count_f] + offset_l[count_f],
|
||||
file_l[count_f],
|
||||
)
|
||||
)
|
||||
assert 'Invalid FAT entry' not in output
|
||||
assert 'Unable to read file' not in output
|
||||
assert 'Misaligned buffer address' not in output
|
||||
expected_text = '%d bytes read' % size_l[count_f]
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr_l[count_f] + offset_l[count_f])
|
||||
)
|
||||
assert crc32_l[count_f] in output
|
||||
|
||||
count_f += 1
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
92
test/py/tests/test_scsi.py
Normal file
92
test/py/tests/test_scsi.py
Normal file
|
@ -0,0 +1,92 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# (C) Copyright 2023, Advanced Micro Devices, Inc.
|
||||
|
||||
import pytest
|
||||
|
||||
"""
|
||||
Note: This test relies on boardenv_* containing configuration values to define
|
||||
the SCSI device number, type and capacity. This test will be automatically
|
||||
skipped without this.
|
||||
|
||||
For example:
|
||||
|
||||
# Setup env__scsi_device_test to set the SCSI device number/slot, the type of
|
||||
device, and the device capacity in MB.
|
||||
env__scsi_device_test = {
|
||||
'dev_num': 0,
|
||||
'device_type': 'Hard Disk',
|
||||
'device_capacity': '476940.0 MB',
|
||||
}
|
||||
"""
|
||||
|
||||
def scsi_setup(u_boot_console):
|
||||
f = u_boot_console.config.env.get('env__scsi_device_test', None)
|
||||
if not f:
|
||||
pytest.skip('No SCSI device to test')
|
||||
|
||||
dev_num = f.get('dev_num', None)
|
||||
if not isinstance(dev_num, int):
|
||||
pytest.skip('No device number specified in env file to read')
|
||||
|
||||
dev_type = f.get('device_type')
|
||||
if not dev_type:
|
||||
pytest.skip('No device type specified in env file to read')
|
||||
|
||||
dev_size = f.get('device_capacity')
|
||||
if not dev_size:
|
||||
pytest.skip('No device capacity specified in env file to read')
|
||||
|
||||
return dev_num, dev_type, dev_size
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_scsi')
|
||||
def test_scsi_reset(u_boot_console):
|
||||
dev_num, dev_type, dev_size = scsi_setup(u_boot_console)
|
||||
output = u_boot_console.run_command('scsi reset')
|
||||
assert f'Device {dev_num}:' in output
|
||||
assert f'Type: {dev_type}' in output
|
||||
assert f'Capacity: {dev_size}' in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_scsi')
|
||||
def test_scsi_info(u_boot_console):
|
||||
dev_num, dev_type, dev_size = scsi_setup(u_boot_console)
|
||||
output = u_boot_console.run_command('scsi info')
|
||||
assert f'Device {dev_num}:' in output
|
||||
assert f'Type: {dev_type}' in output
|
||||
assert f'Capacity: {dev_size}' in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_scsi')
|
||||
def test_scsi_scan(u_boot_console):
|
||||
dev_num, dev_type, dev_size = scsi_setup(u_boot_console)
|
||||
output = u_boot_console.run_command('scsi scan')
|
||||
assert f'Device {dev_num}:' in output
|
||||
assert f'Type: {dev_type}' in output
|
||||
assert f'Capacity: {dev_size}' in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_scsi')
|
||||
def test_scsi_dev(u_boot_console):
|
||||
dev_num, dev_type, dev_size = scsi_setup(u_boot_console)
|
||||
output = u_boot_console.run_command('scsi device')
|
||||
assert 'no scsi devices available' not in output
|
||||
assert f'device {dev_num}:' in output
|
||||
assert f'Type: {dev_type}' in output
|
||||
assert f'Capacity: {dev_size}' in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
output = u_boot_console.run_command('scsi device %d' % dev_num)
|
||||
assert 'is now current device' in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_scsi')
|
||||
def test_scsi_part(u_boot_console):
|
||||
test_scsi_dev(u_boot_console)
|
||||
output = u_boot_console.run_command('scsi part')
|
||||
assert 'Partition Map for SCSI device' in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
626
test/py/tests/test_usb.py
Normal file
626
test/py/tests/test_usb.py
Normal file
|
@ -0,0 +1,626 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# (C) Copyright 2023, Advanced Micro Devices, Inc.
|
||||
|
||||
import pytest
|
||||
import random
|
||||
import re
|
||||
import u_boot_utils
|
||||
|
||||
"""
|
||||
Note: This test doesn't rely on boardenv_* configuration values but it can
|
||||
change the test behavior. To test USB file system cases (fat32, ext2, ext4),
|
||||
USB device should be formatted and valid partitions should be created for
|
||||
different file system, otherwise it may leads to failure. This test will be
|
||||
skipped if the USB device is not detected.
|
||||
|
||||
For example:
|
||||
|
||||
# Setup env__usb_device_test_skip to not skipping the test. By default, its
|
||||
# value is set to True. Set it to False to run all tests for USB device.
|
||||
env__usb_device_test_skip = False
|
||||
"""
|
||||
|
||||
def setup_usb(u_boot_console):
|
||||
if u_boot_console.config.env.get('env__usb_device_test_skip', True):
|
||||
pytest.skip('USB device test is not enabled')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
def test_usb_start(u_boot_console):
|
||||
setup_usb(u_boot_console)
|
||||
output = u_boot_console.run_command('usb start')
|
||||
|
||||
# if output is empty, usb start may already run as part of preboot command
|
||||
# re-start the usb, in that case
|
||||
if not output:
|
||||
u_boot_console.run_command('usb stop')
|
||||
output = u_boot_console.run_command('usb start')
|
||||
|
||||
if 'No USB device found' in output:
|
||||
pytest.skip('No USB controller available')
|
||||
|
||||
if 'Card did not respond to voltage select' in output:
|
||||
pytest.skip('No USB device present')
|
||||
|
||||
controllers = 0
|
||||
storage_device = 0
|
||||
obj = re.search(r'\d USB Device\(s\) found', output)
|
||||
controllers = int(obj.group()[0])
|
||||
|
||||
if not controllers:
|
||||
pytest.skip('No USB device present')
|
||||
|
||||
obj = re.search(r'\d Storage Device\(s\) found', output)
|
||||
storage_device = int(obj.group()[0])
|
||||
|
||||
if not storage_device:
|
||||
pytest.skip('No USB storage device present')
|
||||
|
||||
assert 'USB init failed' not in output
|
||||
assert 'starting USB...' in output
|
||||
|
||||
if 'Starting the controller' in output:
|
||||
assert 'USB XHCI' in output
|
||||
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
return controllers, storage_device
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
def test_usb_stop(u_boot_console):
|
||||
setup_usb(u_boot_console)
|
||||
output = u_boot_console.run_command('usb stop')
|
||||
assert 'stopping USB..' in output
|
||||
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
output = u_boot_console.run_command('usb dev')
|
||||
assert "USB is stopped. Please issue 'usb start' first." in output
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
def test_usb_reset(u_boot_console):
|
||||
setup_usb(u_boot_console)
|
||||
output = u_boot_console.run_command('usb reset')
|
||||
|
||||
if 'No USB device found' in output:
|
||||
pytest.skip('No USB controller available')
|
||||
|
||||
if 'Card did not respond to voltage select' in output:
|
||||
pytest.skip('No USB device present')
|
||||
|
||||
obj = re.search(r'\d USB Device\(s\) found', output)
|
||||
usb_dev_num = int(obj.group()[0])
|
||||
|
||||
if not usb_dev_num:
|
||||
pytest.skip('No USB device present')
|
||||
|
||||
obj = re.search(r'\d Storage Device\(s\) found', output)
|
||||
usb_stor_num = int(obj.group()[0])
|
||||
|
||||
if not usb_stor_num:
|
||||
pytest.skip('No USB storage device present')
|
||||
|
||||
assert 'BUG' not in output
|
||||
assert 'USB init failed' not in output
|
||||
assert 'resetting USB...' in output
|
||||
|
||||
if 'Starting the controller' in output:
|
||||
assert 'USB XHCI' in output
|
||||
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
def test_usb_info(u_boot_console):
|
||||
controllers, storage_device = test_usb_start(u_boot_console)
|
||||
output = u_boot_console.run_command('usb info')
|
||||
|
||||
num_controller = len(re.findall(': Hub,', output))
|
||||
num_mass_storage = len(re.findall(': Mass Storage,', output))
|
||||
|
||||
assert num_controller == controllers - 1
|
||||
assert num_mass_storage == storage_device
|
||||
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
for i in range(0, storage_device + controllers - 1):
|
||||
output = u_boot_console.run_command('usb info %d' % i)
|
||||
num_controller = len(re.findall(': Hub,', output))
|
||||
num_mass_storage = len(re.findall(': Mass Storage,', output))
|
||||
assert num_controller + num_mass_storage == 1
|
||||
assert 'No device available' not in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
def test_usb_tree(u_boot_console):
|
||||
controllers, storage_device = test_usb_start(u_boot_console)
|
||||
output = u_boot_console.run_command('usb tree')
|
||||
|
||||
num_controller = len(re.findall('Hub', output))
|
||||
num_mass_storage = len(re.findall('Mass Storage', output))
|
||||
|
||||
assert num_controller == controllers - 1
|
||||
assert num_mass_storage == storage_device
|
||||
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('usb_storage')
|
||||
def test_usb_storage(u_boot_console):
|
||||
controllers, storage_device = test_usb_start(u_boot_console)
|
||||
output = u_boot_console.run_command('usb storage')
|
||||
|
||||
obj = re.findall(r'Capacity: (\d+|\d+[\.]?\d)', output)
|
||||
devices = {}
|
||||
|
||||
for key in range(int(storage_device)):
|
||||
devices[key] = {}
|
||||
|
||||
for x in range(int(storage_device)):
|
||||
try:
|
||||
capacity = float(obj[x].split()[0])
|
||||
devices[x]['capacity'] = capacity
|
||||
print('USB storage device %d capacity is: %g MB' % (x, capacity))
|
||||
except ValueError:
|
||||
pytest.fail('USB storage device capacity not recognized')
|
||||
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
def test_usb_dev(u_boot_console):
|
||||
controllers, storage_device = test_usb_start(u_boot_console)
|
||||
output = u_boot_console.run_command('usb dev')
|
||||
|
||||
assert 'no usb devices available' not in output
|
||||
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
devices = {}
|
||||
|
||||
for key in range(int(storage_device)):
|
||||
devices[key] = {}
|
||||
|
||||
fail = 0
|
||||
for x in range(0, storage_device):
|
||||
devices[x]['detected'] = 'yes'
|
||||
output = u_boot_console.run_command('usb dev %d' % x)
|
||||
|
||||
if 'Card did not respond to voltage select' in output:
|
||||
fail = 1
|
||||
devices[x]['detected'] = 'no'
|
||||
|
||||
if 'No USB device found' in output:
|
||||
devices[x]['detected'] = 'no'
|
||||
|
||||
if 'unknown device' in output:
|
||||
devices[x]['detected'] = 'no'
|
||||
|
||||
assert 'is now current device' in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
if fail:
|
||||
pytest.fail('USB device not present')
|
||||
|
||||
return devices, controllers, storage_device
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
def test_usb_part(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_dev(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
u_boot_console.run_command('usb part')
|
||||
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
for i in range(0, storage_device):
|
||||
if devices[i]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % i)
|
||||
output = u_boot_console.run_command('usb part')
|
||||
|
||||
lines = output.split('\n')
|
||||
part_fat = []
|
||||
part_ext = []
|
||||
for line in lines:
|
||||
obj = re.search(r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line)
|
||||
if obj:
|
||||
part_id = int(obj.groups()[0])
|
||||
part_type = obj.groups()[1]
|
||||
print('part_id:%d, part_type:%s' % (part_id, part_type))
|
||||
|
||||
if part_type == '0c' or part_type == '0b' or part_type == '0e':
|
||||
print('Fat detected')
|
||||
part_fat.append(part_id)
|
||||
elif part_type == '83':
|
||||
print('ext detected')
|
||||
part_ext.append(part_id)
|
||||
else:
|
||||
pytest.fail('Unsupported Filesystem on device %d' % i)
|
||||
devices[i]['ext4'] = part_ext
|
||||
devices[i]['ext2'] = part_ext
|
||||
devices[i]['fat'] = part_fat
|
||||
|
||||
if not part_ext and not part_fat:
|
||||
pytest.fail('No partition detected on device %d' % i)
|
||||
|
||||
return devices, controllers, storage_device
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_fat')
|
||||
def test_usb_fatls_fatinfo(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'fat'
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
output = u_boot_console.run_command('fatls usb %d:%s' % (x, part))
|
||||
if 'Unrecognized filesystem type' in output:
|
||||
partitions.remove(part)
|
||||
pytest.fail('Unrecognized filesystem')
|
||||
|
||||
if not re.search(r'\d file\(s\), \d dir\(s\)', output):
|
||||
pytest.fail('%s read failed on device %d' % (fs.upper, x))
|
||||
|
||||
output = u_boot_console.run_command('fatinfo usb %d:%s' % (x, part))
|
||||
string = 'Filesystem: %s' % fs.upper
|
||||
if re.search(string, output):
|
||||
pytest.fail('%s FS failed on device %d' % (fs.upper(), x))
|
||||
part_detect = 1
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_fat')
|
||||
@pytest.mark.buildconfigspec('cmd_memory')
|
||||
def test_usb_fatload_fatwrite(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'fat'
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
size = random.randint(4, 1 * 1024 * 1024)
|
||||
output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
|
||||
m = re.search('==> (.+?)', output)
|
||||
if not m:
|
||||
pytest.fail('CRC32 failed')
|
||||
expected_crc32 = m.group(1)
|
||||
|
||||
file = '%s_%d' % ('uboot_test', size)
|
||||
output = u_boot_console.run_command(
|
||||
'%swrite usb %d:%s %x %s %x' % (fs, x, part, addr, file, size)
|
||||
)
|
||||
assert 'Unable to write' not in output
|
||||
assert 'Error' not in output
|
||||
assert 'overflow' not in output
|
||||
expected_text = '%d bytes written' % size
|
||||
assert expected_text in output
|
||||
|
||||
alignment = int(
|
||||
u_boot_console.config.buildconfig.get(
|
||||
'config_sys_cacheline_size', 128
|
||||
)
|
||||
)
|
||||
offset = random.randrange(alignment, 1024, alignment)
|
||||
output = u_boot_console.run_command(
|
||||
'%sload usb %d:%s %x %s' % (fs, x, part, addr + offset, file)
|
||||
)
|
||||
assert 'Invalid FAT entry' not in output
|
||||
assert 'Unable to read file' not in output
|
||||
assert 'Misaligned buffer address' not in output
|
||||
expected_text = '%d bytes read' % size
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr + offset)
|
||||
)
|
||||
assert expected_crc32 in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
return file, size
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_ext4')
|
||||
def test_usb_ext4ls(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'ext4'
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
for part in partitions:
|
||||
output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part))
|
||||
if 'Unrecognized filesystem type' in output:
|
||||
partitions.remove(part)
|
||||
pytest.fail('Unrecognized filesystem')
|
||||
part_detect = 1
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_ext4')
|
||||
@pytest.mark.buildconfigspec('ext4_write')
|
||||
@pytest.mark.buildconfigspec('cmd_memory')
|
||||
def test_usb_ext4load_ext4write(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'ext4'
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
size = random.randint(4, 1 * 1024 * 1024)
|
||||
output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
|
||||
m = re.search('==> (.+?)', output)
|
||||
if not m:
|
||||
pytest.fail('CRC32 failed')
|
||||
expected_crc32 = m.group(1)
|
||||
file = '%s_%d' % ('uboot_test', size)
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'%swrite usb %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
|
||||
)
|
||||
assert 'Unable to write' not in output
|
||||
assert 'Error' not in output
|
||||
assert 'overflow' not in output
|
||||
expected_text = '%d bytes written' % size
|
||||
assert expected_text in output
|
||||
|
||||
offset = random.randrange(128, 1024, 128)
|
||||
output = u_boot_console.run_command(
|
||||
'%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
|
||||
)
|
||||
expected_text = '%d bytes read' % size
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr + offset)
|
||||
)
|
||||
assert expected_crc32 in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
return file, size
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_ext2')
|
||||
def test_usb_ext2ls(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'ext2'
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part))
|
||||
if 'Unrecognized filesystem type' in output:
|
||||
partitions.remove(part)
|
||||
pytest.fail('Unrecognized filesystem')
|
||||
part_detect = 1
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_ext2')
|
||||
@pytest.mark.buildconfigspec('cmd_ext4')
|
||||
@pytest.mark.buildconfigspec('ext4_write')
|
||||
@pytest.mark.buildconfigspec('cmd_memory')
|
||||
def test_usb_ext2load(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
file, size = test_usb_ext4load_ext4write(u_boot_console)
|
||||
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
fs = 'ext2'
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
|
||||
m = re.search('==> (.+?)', output)
|
||||
if not m:
|
||||
pytest.fail('CRC32 failed')
|
||||
expected_crc32 = m.group(1)
|
||||
|
||||
offset = random.randrange(128, 1024, 128)
|
||||
output = u_boot_console.run_command(
|
||||
'%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
|
||||
)
|
||||
expected_text = '%d bytes read' % size
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr + offset)
|
||||
)
|
||||
assert expected_crc32 in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No %s partition detected' % fs.upper())
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_fs_generic')
|
||||
def test_usb_ls(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
for fs in ['fat', 'ext4']:
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
output = u_boot_console.run_command('ls usb %d:%s' % (x, part))
|
||||
if re.search(r'No \w+ table on this device', output):
|
||||
pytest.fail(
|
||||
'%s: Partition table not found %d' % (fs.upper(), x)
|
||||
)
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No partition detected')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_fs_generic')
|
||||
def test_usb_load(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
for fs in ['fat', 'ext4']:
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
|
||||
if fs == 'fat':
|
||||
file, size = test_usb_fatload_fatwrite(u_boot_console)
|
||||
elif fs == 'ext4':
|
||||
file, size = test_usb_ext4load_ext4write(u_boot_console)
|
||||
|
||||
output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
|
||||
m = re.search('==> (.+?)', output)
|
||||
if not m:
|
||||
pytest.fail('CRC32 failed')
|
||||
expected_crc32 = m.group(1)
|
||||
|
||||
offset = random.randrange(128, 1024, 128)
|
||||
output = u_boot_console.run_command(
|
||||
'load usb %d:%s %x /%s' % (x, part, addr + offset, file)
|
||||
)
|
||||
expected_text = '%d bytes read' % size
|
||||
assert expected_text in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'crc32 %x $filesize' % (addr + offset)
|
||||
)
|
||||
assert expected_crc32 in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No partition detected')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_usb')
|
||||
@pytest.mark.buildconfigspec('cmd_fs_generic')
|
||||
def test_usb_save(u_boot_console):
|
||||
devices, controllers, storage_device = test_usb_part(u_boot_console)
|
||||
if not devices:
|
||||
pytest.skip('No devices detected')
|
||||
|
||||
part_detect = 0
|
||||
for x in range(0, int(storage_device)):
|
||||
if devices[x]['detected'] == 'yes':
|
||||
u_boot_console.run_command('usb dev %d' % x)
|
||||
for fs in ['fat', 'ext4']:
|
||||
try:
|
||||
partitions = devices[x][fs]
|
||||
except:
|
||||
print('No %s table on this device' % fs.upper())
|
||||
continue
|
||||
|
||||
for part in partitions:
|
||||
part_detect = 1
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
size = random.randint(4, 1 * 1024 * 1024)
|
||||
file = '%s_%d' % ('uboot_test', size)
|
||||
|
||||
offset = random.randrange(128, 1024, 128)
|
||||
output = u_boot_console.run_command(
|
||||
'save usb %d:%s %x /%s %x'
|
||||
% (x, part, addr + offset, file, size)
|
||||
)
|
||||
expected_text = '%d bytes written' % size
|
||||
assert expected_text in output
|
||||
|
||||
if not part_detect:
|
||||
pytest.skip('No partition detected')
|
190
test/py/tests/test_zynq_secure.py
Normal file
190
test/py/tests/test_zynq_secure.py
Normal file
|
@ -0,0 +1,190 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# (C) Copyright 2023, Advanced Micro Devices, Inc.
|
||||
|
||||
import pytest
|
||||
import re
|
||||
import u_boot_utils
|
||||
import test_net
|
||||
|
||||
"""
|
||||
This test verifies different type of secure boot images to authentication and
|
||||
decryption using AES and RSA features for AMD's Zynq SoC.
|
||||
|
||||
Note: This test relies on boardenv_* containing configuration values to define
|
||||
the network available and files to be used for testing. Without this, this test
|
||||
will be automatically skipped. It also relies on dhcp or setup_static net test
|
||||
to support tftp to load files from a TFTP server.
|
||||
|
||||
For example:
|
||||
|
||||
# Details regarding the files that may be read from a TFTP server and addresses
|
||||
# and size for aes and rsa cases respectively. This variable may be omitted or
|
||||
# set to None if zynqmp secure testing is not possible or desired.
|
||||
env__zynq_aes_readable_file = {
|
||||
'fn': 'zynq_aes_image.bin',
|
||||
'fnbit': 'zynq_aes_bit.bin',
|
||||
'fnpbit': 'zynq_aes_par_bit.bin',
|
||||
'srcaddr': 0x1000000,
|
||||
'dstaddr': 0x2000000,
|
||||
'dstlen': 0x1000000,
|
||||
}
|
||||
|
||||
env__zynq_rsa_readable_file = {
|
||||
'fn': 'zynq_rsa_image.bin',
|
||||
'fninvalid': 'zynq_rsa_image_invalid.bin',
|
||||
'srcaddr': 0x1000000,
|
||||
}
|
||||
"""
|
||||
|
||||
def zynq_secure_pre_commands(u_boot_console):
|
||||
output = u_boot_console.run_command('print modeboot')
|
||||
if not 'modeboot=' in output:
|
||||
pytest.skip('bootmode cannnot be determined')
|
||||
m = re.search('modeboot=(.+?)boot', output)
|
||||
if not m:
|
||||
pytest.skip('bootmode cannnot be determined')
|
||||
bootmode = m.group(1)
|
||||
if bootmode == 'jtag':
|
||||
pytest.skip('skipping due to jtag bootmode')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynq_aes')
|
||||
def test_zynq_aes_image(u_boot_console):
|
||||
f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
|
||||
if not f:
|
||||
pytest.skip('No TFTP readable file for zynq secure aes case to read')
|
||||
|
||||
dstaddr = f.get('dstaddr', None)
|
||||
if not dstaddr:
|
||||
pytest.skip('No dstaddr specified in env file to read')
|
||||
|
||||
dstsize = f.get('dstlen', None)
|
||||
if not dstsize:
|
||||
pytest.skip('No dstlen specified in env file to read')
|
||||
|
||||
zynq_secure_pre_commands(u_boot_console)
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
srcaddr = f.get('srcaddr', None)
|
||||
if not srcaddr:
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
|
||||
expected_tftp = 'Bytes transferred = '
|
||||
fn = f['fn']
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
|
||||
assert expected_tftp in output
|
||||
|
||||
expected_op = 'zynq aes [operation type] <srcaddr>'
|
||||
output = u_boot_console.run_command(
|
||||
'zynq aes %x $filesize %x %x' % (srcaddr, dstaddr, dstsize)
|
||||
)
|
||||
assert expected_op not in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynq_aes')
|
||||
def test_zynq_aes_bitstream(u_boot_console):
|
||||
f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
|
||||
if not f:
|
||||
pytest.skip('No TFTP readable file for zynq secure aes case to read')
|
||||
|
||||
zynq_secure_pre_commands(u_boot_console)
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
srcaddr = f.get('srcaddr', None)
|
||||
if not srcaddr:
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
|
||||
expected_tftp = 'Bytes transferred = '
|
||||
fn = f['fnbit']
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
|
||||
assert expected_tftp in output
|
||||
|
||||
expected_op = 'zynq aes [operation type] <srcaddr>'
|
||||
output = u_boot_console.run_command(
|
||||
'zynq aes load %x $filesize' % (srcaddr)
|
||||
)
|
||||
assert expected_op not in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynq_aes')
|
||||
def test_zynq_aes_partial_bitstream(u_boot_console):
|
||||
f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None)
|
||||
if not f:
|
||||
pytest.skip('No TFTP readable file for zynq secure aes case to read')
|
||||
|
||||
zynq_secure_pre_commands(u_boot_console)
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
srcaddr = f.get('srcaddr', None)
|
||||
if not srcaddr:
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
|
||||
expected_tftp = 'Bytes transferred = '
|
||||
fn = f['fnpbit']
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
|
||||
assert expected_tftp in output
|
||||
|
||||
expected_op = 'zynq aes [operation type] <srcaddr>'
|
||||
output = u_boot_console.run_command('zynq aes loadp %x $filesize' % (srcaddr))
|
||||
assert expected_op not in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynq_rsa')
|
||||
def test_zynq_rsa_image(u_boot_console):
|
||||
f = u_boot_console.config.env.get('env__zynq_rsa_readable_file', None)
|
||||
if not f:
|
||||
pytest.skip('No TFTP readable file for zynq secure rsa case to read')
|
||||
|
||||
zynq_secure_pre_commands(u_boot_console)
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
srcaddr = f.get('srcaddr', None)
|
||||
if not srcaddr:
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
|
||||
expected_tftp = 'Bytes transferred = '
|
||||
fn = f['fn']
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn))
|
||||
assert expected_tftp in output
|
||||
|
||||
expected_op = 'zynq rsa <baseaddr>'
|
||||
output = u_boot_console.run_command('zynq rsa %x ' % (srcaddr))
|
||||
assert expected_op not in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynq_rsa')
|
||||
def test_zynq_rsa_image_invalid(u_boot_console):
|
||||
f = u_boot_console.config.env.get('env__zynq_rsa_readable_file', None)
|
||||
if not f:
|
||||
pytest.skip('No TFTP readable file for zynq secure rsa case to read')
|
||||
|
||||
zynq_secure_pre_commands(u_boot_console)
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
srcaddr = f.get('srcaddr', None)
|
||||
if not srcaddr:
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
|
||||
expected_tftp = 'Bytes transferred = '
|
||||
fninvalid = f['fninvalid']
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fninvalid))
|
||||
assert expected_tftp in output
|
||||
|
||||
expected_op = 'zynq rsa <baseaddr>'
|
||||
output = u_boot_console.run_command('zynq rsa %x ' % (srcaddr))
|
||||
assert expected_op in output
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert not output.endswith('0')
|
208
test/py/tests/test_zynqmp_rpu.py
Normal file
208
test/py/tests/test_zynqmp_rpu.py
Normal file
|
@ -0,0 +1,208 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# (C) Copyright 2023, Advanced Micro Devices, Inc.
|
||||
|
||||
import pytest
|
||||
import random
|
||||
import string
|
||||
import test_net
|
||||
|
||||
"""
|
||||
Note: This test relies on boardenv_* containing configuration values to define
|
||||
RPU applications information for AMD's ZynqMP SoC which contains, application
|
||||
names, processors, address where it is built, expected output and the tftp load
|
||||
addresses. This test will be automatically skipped without this.
|
||||
|
||||
It also relies on dhcp or setup_static net test to support tftp to load
|
||||
application on DDR. All the environment parameters are stored sequentially.
|
||||
The length of all parameters values should be same. For example, if 2 app_names
|
||||
are defined in a list as a value of parameter 'app_name' then the other
|
||||
parameters value also should have a list with 2 items.
|
||||
It will run RPU cases for all the applications defined in boardenv_*
|
||||
configuration file.
|
||||
|
||||
Example:
|
||||
env__zynqmp_rpu_apps = {
|
||||
'app_name': ['hello_world_r5_0_ddr.elf', 'hello_world_r5_1_ddr.elf'],
|
||||
'proc': ['rpu0', 'rpu1'],
|
||||
'cpu_num': [4, 5],
|
||||
'addr': [0xA00000, 0xB00000],
|
||||
'output': ['Successfully ran Hello World application on DDR from RPU0',
|
||||
'Successfully ran Hello World application on DDR from RPU1'],
|
||||
'tftp_addr': [0x100000, 0x200000],
|
||||
}
|
||||
"""
|
||||
|
||||
# Get rpu apps params from env
|
||||
def get_rpu_apps_env(u_boot_console):
|
||||
rpu_apps = u_boot_console.config.env.get('env__zynqmp_rpu_apps', False)
|
||||
if not rpu_apps:
|
||||
pytest.skip('ZynqMP RPU application info not defined!')
|
||||
|
||||
apps = rpu_apps.get('app_name', None)
|
||||
if not apps:
|
||||
pytest.skip('No RPU application found!')
|
||||
|
||||
procs = rpu_apps.get('proc', None)
|
||||
if not procs:
|
||||
pytest.skip('No RPU application processor provided!')
|
||||
|
||||
cpu_nums = rpu_apps.get('cpu_num', None)
|
||||
if not cpu_nums:
|
||||
pytest.skip('No CPU number for respective processor provided!')
|
||||
|
||||
addrs = rpu_apps.get('addr', None)
|
||||
if not addrs:
|
||||
pytest.skip('No RPU application build address found!')
|
||||
|
||||
outputs = rpu_apps.get('output', None)
|
||||
if not outputs:
|
||||
pytest.skip('Expected output not found!')
|
||||
|
||||
tftp_addrs = rpu_apps.get('tftp_addr', None)
|
||||
if not tftp_addrs:
|
||||
pytest.skip('TFTP address to load application not found!')
|
||||
|
||||
return apps, procs, cpu_nums, addrs, outputs, tftp_addrs
|
||||
|
||||
# Check return code
|
||||
def ret_code(u_boot_console):
|
||||
return u_boot_console.run_command('echo $?')
|
||||
|
||||
# Initialize tcm
|
||||
def tcminit(u_boot_console, rpu_mode):
|
||||
output = u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode)
|
||||
assert 'Initializing TCM overwrites TCM content' in output
|
||||
return ret_code(u_boot_console)
|
||||
|
||||
# Load application in DDR
|
||||
def load_app_ddr(u_boot_console, tftp_addr, app):
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (tftp_addr, app))
|
||||
assert 'TIMEOUT' not in output
|
||||
assert 'Bytes transferred = ' in output
|
||||
|
||||
# Load elf
|
||||
u_boot_console.run_command('bootelf -p %x' % tftp_addr)
|
||||
assert ret_code(u_boot_console).endswith('0')
|
||||
|
||||
# Disable cpus
|
||||
def disable_cpus(u_boot_console, cpu_nums):
|
||||
for num in cpu_nums:
|
||||
u_boot_console.run_command(f'cpu {num} disable')
|
||||
|
||||
# Load apps on RPU cores
|
||||
def rpu_apps_load(u_boot_console, rpu_mode):
|
||||
apps, procs, cpu_nums, addrs, outputs, tftp_addrs = get_rpu_apps_env(
|
||||
u_boot_console)
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
try:
|
||||
assert tcminit(u_boot_console, rpu_mode).endswith('0')
|
||||
|
||||
for i in range(len(apps)):
|
||||
if rpu_mode == 'lockstep' and procs[i] != 'rpu0':
|
||||
continue
|
||||
|
||||
load_app_ddr(u_boot_console, tftp_addrs[i], apps[i])
|
||||
rel_addr = int(addrs[i] + 0x3C)
|
||||
|
||||
# Release cpu at app load address
|
||||
cpu_num = cpu_nums[i]
|
||||
cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode)
|
||||
output = u_boot_console.run_command(cmd)
|
||||
exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}'
|
||||
assert exp_op in output
|
||||
assert f'R5 {rpu_mode} mode' in output
|
||||
u_boot_console.wait_for(outputs[i])
|
||||
assert ret_code(u_boot_console).endswith('0')
|
||||
finally:
|
||||
disable_cpus(u_boot_console, cpu_nums)
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynqmp')
|
||||
def test_zynqmp_rpu_app_load_split(u_boot_console):
|
||||
rpu_apps_load(u_boot_console, 'split')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynqmp')
|
||||
def test_zynqmp_rpu_app_load_lockstep(u_boot_console):
|
||||
rpu_apps_load(u_boot_console, 'lockstep')
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynqmp')
|
||||
def test_zynqmp_rpu_app_load_negative(u_boot_console):
|
||||
apps, procs, cpu_nums, addrs, outputs, tftp_addrs = get_rpu_apps_env(
|
||||
u_boot_console)
|
||||
|
||||
# Invalid commands
|
||||
u_boot_console.run_command('zynqmp tcminit mode')
|
||||
assert ret_code(u_boot_console).endswith('1')
|
||||
|
||||
rand_str = ''.join(random.choices(string.ascii_lowercase, k=4))
|
||||
u_boot_console.run_command('zynqmp tcminit %s' % rand_str)
|
||||
assert ret_code(u_boot_console).endswith('1')
|
||||
|
||||
rand_num = random.randint(2, 100)
|
||||
u_boot_console.run_command('zynqmp tcminit %d' % rand_num)
|
||||
assert ret_code(u_boot_console).endswith('1')
|
||||
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
try:
|
||||
rpu_mode = 'split'
|
||||
assert tcminit(u_boot_console, rpu_mode).endswith('0')
|
||||
|
||||
for i in range(len(apps)):
|
||||
load_app_ddr(u_boot_console, tftp_addrs[i], apps[i])
|
||||
|
||||
# Run in split mode at different load address
|
||||
rel_addr = int(addrs[i]) + random.randint(200, 1000)
|
||||
cpu_num = cpu_nums[i]
|
||||
cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode)
|
||||
output = u_boot_console.run_command(cmd)
|
||||
exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}'
|
||||
assert exp_op in output
|
||||
assert f'R5 {rpu_mode} mode' in output
|
||||
assert not outputs[i] in output
|
||||
|
||||
# Invalid rpu mode
|
||||
rand_str = ''.join(random.choices(string.ascii_lowercase, k=4))
|
||||
cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rand_str)
|
||||
output = u_boot_console.run_command(cmd)
|
||||
assert exp_op in output
|
||||
assert f'Unsupported mode' in output
|
||||
assert not ret_code(u_boot_console).endswith('0')
|
||||
|
||||
# Switch to lockstep mode, without disabling CPUs
|
||||
rpu_mode = 'lockstep'
|
||||
u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode)
|
||||
assert not ret_code(u_boot_console).endswith('0')
|
||||
|
||||
# Disable cpus
|
||||
disable_cpus(u_boot_console, cpu_nums)
|
||||
|
||||
# Switch to lockstep mode, after disabling CPUs
|
||||
output = u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode)
|
||||
assert 'Initializing TCM overwrites TCM content' in output
|
||||
assert ret_code(u_boot_console).endswith('0')
|
||||
|
||||
# Run lockstep mode for RPU1
|
||||
for i in range(len(apps)):
|
||||
if procs[i] == 'rpu0':
|
||||
continue
|
||||
|
||||
load_app_ddr(u_boot_console, tftp_addrs[i], apps[i])
|
||||
rel_addr = int(addrs[i] + 0x3C)
|
||||
cpu_num = cpu_nums[i]
|
||||
cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode)
|
||||
output = u_boot_console.run_command(cmd)
|
||||
exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}'
|
||||
assert exp_op in output
|
||||
assert f'R5 {rpu_mode} mode' in output
|
||||
assert u_boot_console.p.expect([outputs[i]])
|
||||
finally:
|
||||
disable_cpus(u_boot_console, cpu_nums)
|
||||
# This forces the console object to be shutdown, so any subsequent test
|
||||
# will reset the board back into U-Boot.
|
||||
u_boot_console.drain_console()
|
||||
u_boot_console.cleanup_spawn()
|
104
test/py/tests/test_zynqmp_secure.py
Normal file
104
test/py/tests/test_zynqmp_secure.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# (C) Copyright 2023, Advanced Micro Devices, Inc.
|
||||
|
||||
import pytest
|
||||
import re
|
||||
import u_boot_utils
|
||||
import test_net
|
||||
|
||||
"""
|
||||
This test verifies different type of secure boot images loaded at the DDR for
|
||||
AMD's ZynqMP SoC.
|
||||
|
||||
Note: This test relies on boardenv_* containing configuration values to define
|
||||
the files to be used for testing. Without this, this test will be automatically
|
||||
skipped. It also relies on dhcp or setup_static net test to support tftp to
|
||||
load files from a TFTP server.
|
||||
|
||||
For example:
|
||||
|
||||
# Details regarding the files that may be read from a TFTP server. This
|
||||
# variable may be omitted or set to None if zynqmp secure testing is not
|
||||
# possible or desired.
|
||||
env__zynqmp_secure_readable_file = {
|
||||
'fn': 'auth_bhdr_ppk1.bin',
|
||||
'enckupfn': 'auth_bhdr_enc_kup_load.bin',
|
||||
'addr': 0x1000000,
|
||||
'keyaddr': 0x100000,
|
||||
'keyfn': 'aes.txt',
|
||||
}
|
||||
"""
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynqmp')
|
||||
def test_zynqmp_secure_boot_image(u_boot_console):
|
||||
"""This test verifies secure boot image at the DDR address for
|
||||
authentication only case.
|
||||
"""
|
||||
|
||||
f = u_boot_console.config.env.get('env__zynqmp_secure_readable_file', None)
|
||||
if not f:
|
||||
pytest.skip('No TFTP readable file for zynqmp secure cases to read')
|
||||
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
addr = f.get('addr', None)
|
||||
if not addr:
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
|
||||
expected_tftp = 'Bytes transferred = '
|
||||
fn = f['fn']
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
|
||||
assert expected_tftp in output
|
||||
|
||||
output = u_boot_console.run_command('zynqmp secure %x $filesize' % (addr))
|
||||
assert 'Verified image at' in output
|
||||
ver_addr = re.search(r'Verified image at 0x(.+)', output).group(1)
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
output = u_boot_console.run_command('print zynqmp_verified_img_addr')
|
||||
assert f'zynqmp_verified_img_addr={ver_addr}' in output
|
||||
assert 'Error' not in output
|
||||
|
||||
|
||||
@pytest.mark.buildconfigspec('cmd_zynqmp')
|
||||
def test_zynqmp_secure_boot_img_kup(u_boot_console):
|
||||
"""This test verifies secure boot image at the DDR address for encryption
|
||||
with kup key case.
|
||||
"""
|
||||
|
||||
f = u_boot_console.config.env.get('env__zynqmp_secure_readable_file', None)
|
||||
if not f:
|
||||
pytest.skip('No TFTP readable file for zynqmp secure cases to read')
|
||||
|
||||
test_net.test_net_dhcp(u_boot_console)
|
||||
if not test_net.net_set_up:
|
||||
test_net.test_net_setup_static(u_boot_console)
|
||||
|
||||
keyaddr = f.get('keyaddr', None)
|
||||
if not keyaddr:
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
expected_tftp = 'Bytes transferred = '
|
||||
keyfn = f['keyfn']
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (keyaddr, keyfn))
|
||||
assert expected_tftp in output
|
||||
|
||||
addr = f.get('addr', None)
|
||||
if not addr:
|
||||
addr = u_boot_utils.find_ram_base(u_boot_console)
|
||||
expected_tftp = 'Bytes transferred = '
|
||||
fn = f['enckupfn']
|
||||
output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn))
|
||||
assert expected_tftp in output
|
||||
|
||||
output = u_boot_console.run_command(
|
||||
'zynqmp secure %x $filesize %x' % (addr, keyaddr)
|
||||
)
|
||||
assert 'Verified image at' in output
|
||||
ver_addr = re.search(r'Verified image at 0x(.+)', output).group(1)
|
||||
output = u_boot_console.run_command('echo $?')
|
||||
assert output.endswith('0')
|
||||
output = u_boot_console.run_command('print zynqmp_verified_img_addr')
|
||||
assert f'zynqmp_verified_img_addr={ver_addr}' in output
|
||||
assert 'Error' not in output
|
Loading…
Add table
Reference in a new issue