1# SPDX-License-Identifier: GPL-2.0 2# Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. 3 4# Test U-Boot's "mmc read" command. The test reads data from the eMMC or SD 5# card, and validates the no errors occurred, and that the expected data was 6# read if the test configuration contains a CRC of the expected data. 7 8import pytest 9import time 10import u_boot_utils 11 12""" 13This test relies on boardenv_* to containing configuration values to define 14which MMC devices should be tested. For example: 15 16# Configuration data for test_mmc_dev, test_mmc_rescan, test_mmc_info; defines 17# whole MMC devices that mmc dev/rescan/info commands may operate upon. 18env__mmc_dev_configs = ( 19 { 20 'fixture_id': 'emmc-boot0', 21 'is_emmc': True, 22 'devid': 0, 23 'partid': 1, 24 'info_device': ???, 25 'info_speed': ???, 26 'info_mode': ???, 27 'info_buswidth': ???. 28 }, 29 { 30 'fixture_id': 'emmc-boot1', 31 'is_emmc': True, 32 'devid': 0, 33 'partid': 2, 34 'info_device': ???, 35 'info_speed': ???, 36 'info_mode': ???, 37 'info_buswidth': ???. 38 }, 39 { 40 'fixture_id': 'emmc-data', 41 'is_emmc': True, 42 'devid': 0, 43 'partid': 0, 44 'info_device': ???, 45 'info_speed': ???, 46 'info_mode': ???, 47 'info_buswidth': ???. 48 }, 49 { 50 'fixture_id': 'sd', 51 'is_emmc': False, 52 'devid': 1, 53 'partid': None, 54 'info_device': ???, 55 'info_speed': ???, 56 'info_mode': ???, 57 'info_buswidth': ???. 58 }, 59) 60 61# Configuration data for test_mmc_rd; defines regions of the MMC (entire 62# devices, or ranges of sectors) which can be read: 63env__mmc_rd_configs = ( 64 { 65 'fixture_id': 'emmc-boot0', 66 'is_emmc': True, 67 'devid': 0, 68 'partid': 1, 69 'sector': 0x10, 70 'count': 1, 71 }, 72 { 73 'fixture_id': 'emmc-boot1', 74 'is_emmc': True, 75 'devid': 0, 76 'partid': 2, 77 'sector': 0x10, 78 'count': 1, 79 }, 80 { 81 'fixture_id': 'emmc-data', 82 'is_emmc': True, 83 'devid': 0, 84 'partid': 0, 85 'sector': 0x10, 86 'count': 0x1000, 87 }, 88 { 89 'fixture_id': 'sd-mbr', 90 'is_emmc': False, 91 'devid': 1, 92 'partid': None, 93 'sector': 0, 94 'count': 1, 95 'crc32': '8f6ecf0d', 96 }, 97 { 98 'fixture_id': 'sd-large', 99 'is_emmc': False, 100 'devid': 1, 101 'partid': None, 102 'sector': 0x10, 103 'count': 0x1000, 104 }, 105) 106""" 107 108def mmc_dev(u_boot_console, is_emmc, devid, partid): 109 """Run the "mmc dev" command. 110 111 Args: 112 u_boot_console: A U-Boot console connection. 113 is_emmc: Whether the device is eMMC 114 devid: Device ID 115 partid: Partition ID 116 117 Returns: 118 Nothing. 119 """ 120 121 # Select MMC device 122 cmd = 'mmc dev %d' % devid 123 if is_emmc: 124 cmd += ' %d' % partid 125 response = u_boot_console.run_command(cmd) 126 assert 'no card present' not in response 127 if is_emmc: 128 partid_response = '(part %d)' % partid 129 else: 130 partid_response = '' 131 good_response = 'mmc%d%s is current device' % (devid, partid_response) 132 assert good_response in response 133 134@pytest.mark.buildconfigspec('cmd_mmc') 135def test_mmc_dev(u_boot_console, env__mmc_dev_config): 136 """Test the "mmc dev" command. 137 138 Args: 139 u_boot_console: A U-Boot console connection. 140 env__mmc_dev_config: The single MMC configuration on which 141 to run the test. See the file-level comment above for details 142 of the format. 143 144 Returns: 145 Nothing. 146 """ 147 148 is_emmc = env__mmc_dev_config['is_emmc'] 149 devid = env__mmc_dev_config['devid'] 150 partid = env__mmc_dev_config.get('partid', 0) 151 152 # Select MMC device 153 mmc_dev(u_boot_console, is_emmc, devid, partid) 154 155@pytest.mark.buildconfigspec('cmd_mmc') 156def test_mmc_rescan(u_boot_console, env__mmc_dev_config): 157 """Test the "mmc rescan" command. 158 159 Args: 160 u_boot_console: A U-Boot console connection. 161 env__mmc_dev_config: The single MMC configuration on which 162 to run the test. See the file-level comment above for details 163 of the format. 164 165 Returns: 166 Nothing. 167 """ 168 169 is_emmc = env__mmc_dev_config['is_emmc'] 170 devid = env__mmc_dev_config['devid'] 171 partid = env__mmc_dev_config.get('partid', 0) 172 173 # Select MMC device 174 mmc_dev(u_boot_console, is_emmc, devid, partid) 175 176 # Rescan MMC device 177 cmd = 'mmc rescan' 178 response = u_boot_console.run_command(cmd) 179 assert 'no card present' not in response 180 181@pytest.mark.buildconfigspec('cmd_mmc') 182def test_mmc_info(u_boot_console, env__mmc_dev_config): 183 """Test the "mmc info" command. 184 185 Args: 186 u_boot_console: A U-Boot console connection. 187 env__mmc_dev_config: The single MMC configuration on which 188 to run the test. See the file-level comment above for details 189 of the format. 190 191 Returns: 192 Nothing. 193 """ 194 195 is_emmc = env__mmc_dev_config['is_emmc'] 196 devid = env__mmc_dev_config['devid'] 197 partid = env__mmc_dev_config.get('partid', 0) 198 info_device = env__mmc_dev_config['info_device'] 199 info_speed = env__mmc_dev_config['info_speed'] 200 info_mode = env__mmc_dev_config['info_mode'] 201 info_buswidth = env__mmc_dev_config['info_buswidth'] 202 203 # Select MMC device 204 mmc_dev(u_boot_console, is_emmc, devid, partid) 205 206 # Read MMC device information 207 cmd = 'mmc info' 208 response = u_boot_console.run_command(cmd) 209 good_response = "Device: %s" % info_device 210 assert good_response in response 211 good_response = "Bus Speed: %s" % info_speed 212 assert good_response in response 213 good_response = "Mode: %s" % info_mode 214 assert good_response in response 215 good_response = "Bus Width: %s" % info_buswidth 216 assert good_response in response 217 218@pytest.mark.buildconfigspec('cmd_mmc') 219def test_mmc_rd(u_boot_console, env__mmc_rd_config): 220 """Test the "mmc read" command. 221 222 Args: 223 u_boot_console: A U-Boot console connection. 224 env__mmc_rd_config: The single MMC configuration on which 225 to run the test. See the file-level comment above for details 226 of the format. 227 228 Returns: 229 Nothing. 230 """ 231 232 is_emmc = env__mmc_rd_config['is_emmc'] 233 devid = env__mmc_rd_config['devid'] 234 partid = env__mmc_rd_config.get('partid', 0) 235 sector = env__mmc_rd_config.get('sector', 0) 236 count_sectors = env__mmc_rd_config.get('count', 1) 237 expected_crc32 = env__mmc_rd_config.get('crc32', None) 238 read_duration_max = env__mmc_rd_config.get('read_duration_max', 0) 239 240 count_bytes = count_sectors * 512 241 bcfg = u_boot_console.config.buildconfig 242 has_cmd_memory = bcfg.get('config_cmd_memory', 'n') == 'y' 243 has_cmd_crc32 = bcfg.get('config_cmd_crc32', 'n') == 'y' 244 ram_base = u_boot_utils.find_ram_base(u_boot_console) 245 addr = '0x%08x' % ram_base 246 247 # Select MMC device 248 mmc_dev(u_boot_console, is_emmc, devid, partid) 249 250 # Clear target RAM 251 if expected_crc32: 252 if has_cmd_memory and has_cmd_crc32: 253 cmd = 'mw.b %s 0 0x%x' % (addr, count_bytes) 254 u_boot_console.run_command(cmd) 255 256 cmd = 'crc32 %s 0x%x' % (addr, count_bytes) 257 response = u_boot_console.run_command(cmd) 258 assert expected_crc32 not in response 259 else: 260 u_boot_console.log.warning( 261 'CONFIG_CMD_MEMORY or CONFIG_CMD_CRC32 != y: Skipping RAM clear') 262 263 # Read data 264 cmd = 'mmc read %s %x %x' % (addr, sector, count_sectors) 265 tstart = time.time() 266 response = u_boot_console.run_command(cmd) 267 tend = time.time() 268 good_response = 'MMC read: dev # %d, block # %d, count %d ... %d blocks read: OK' % ( 269 devid, sector, count_sectors, count_sectors) 270 assert good_response in response 271 272 # Check target RAM 273 if expected_crc32: 274 if has_cmd_crc32: 275 cmd = 'crc32 %s 0x%x' % (addr, count_bytes) 276 response = u_boot_console.run_command(cmd) 277 assert expected_crc32 in response 278 else: 279 u_boot_console.log.warning('CONFIG_CMD_CRC32 != y: Skipping check') 280 281 # Check if the command did not take too long 282 if read_duration_max: 283 elapsed = tend - tstart 284 u_boot_console.log.info('Reading %d bytes took %f seconds' % 285 (count_bytes, elapsed)) 286 assert elapsed <= (read_duration_max - 0.01) 287