test/py: mmc: Add 'mmc read' performance check
[oweals/u-boot.git] / test / py / tests / test_mmc_rd.py
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
8 import pytest
9 import time
10 import u_boot_utils
11
12 """
13 This test relies on boardenv_* to containing configuration values to define
14 which MMC devices should be tested. For example:
15
16 env__mmc_rd_configs = (
17     {
18         'fixture_id': 'emmc-boot0',
19         'is_emmc': True,
20         'devid': 0,
21         'partid': 1,
22         'sector': 0x10,
23         'count': 1,
24     },
25     {
26         'fixture_id': 'emmc-boot1',
27         'is_emmc': True,
28         'devid': 0,
29         'partid': 2,
30         'sector': 0x10,
31         'count': 1,
32     },
33     {
34         'fixture_id': 'emmc-data',
35         'is_emmc': True,
36         'devid': 0,
37         'partid': 0,
38         'sector': 0x10,
39         'count': 0x1000,
40     },
41     {
42         'fixture_id': 'sd-mbr',
43         'is_emmc': False,
44         'devid': 1,
45         'partid': None,
46         'sector': 0,
47         'count': 1,
48         'crc32': '8f6ecf0d',
49     },
50     {
51         'fixture_id': 'sd-large',
52         'is_emmc': False,
53         'devid': 1,
54         'partid': None,
55         'sector': 0x10,
56         'count': 0x1000,
57     },
58 )
59 """
60
61 def mmc_dev(u_boot_console, is_emmc, devid, partid):
62     """Run the "mmc dev" command.
63
64     Args:
65         u_boot_console: A U-Boot console connection.
66         is_emmc: Whether the device is eMMC
67         devid: Device ID
68         partid: Partition ID
69
70     Returns:
71         Nothing.
72     """
73
74     # Select MMC device
75     cmd = 'mmc dev %d' % devid
76     if is_emmc:
77         cmd += ' %d' % partid
78     response = u_boot_console.run_command(cmd)
79     assert 'no card present' not in response
80     if is_emmc:
81         partid_response = '(part %d)' % partid
82     else:
83         partid_response = ''
84     good_response = 'mmc%d%s is current device' % (devid, partid_response)
85     assert good_response in response
86
87 @pytest.mark.buildconfigspec('cmd_mmc')
88 def test_mmc_dev(u_boot_console, env__mmc_rd_config):
89     """Test the "mmc dev" command.
90
91     Args:
92         u_boot_console: A U-Boot console connection.
93         env__mmc_rd_config: The single MMC configuration on which
94             to run the test. See the file-level comment above for details
95             of the format.
96
97     Returns:
98         Nothing.
99     """
100
101     is_emmc = env__mmc_rd_config['is_emmc']
102     devid = env__mmc_rd_config['devid']
103     partid = env__mmc_rd_config.get('partid', 0)
104
105     # Select MMC device
106     mmc_dev(u_boot_console, is_emmc, devid, partid)
107
108 @pytest.mark.buildconfigspec('cmd_mmc')
109 def test_mmc_rescan(u_boot_console, env__mmc_rd_config):
110     """Test the "mmc rescan" command.
111
112     Args:
113         u_boot_console: A U-Boot console connection.
114         env__mmc_rd_config: The single MMC configuration on which
115             to run the test. See the file-level comment above for details
116             of the format.
117
118     Returns:
119         Nothing.
120     """
121
122     is_emmc = env__mmc_rd_config['is_emmc']
123     devid = env__mmc_rd_config['devid']
124     partid = env__mmc_rd_config.get('partid', 0)
125
126     # Select MMC device
127     mmc_dev(u_boot_console, is_emmc, devid, partid)
128
129     # Rescan MMC device
130     cmd = 'mmc rescan'
131     response = u_boot_console.run_command(cmd)
132     assert 'no card present' not in response
133
134 @pytest.mark.buildconfigspec('cmd_mmc')
135 def test_mmc_info(u_boot_console, env__mmc_rd_config):
136     """Test the "mmc info" command.
137
138     Args:
139         u_boot_console: A U-Boot console connection.
140         env__mmc_rd_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_rd_config['is_emmc']
149     devid = env__mmc_rd_config['devid']
150     partid = env__mmc_rd_config.get('partid', 0)
151     info_device = env__mmc_rd_config['info_device']
152     info_speed = env__mmc_rd_config['info_speed']
153     info_mode = env__mmc_rd_config['info_mode']
154     info_buswidth = env__mmc_rd_config['info_buswidth']
155
156     # Select MMC device
157     mmc_dev(u_boot_console, is_emmc, devid, partid)
158
159     # Read MMC device information
160     cmd = 'mmc info'
161     response = u_boot_console.run_command(cmd)
162     good_response = "Device: %s" % info_device
163     assert good_response in response
164     good_response = "Bus Speed: %s" % info_speed
165     assert good_response in response
166     good_response = "Mode : %s" % info_mode
167     assert good_response in response
168     good_response = "Bus Width: %s" % info_buswidth
169     assert good_response in response
170
171 @pytest.mark.buildconfigspec('cmd_mmc')
172 def test_mmc_rd(u_boot_console, env__mmc_rd_config):
173     """Test the "mmc read" command.
174
175     Args:
176         u_boot_console: A U-Boot console connection.
177         env__mmc_rd_config: The single MMC configuration on which
178             to run the test. See the file-level comment above for details
179             of the format.
180
181     Returns:
182         Nothing.
183     """
184
185     is_emmc = env__mmc_rd_config['is_emmc']
186     devid = env__mmc_rd_config['devid']
187     partid = env__mmc_rd_config.get('partid', 0)
188     sector = env__mmc_rd_config.get('sector', 0)
189     count_sectors = env__mmc_rd_config.get('count', 1)
190     expected_crc32 = env__mmc_rd_config.get('crc32', None)
191     read_duration_max = env__mmc_rd_config.get('read_duration_max', 0)
192
193     count_bytes = count_sectors * 512
194     bcfg = u_boot_console.config.buildconfig
195     has_cmd_memory = bcfg.get('config_cmd_memory', 'n') == 'y'
196     has_cmd_crc32 = bcfg.get('config_cmd_crc32', 'n') == 'y'
197     ram_base = u_boot_utils.find_ram_base(u_boot_console)
198     addr = '0x%08x' % ram_base
199
200     # Select MMC device
201     mmc_dev(u_boot_console, is_emmc, devid, partid)
202
203     # Clear target RAM
204     if expected_crc32:
205         if has_cmd_memory and has_cmd_crc32:
206             cmd = 'mw.b %s 0 0x%x' % (addr, count_bytes)
207             u_boot_console.run_command(cmd)
208
209             cmd = 'crc32 %s 0x%x' % (addr, count_bytes)
210             response = u_boot_console.run_command(cmd)
211             assert expected_crc32 not in response
212         else:
213             u_boot_console.log.warning(
214                 'CONFIG_CMD_MEMORY or CONFIG_CMD_CRC32 != y: Skipping RAM clear')
215
216     # Read data
217     cmd = 'mmc read %s %x %x' % (addr, sector, count_sectors)
218     tstart = time.time()
219     response = u_boot_console.run_command(cmd)
220     tend = time.time()
221     good_response = 'MMC read: dev # %d, block # %d, count %d ... %d blocks read: OK' % (
222         devid, sector, count_sectors, count_sectors)
223     assert good_response in response
224
225     # Check target RAM
226     if expected_crc32:
227         if has_cmd_crc32:
228             cmd = 'crc32 %s 0x%x' % (addr, count_bytes)
229             response = u_boot_console.run_command(cmd)
230             assert expected_crc32 in response
231         else:
232             u_boot_console.log.warning('CONFIG_CMD_CRC32 != y: Skipping check')
233
234     # Check if the command did not take too long
235     if read_duration_max:
236         elapsed = tend - tstart
237         u_boot_console.log.info('Reading %d bytes took %f seconds' %
238                                 (count_bytes, elapsed))
239         assert elapsed <= (read_duration_max - 0.01)