[PATCH] test/py: nand: Add tests for NAND flash device
Love Kumar
love.kumar at amd.com
Fri Jan 19 15:26:19 CET 2024
Add tests for nand commands to test various NAND flash operations such
as erase, write and read.
Signed-off-by: Love Kumar <love.kumar at amd.com>
---
test/py/tests/test_nand.py | 201 +++++++++++++++++++++++++++++++++++++
1 file changed, 201 insertions(+)
create mode 100644 test/py/tests/test_nand.py
diff --git a/test/py/tests/test_nand.py b/test/py/tests/test_nand.py
new file mode 100644
index 000000000000..f5fd5d065cfe
--- /dev/null
+++ b/test/py/tests/test_nand.py
@@ -0,0 +1,201 @@
+# 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 relies on boardenv_* containing configuration values to define
+the nand device total size and timeout available for testing. Without this, the
+test will be automatically skipped. This test will be also skipped if the NAND
+flash device is not detected.
+
+For example:
+
+# Setup env__nand_device_test to set the NAND flash total size and timeout.
+env__nand_device_test = {
+ 'size': '8192 MB',
+ 'timeout': 100000,
+}
+"""
+
+# Find out nand memory parameters
+def nand_pre_commands(u_boot_console):
+ f = u_boot_console.config.env.get('env__nand_device_test', None)
+ if not f:
+ pytest.skip('No env file to read for NAND device test')
+
+ total_size = f.get('size', None)
+ timeout = f.get('timeout')
+
+ if not total_size:
+ pytest.skip('NAND device size not recognized')
+
+ output = u_boot_console.run_command('nand info')
+ if not 'Device 0: nand0' in output:
+ pytest.skip('No NAND device available')
+
+ m = re.search('Page size (.+?) b', output)
+ if m:
+ try:
+ page_size = int(m.group(1))
+ except ValueError:
+ pytest.fail('NAND page size not recognized')
+
+ m = re.search('sector size (.+?) KiB', output)
+ if m:
+ try:
+ erase_size = int(m.group(1))
+ sector_size = erase_size
+ except ValueError:
+ pytest.fail('NAND erase size not recognized')
+
+ erase_size *= 1024
+
+ output = u_boot_console.run_command('nand bad')
+ if not 'bad blocks:' in output:
+ pytest.skip('No NAND device available')
+
+ count = 0
+ m = re.search('bad blocks:([\n\s\s\d\w]*)', output)
+ if m:
+ print(m.group(1))
+ var = m.group(1).split()
+ count = len(var)
+ print('bad blocks count= ' + str(count))
+
+ m = re.search('(.+?) MB', total_size)
+ if m:
+ try:
+ total_size = int(m.group(1))
+ total_size *= 1024 * 1024
+ print('Total size is: ' + str(total_size) + ' B')
+ total_size -= count * sector_size * 1024
+ print('New Total size is: ' + str(total_size) + ' B')
+ except ValueError:
+ pytest.fail('NAND size not recognized')
+
+ return page_size, erase_size, total_size, sector_size, timeout
+
+ at pytest.mark.buildconfigspec('cmd_nand')
+ at pytest.mark.buildconfigspec('cmd_bdi')
+ at pytest.mark.buildconfigspec('cmd_memory')
+def test_nand_read_twice(u_boot_console):
+ """This test reads the whole NAND flash twice, random_size till full flash
+ size, random till page size.
+ """
+
+ page_size, erase_size, total_size, sector_size, timeout = nand_pre_commands(
+ u_boot_console)
+ expected_read = 'read: OK'
+
+ for size in random.randint(4, page_size), random.randint(4, total_size), total_size:
+ addr = u_boot_utils.find_ram_base(u_boot_console)
+
+ output = u_boot_console.run_command(
+ 'nand read %x 0 %x' % (addr + total_size, size)
+ )
+ assert expected_read in output
+
+ output = u_boot_console.run_command('crc32 %x %x' % (addr + total_size, size))
+ m = re.search('==> (.+?)', output)
+ if not m:
+ pytest.fail('CRC32 failed')
+ expected_crc32 = m.group(1)
+
+ output = u_boot_console.run_command(
+ 'nand read %x 0 %x' % (addr + total_size + 10, size)
+ )
+ assert expected_read in output
+
+ output = u_boot_console.run_command(
+ 'crc32 %x %x' % (addr + total_size + 10, size)
+ )
+ assert expected_crc32 in output
+
+ at pytest.mark.buildconfigspec('cmd_nand')
+ at pytest.mark.buildconfigspec('cmd_bdi')
+ at pytest.mark.buildconfigspec('cmd_memory')
+def test_nand_write_twice(u_boot_console):
+ """This test does the random writes till page size, size and full size"""
+
+ page_size, erase_size, total_size, sector_size, timeout = nand_pre_commands(
+ u_boot_console)
+ expected_write = 'written: OK'
+ expected_read = 'read: OK'
+ expected_erase = '100% complete.'
+ old_size = 0
+
+ for size in (
+ random.randint(4, page_size),
+ random.randint(page_size, total_size),
+ total_size,
+ ):
+ offset = page_size
+ addr = u_boot_utils.find_ram_base(u_boot_console)
+ size = size - old_size
+ output = u_boot_console.run_command('crc32 %x %x' % (addr + total_size, size))
+ m = re.search('==> (.+?)', output)
+ if not m:
+ pytest.fail('CRC32 failed')
+
+ expected_crc32 = m.group(1)
+
+ if old_size % page_size:
+ old_size = int(old_size / page_size + 1)
+ old_size *= page_size
+
+ if old_size + size > total_size:
+ size = total_size - old_size
+
+ eraseoffset = int(old_size / erase_size)
+ eraseoffset *= erase_size
+
+ erasesize = int(size / erase_size + 1)
+ erasesize *= erase_size
+
+ output = u_boot_console.run_command(
+ 'nand erase.spread %x %x' % (eraseoffset, erasesize)
+ )
+ assert expected_erase in output
+
+ output = u_boot_console.run_command(
+ 'nand write %x %x %x' % (addr + total_size, old_size, size)
+ )
+ assert expected_write in output
+ output = u_boot_console.run_command(
+ 'nand read %x %x %x' % (addr + total_size + offset, old_size, size)
+ )
+ assert expected_read in output
+ output = u_boot_console.run_command(
+ 'crc32 %x %x' % (addr + total_size + offset, size)
+ )
+ assert expected_crc32 in output
+ old_size = size
+
+ at pytest.mark.buildconfigspec('cmd_nand')
+def test_nand_erase_block(u_boot_console):
+ page_size, erase_size, total_size, sector_size, timeout = nand_pre_commands(
+ u_boot_console)
+
+ expected_erase = '100% complete.'
+ for start in range(0, total_size, erase_size):
+ output = u_boot_console.run_command(
+ 'nand erase.spread %x %x' % (start, erase_size)
+ )
+ assert expected_erase in output
+
+ at pytest.mark.buildconfigspec('cmd_nand')
+def test_nand_erase_all(u_boot_console):
+ page_size, erase_size, total_size, sector_size, timeout = nand_pre_commands(
+ u_boot_console)
+
+ expected_erase = '100% complete.'
+ start = 0
+ with u_boot_console.temporary_timeout(timeout):
+ output = u_boot_console.run_command(
+ 'nand erase.spread 0 ' + str(hex(total_size))
+ )
+ assert expected_erase in output
--
2.25.1
More information about the U-Boot
mailing list