83d290c56f
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
218 lines
7.6 KiB
Python
218 lines
7.6 KiB
Python
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (c) 2016, Xilinx Inc. Michal Simek
|
|
# Copyright (c) 2017, Xiphos Systems Corp. All rights reserved.
|
|
|
|
import re
|
|
import pytest
|
|
import random
|
|
import u_boot_utils
|
|
|
|
"""
|
|
Note: This test relies on boardenv_* containing configuration values to define
|
|
which SPI Flash areas are available for testing. Without this, this test will
|
|
be automatically skipped.
|
|
For example:
|
|
|
|
# A list of sections of Flash memory to be tested.
|
|
env__sf_configs = (
|
|
{
|
|
# Where in SPI Flash should the test operate.
|
|
'offset': 0x00000000,
|
|
# This value is optional.
|
|
# If present, specifies the [[bus:]cs] argument used in `sf probe`
|
|
# If missing, defaults to 0.
|
|
'id': '0:1',
|
|
# This value is optional.
|
|
# If set as a number, specifies the speed of the SPI Flash.
|
|
# If set as an array of 2, specifies a range for a random speed.
|
|
# If missing, defaults to 0.
|
|
'speed': 1000000,
|
|
# This value is optional.
|
|
# If present, specifies the size to use for read/write operations.
|
|
# If missing, the SPI Flash page size is used as a default (based on
|
|
# the `sf probe` output).
|
|
'len': 0x10000,
|
|
# This value is optional.
|
|
# If present, specifies if the test can write to Flash offset
|
|
# If missing, defaults to False.
|
|
'writeable': False,
|
|
# This value is optional.
|
|
# If present, specifies the expected CRC32 value of the flash area.
|
|
# If missing, extra check is ignored.
|
|
'crc32': 0xCAFECAFE,
|
|
},
|
|
)
|
|
"""
|
|
|
|
def sf_prepare(u_boot_console, env__sf_config):
|
|
"""Check global state of the SPI Flash before running any test.
|
|
|
|
Args:
|
|
u_boot_console: A U-Boot console connection.
|
|
env__sf_config: The single SPI Flash device configuration on which to
|
|
run the tests.
|
|
|
|
Returns:
|
|
sf_params: a dictionary of SPI Flash parameters.
|
|
"""
|
|
|
|
sf_params = {}
|
|
sf_params['ram_base'] = u_boot_utils.find_ram_base(u_boot_console)
|
|
|
|
probe_id = env__sf_config.get('id', 0)
|
|
speed = env__sf_config.get('speed', 0)
|
|
if isinstance(speed, int):
|
|
sf_params['speed'] = speed
|
|
else:
|
|
assert len(speed) == 2, "If speed is a list, it must have 2 entries"
|
|
sf_params['speed'] = random.randint(speed[0], speed[1])
|
|
|
|
cmd = 'sf probe %d %d' % (probe_id, sf_params['speed'])
|
|
|
|
output = u_boot_console.run_command(cmd)
|
|
assert 'SF: Detected' in output, 'No Flash device available'
|
|
|
|
m = re.search('page size (.+?) Bytes', output)
|
|
assert m, 'SPI Flash page size not recognized'
|
|
sf_params['page_size'] = int(m.group(1))
|
|
|
|
m = re.search('erase size (.+?) KiB', output)
|
|
assert m, 'SPI Flash erase size not recognized'
|
|
sf_params['erase_size'] = int(m.group(1))
|
|
sf_params['erase_size'] *= 1024
|
|
|
|
m = re.search('total (.+?) MiB', output)
|
|
assert m, 'SPI Flash total size not recognized'
|
|
sf_params['total_size'] = int(m.group(1))
|
|
sf_params['total_size'] *= 1024 * 1024
|
|
|
|
assert 'offset' in env__sf_config, \
|
|
'\'offset\' is required for this test.'
|
|
sf_params['len'] = env__sf_config.get('len', sf_params['erase_size'])
|
|
|
|
assert not env__sf_config['offset'] % sf_params['erase_size'], \
|
|
'offset not multiple of erase size.'
|
|
assert not sf_params['len'] % sf_params['erase_size'], \
|
|
'erase length not multiple of erase size.'
|
|
|
|
assert not (env__sf_config.get('writeable', False) and
|
|
'crc32' in env__sf_config), \
|
|
'Cannot check crc32 on writeable sections'
|
|
|
|
return sf_params
|
|
|
|
def sf_read(u_boot_console, env__sf_config, sf_params):
|
|
"""Helper function used to read and compute the CRC32 value of a section of
|
|
SPI Flash memory.
|
|
|
|
Args:
|
|
u_boot_console: A U-Boot console connection.
|
|
env__sf_config: The single SPI Flash device configuration on which to
|
|
run the tests.
|
|
sf_params: SPI Flash parameters.
|
|
|
|
Returns:
|
|
CRC32 value of SPI Flash section
|
|
"""
|
|
|
|
addr = sf_params['ram_base']
|
|
offset = env__sf_config['offset']
|
|
count = sf_params['len']
|
|
pattern = random.randint(0, 0xFF)
|
|
crc_expected = env__sf_config.get('crc32', None)
|
|
|
|
cmd = 'mw.b %08x %02x %x' % (addr, pattern, count)
|
|
u_boot_console.run_command(cmd)
|
|
crc_pattern = u_boot_utils.crc32(u_boot_console, addr, count)
|
|
if crc_expected:
|
|
assert crc_pattern != crc_expected
|
|
|
|
cmd = 'sf read %08x %08x %x' % (addr, offset, count)
|
|
response = u_boot_console.run_command(cmd)
|
|
assert 'Read: OK' in response, 'Read operation failed'
|
|
crc_readback = u_boot_utils.crc32(u_boot_console, addr, count)
|
|
assert crc_pattern != crc_readback, 'sf read did not update RAM content.'
|
|
if crc_expected:
|
|
assert crc_readback == crc_expected
|
|
|
|
return crc_readback
|
|
|
|
def sf_update(u_boot_console, env__sf_config, sf_params):
|
|
"""Helper function used to update a section of SPI Flash memory.
|
|
|
|
Args:
|
|
u_boot_console: A U-Boot console connection.
|
|
env__sf_config: The single SPI Flash device configuration on which to
|
|
run the tests.
|
|
|
|
Returns:
|
|
CRC32 value of SPI Flash section
|
|
"""
|
|
|
|
addr = sf_params['ram_base']
|
|
offset = env__sf_config['offset']
|
|
count = sf_params['len']
|
|
pattern = int(random.random() * 0xFF)
|
|
|
|
cmd = 'mw.b %08x %02x %x' % (addr, pattern, count)
|
|
u_boot_console.run_command(cmd)
|
|
crc_pattern = u_boot_utils.crc32(u_boot_console, addr, count)
|
|
|
|
cmd = 'sf update %08x %08x %x' % (addr, offset, count)
|
|
u_boot_console.run_command(cmd)
|
|
crc_readback = sf_read(u_boot_console, env__sf_config, sf_params)
|
|
|
|
assert crc_readback == crc_pattern
|
|
|
|
@pytest.mark.buildconfigspec('cmd_sf')
|
|
@pytest.mark.buildconfigspec('cmd_crc32')
|
|
@pytest.mark.buildconfigspec('cmd_memory')
|
|
def test_sf_read(u_boot_console, env__sf_config):
|
|
sf_params = sf_prepare(u_boot_console, env__sf_config)
|
|
sf_read(u_boot_console, env__sf_config, sf_params)
|
|
|
|
@pytest.mark.buildconfigspec('cmd_sf')
|
|
@pytest.mark.buildconfigspec('cmd_crc32')
|
|
@pytest.mark.buildconfigspec('cmd_memory')
|
|
def test_sf_read_twice(u_boot_console, env__sf_config):
|
|
sf_params = sf_prepare(u_boot_console, env__sf_config)
|
|
|
|
crc1 = sf_read(u_boot_console, env__sf_config, sf_params)
|
|
sf_params['ram_base'] += 0x100
|
|
crc2 = sf_read(u_boot_console, env__sf_config, sf_params)
|
|
|
|
assert crc1 == crc2, 'CRC32 of two successive read operation do not match'
|
|
|
|
@pytest.mark.buildconfigspec('cmd_sf')
|
|
@pytest.mark.buildconfigspec('cmd_crc32')
|
|
@pytest.mark.buildconfigspec('cmd_memory')
|
|
def test_sf_erase(u_boot_console, env__sf_config):
|
|
if not env__sf_config.get('writeable', False):
|
|
pytest.skip('Flash config is tagged as not writeable')
|
|
|
|
sf_params = sf_prepare(u_boot_console, env__sf_config)
|
|
addr = sf_params['ram_base']
|
|
offset = env__sf_config['offset']
|
|
count = sf_params['len']
|
|
|
|
cmd = 'sf erase %08x %x' % (offset, count)
|
|
output = u_boot_console.run_command(cmd)
|
|
assert 'Erased: OK' in output, 'Erase operation failed'
|
|
|
|
cmd = 'mw.b %08x ff %x' % (addr, count)
|
|
u_boot_console.run_command(cmd)
|
|
crc_ffs = u_boot_utils.crc32(u_boot_console, addr, count)
|
|
|
|
crc_read = sf_read(u_boot_console, env__sf_config, sf_params)
|
|
assert crc_ffs == crc_read, 'Unexpected CRC32 after erase operation.'
|
|
|
|
@pytest.mark.buildconfigspec('cmd_sf')
|
|
@pytest.mark.buildconfigspec('cmd_crc32')
|
|
@pytest.mark.buildconfigspec('cmd_memory')
|
|
def test_sf_update(u_boot_console, env__sf_config):
|
|
if not env__sf_config.get('writeable', False):
|
|
pytest.skip('Flash config is tagged as not writeable')
|
|
|
|
sf_params = sf_prepare(u_boot_console, env__sf_config)
|
|
sf_update(u_boot_console, env__sf_config, sf_params)
|