[U-Boot] [PATCH 3/3] test/py: add spi_flash tests
Liam Beguin
liambeguin at gmail.com
Tue Feb 27 04:17:46 UTC 2018
Add basic tests for the spi_flash subsystem.
Signed-off-by: Liam Beguin <liambeguin at gmail.com>
---
test/py/tests/test_sf.py | 233 +++++++++++++++++++++++++++++++++++++++
1 file changed, 233 insertions(+)
diff --git a/test/py/tests/test_sf.py b/test/py/tests/test_sf.py
new file mode 100644
index 000000000000..7017d8072ea9
--- /dev/null
+++ b/test/py/tests/test_sf.py
@@ -0,0 +1,233 @@
+# Copyright (c) 2017, Xiphos Systems Corp. All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0
+
+import re
+import pytest
+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:
+
+# Boolean indicating whether the SF tests should be skipped.
+env__sf_skip = False
+
+# A list of sections of flash memory to be tested.
+env__sf_configs = (
+ {
+ # Optional, [[bus:]cs] argument used in `sf probe`
+ 'id': "0",
+ # Where in SPI flash should the test operate.
+ 'offset': 0x00000000,
+ # 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,
+ # Specifies if the test can write to offset
+ 'writeable': False,
+ },
+)
+"""
+
+
+def sf_prepare(u_boot_console, env__sf_config, verbose=False):
+ """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:
+ Nothing.
+ """
+
+ if u_boot_console.config.env.get('env__sf_skip', True):
+ pytest.skip('sf test disabled in environment')
+
+ # NOTE: sf read at address 0 fails because map_physmem 'converts' it
+ # address 0 to a pointer.
+ ram_address = u_boot_utils.find_ram_base(u_boot_console) + 0x10
+
+ probe_id = env__sf_config.get('id', '')
+ output = u_boot_console.run_command('sf probe ' + probe_id)
+ if 'SF: Detected' not in output:
+ pytest.fail('No flash device available')
+
+ m = re.search('page size (.+?) Bytes', output)
+ if m:
+ try:
+ page_size = int(m.group(1))
+ except ValueError:
+ pytest.fail('SPI Flash page size not recognized')
+
+ m = re.search('erase size (.+?) KiB', output)
+ if m:
+ try:
+ erase_size = int(m.group(1))
+ except ValueError:
+ pytest.fail('SPI Flash erase size not recognized')
+
+ erase_size *= 1024
+
+ m = re.search('total (.+?) MiB', output)
+ if m:
+ try:
+ total_size = int(m.group(1))
+ except ValueError:
+ pytest.fail('SPI Flash total size not recognized')
+
+ total_size *= 1024 * 1024
+
+ if verbose:
+ u_boot_console.log.info('Page size is: ' + str(page_size) + ' B')
+ u_boot_console.log.info('Erase size is: ' + str(erase_size) + ' B')
+ u_boot_console.log.info('Total size is: ' + str(total_size) + ' B')
+
+ env__sf_config['len'] = env__sf_config.get('len', erase_size)
+ if env__sf_config['offset'] % erase_size or \
+ env__sf_config['len'] % erase_size:
+ u_boot_console.log.warning("erase offset/length not multiple of "
+ "erase size")
+
+ env__sf_config['ram_address'] = ram_address
+
+
+def crc32(u_boot_console, address, count):
+ """Helper function used to compute the CRC32 value of a section of RAM.
+
+ Args:
+ u_boot_console: A U-Boot console connection.
+ address: Address where data starts.
+ count: Amount of data to use for calculation.
+
+ Returns:
+ CRC32 value
+ """
+
+ output = u_boot_console.run_command('crc32 %08x %x' % (address, count))
+
+ m = re.search('==> ([0-9a-fA-F]{8})$', output)
+ if not m:
+ pytest.fail('CRC32 failed')
+
+ return m.group(1)
+
+
+def sf_read(u_boot_console, env__sf_config, size=None):
+ """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.
+ size: Optional, used to override env__sf_config value.
+
+ Returns:
+ CRC32 value of SPI Flash section
+ """
+
+ if size is None:
+ size = env__sf_config['len']
+
+ u_boot_console.run_command('mw %08x 0 %x' % (env__sf_config['ram_address'],
+ size))
+
+ response = u_boot_console.run_command('sf read %08x %08x %x' %
+ (env__sf_config['ram_address'],
+ env__sf_config['offset'],
+ size))
+ assert 'Read: OK' in response, "Read operation failed"
+
+ return crc32(u_boot_console, env__sf_config['ram_address'],
+ env__sf_config['len'])
+
+
+def sf_update(u_boot_console, env__sf_config):
+ """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
+ """
+ from time import time
+
+ u_boot_console.run_command('mw %08x %08x %x' %
+ (env__sf_config['ram_address'], time(),
+ env__sf_config['len']))
+ crc_ram = crc32(u_boot_console, env__sf_config['ram_address'],
+ env__sf_config['len'])
+ u_boot_console.run_command('sf update %08x %08x %x' %
+ (env__sf_config['ram_address'],
+ env__sf_config['offset'],
+ env__sf_config['len']))
+
+ crc2 = sf_read(u_boot_console, env__sf_config)
+
+ return (crc2 == crc_ram)
+
+
+ at pytest.mark.buildconfigspec("cmd_sf")
+def test_sf_read(u_boot_console, env__sf_config):
+ sf_prepare(u_boot_console, env__sf_config)
+
+ output = u_boot_console.run_command('sf read %08x %08x %x' %
+ (env__sf_config['ram_address'],
+ env__sf_config['offset'],
+ env__sf_config['len']))
+ assert 'Read: OK' in output, "Read operation failed"
+
+
+ at pytest.mark.buildconfigspec("cmd_sf")
+ at pytest.mark.buildconfigspec("cmd_crc32")
+ at pytest.mark.buildconfigspec("cmd_memory")
+def test_sf_read_twice(u_boot_console, env__sf_config):
+ sf_prepare(u_boot_console, env__sf_config)
+
+ crc1 = sf_read(u_boot_console, env__sf_config)
+ crc2 = sf_read(u_boot_console, env__sf_config)
+
+ assert crc1 == crc2, "CRC32 of two successive read operation do not match"
+
+
+ at pytest.mark.buildconfigspec("cmd_sf")
+ at pytest.mark.buildconfigspec("cmd_crc32")
+ at pytest.mark.buildconfigspec("cmd_memory")
+def test_sf_erase(u_boot_console, env__sf_config):
+ if not env__sf_config['writeable']:
+ pytest.skip('flash config is tagged as not writeable')
+
+ sf_prepare(u_boot_console, env__sf_config)
+ output = u_boot_console.run_command('sf erase %08x %x' %
+ (env__sf_config['offset'],
+ env__sf_config['len']))
+ assert 'Erased: OK' in output, "Erase operation failed"
+
+ u_boot_console.run_command('mw %08x ffffffff %x' %
+ (env__sf_config['ram_address'],
+ env__sf_config['len']))
+ crc1 = crc32(u_boot_console, env__sf_config['ram_address'],
+ env__sf_config['len'])
+
+ crc2 = sf_read(u_boot_console, env__sf_config)
+ assert crc1 == crc2, "CRC32 of erase section does not match expected value"
+
+
+ at pytest.mark.buildconfigspec("cmd_sf")
+ at pytest.mark.buildconfigspec("cmd_memory")
+def test_sf_update(u_boot_console, env__sf_config):
+ if not env__sf_config['writeable']:
+ pytest.skip('flash config is tagged as not writeable')
+
+ sf_prepare(u_boot_console, env__sf_config)
+ assert sf_update(u_boot_console, env__sf_config) is True
--
2.16.1.72.g5be1f00a9a70
More information about the U-Boot
mailing list