blob: a96c4e8fd890b3d4e74a259bd15be290914f068d [file] [log] [blame]
Love Kumar40598bd2024-01-19 19:55:50 +05301# SPDX-License-Identifier: GPL-2.0
2# (C) Copyright 2023, Advanced Micro Devices, Inc.
3
4import pytest
5import random
6import re
7import u_boot_utils
8
9"""
10Note: This test doesn't rely on boardenv_* configuration values but it can
11change the test behavior. To test MMC file system cases (fat32, ext2, ext4),
12MMC device should be formatted and valid partitions should be created for
13different file system, otherwise it may leads to failure. This test will be
14skipped if the MMC device is not detected.
15
16For example:
17
18# Setup env__mmc_device_test_skip to not skipping the test. By default, its
19# value is set to True. Set it to False to run all tests for MMC device.
20env__mmc_device_test_skip = False
21"""
22
23mmc_set_up = False
24controllers = 0
25devices = {}
26
27def setup_mmc(u_boot_console):
28 if u_boot_console.config.env.get('env__mmc_device_test_skip', True):
29 pytest.skip('MMC device test is not enabled')
30
31@pytest.mark.buildconfigspec('cmd_mmc')
32def test_mmc_list(u_boot_console):
33 setup_mmc(u_boot_console)
34 output = u_boot_console.run_command('mmc list')
35 if 'No MMC device available' in output:
36 pytest.skip('No SD/MMC/eMMC controller available')
37
38 if 'Card did not respond to voltage select' in output:
39 pytest.skip('No SD/MMC card present')
40
41 array = output.split()
42 global devices
43 global controllers
44 controllers = int(len(array) / 2)
45 for x in range(0, controllers):
46 y = x * 2
47 devices[x] = {}
48 devices[x]['name'] = array[y]
49
50 global mmc_set_up
51 mmc_set_up = True
52
53@pytest.mark.buildconfigspec('cmd_mmc')
54def test_mmc_dev(u_boot_console):
55 if not mmc_set_up:
56 pytest.skip('No SD/MMC/eMMC controller available')
57
58 fail = 0
59 for x in range(0, controllers):
60 devices[x]['detected'] = 'yes'
61 output = u_boot_console.run_command('mmc dev %d' % x)
62
63 # Some sort of switch here
64 if 'Card did not respond to voltage select' in output:
65 fail = 1
66 devices[x]['detected'] = 'no'
67
68 if 'no mmc device at slot' in output:
69 devices[x]['detected'] = 'no'
70
71 if 'MMC: no card present' in output:
72 devices[x]['detected'] = 'no'
73
74 if fail:
75 pytest.fail('Card not present')
76
77@pytest.mark.buildconfigspec('cmd_mmc')
78def test_mmcinfo(u_boot_console):
79 if not mmc_set_up:
80 pytest.skip('No SD/MMC/eMMC controller available')
81
82 for x in range(0, controllers):
83 if devices[x]['detected'] == 'yes':
84 u_boot_console.run_command('mmc dev %d' % x)
85 output = u_boot_console.run_command('mmcinfo')
86 if 'busy timeout' in output:
87 pytest.skip('No SD/MMC/eMMC device present')
88
89 obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output)
90 try:
91 capacity = float(obj.groups()[0])
92 print(capacity)
93 devices[x]['capacity'] = capacity
94 print('Capacity of dev %d is: %g GiB' % (x, capacity))
95 except ValueError:
96 pytest.fail('MMC capacity not recognized')
97
98@pytest.mark.buildconfigspec('cmd_mmc')
99def test_mmc_info(u_boot_console):
100 if not mmc_set_up:
101 pytest.skip('No SD/MMC/eMMC controller available')
102
103 for x in range(0, controllers):
104 if devices[x]['detected'] == 'yes':
105 u_boot_console.run_command('mmc dev %d' % x)
106
107 output = u_boot_console.run_command('mmc info')
108
109 obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output)
110 try:
111 capacity = float(obj.groups()[0])
112 print(capacity)
113 if devices[x]['capacity'] != capacity:
114 pytest.fail("MMC capacity doesn't match mmcinfo")
115
116 except ValueError:
117 pytest.fail('MMC capacity not recognized')
118
119@pytest.mark.buildconfigspec('cmd_mmc')
120def test_mmc_rescan(u_boot_console):
121 if not mmc_set_up:
122 pytest.skip('No SD/MMC/eMMC controller available')
123
124 if not devices:
125 pytest.skip('No devices detected')
126
127 for x in range(0, controllers):
128 if devices[x]['detected'] == 'yes':
129 u_boot_console.run_command('mmc dev %d' % x)
130 output = u_boot_console.run_command('mmc rescan')
131 if output:
132 pytest.fail('mmc rescan has something to check')
133 output = u_boot_console.run_command('echo $?')
134 assert output.endswith('0')
135
136@pytest.mark.buildconfigspec('cmd_mmc')
137def test_mmc_part(u_boot_console):
138 if not mmc_set_up:
139 pytest.skip('No SD/MMC/eMMC controller available')
140
141 if not devices:
142 pytest.skip('No devices detected')
143
144 for x in range(0, controllers):
145 if devices[x]['detected'] == 'yes':
146 u_boot_console.run_command('mmc dev %d' % x)
147 output = u_boot_console.run_command('mmc part')
148
149 lines = output.split('\n')
150 part_fat = []
151 part_ext = []
152 for line in lines:
153 obj = re.search(
154 r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line)
155 if obj:
156 part_id = int(obj.groups()[0])
157 part_type = obj.groups()[1]
158 print('part_id:%d, part_type:%s' % (part_id, part_type))
159
160 if part_type in ['0c', '0b', '0e']:
161 print('Fat detected')
162 part_fat.append(part_id)
163 elif part_type == '83':
164 print('ext detected')
165 part_ext.append(part_id)
166 else:
167 pytest.fail('Unsupported Filesystem on device %d' % x)
168 devices[x]['ext4'] = part_ext
169 devices[x]['ext2'] = part_ext
170 devices[x]['fat'] = part_fat
171
172 if not part_ext and not part_fat:
173 pytest.fail('No partition detected on device %d' % x)
174
175@pytest.mark.buildconfigspec('cmd_mmc')
176@pytest.mark.buildconfigspec('cmd_fat')
177def test_mmc_fatls_fatinfo(u_boot_console):
178 if not mmc_set_up:
179 pytest.skip('No SD/MMC/eMMC controller available')
180
181 if not devices:
182 pytest.skip('No devices detected')
183
184 part_detect = 0
185 fs = 'fat'
186 for x in range(0, controllers):
187 if devices[x]['detected'] == 'yes':
188 u_boot_console.run_command('mmc dev %d' % x)
189 try:
190 partitions = devices[x][fs]
191 except:
192 print('No %s table on this device' % fs.upper())
193 continue
194
195 for part in partitions:
196 output = u_boot_console.run_command(
197 'fatls mmc %d:%s' % (x, part))
198 if 'Unrecognized filesystem type' in output:
199 partitions.remove(part)
200 pytest.fail('Unrecognized filesystem')
201
202 if not re.search(r'\d file\(s\), \d dir\(s\)', output):
203 pytest.fail('%s read failed on device %d' % (fs.upper, x))
204 output = u_boot_console.run_command(
205 'fatinfo mmc %d:%s' % (x, part))
206 string = 'Filesystem: %s' % fs.upper
207 if re.search(string, output):
208 pytest.fail('%s FS failed on device %d' % (fs.upper(), x))
209 part_detect = 1
210
211 if not part_detect:
212 pytest.skip('No %s partition detected' % fs.upper())
213
214
215@pytest.mark.buildconfigspec('cmd_mmc')
216@pytest.mark.buildconfigspec('cmd_fat')
217@pytest.mark.buildconfigspec('cmd_memory')
218def test_mmc_fatload_fatwrite(u_boot_console):
219 if not mmc_set_up:
220 pytest.skip('No SD/MMC/eMMC controller available')
221
222 if not devices:
223 pytest.skip('No devices detected')
224
225 part_detect = 0
226 fs = 'fat'
227 for x in range(0, controllers):
228 if devices[x]['detected'] == 'yes':
229 u_boot_console.run_command('mmc dev %d' % x)
230 try:
231 partitions = devices[x][fs]
232 except:
233 print('No %s table on this device' % fs.upper())
234 continue
235
236 for part in partitions:
237 part_detect = 1
238 addr = u_boot_utils.find_ram_base(u_boot_console)
239 devices[x]['addr_%d' % part] = addr
240 size = random.randint(4, 1 * 1024 * 1024)
241 devices[x]['size_%d' % part] = size
242 # count CRC32
243 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
244 m = re.search('==> (.+?)', output)
245 if not m:
246 pytest.fail('CRC32 failed')
247 expected_crc32 = m.group(1)
248 devices[x]['expected_crc32_%d' % part] = expected_crc32
249 # do write
250 file = '%s_%d' % ('uboot_test', size)
251 devices[x]['file_%d' % part] = file
252 output = u_boot_console.run_command(
253 '%swrite mmc %d:%s %x %s %x' % (fs, x, part, addr, file, size)
254 )
255 assert 'Unable to write' not in output
256 assert 'Error' not in output
257 assert 'overflow' not in output
258 expected_text = '%d bytes written' % size
259 assert expected_text in output
260
261 alignment = int(
262 u_boot_console.config.buildconfig.get(
263 'config_sys_cacheline_size', 128
264 )
265 )
266 offset = random.randrange(alignment, 1024, alignment)
267 output = u_boot_console.run_command(
268 '%sload mmc %d:%s %x %s' % (fs, x, part, addr + offset, file)
269 )
270 assert 'Invalid FAT entry' not in output
271 assert 'Unable to read file' not in output
272 assert 'Misaligned buffer address' not in output
273 expected_text = '%d bytes read' % size
274 assert expected_text in output
275
276 output = u_boot_console.run_command(
277 'crc32 %x $filesize' % (addr + offset)
278 )
279 assert expected_crc32 in output
280
281 if not part_detect:
282 pytest.skip('No %s partition detected' % fs.upper())
283
284@pytest.mark.buildconfigspec('cmd_mmc')
285@pytest.mark.buildconfigspec('cmd_ext4')
286def test_mmc_ext4ls(u_boot_console):
287 if not mmc_set_up:
288 pytest.skip('No SD/MMC/eMMC controller available')
289
290 if not devices:
291 pytest.skip('No devices detected')
292
293 part_detect = 0
294 fs = 'ext4'
295 for x in range(0, controllers):
296 if devices[x]['detected'] == 'yes':
297 try:
298 partitions = devices[x][fs]
299 except:
300 print('No %s table on this device' % fs.upper())
301 continue
302
303 u_boot_console.run_command('mmc dev %d' % x)
304 for part in partitions:
305 output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part))
306 if 'Unrecognized filesystem type' in output:
307 partitions.remove(part)
308 pytest.fail('Unrecognized filesystem')
309 part_detect = 1
310
311 if not part_detect:
312 pytest.skip('No %s partition detected' % fs.upper())
313
314@pytest.mark.buildconfigspec('cmd_mmc')
315@pytest.mark.buildconfigspec('cmd_ext4')
316@pytest.mark.buildconfigspec('ext4_write')
317@pytest.mark.buildconfigspec('cmd_memory')
318def test_mmc_ext4load_ext4write(u_boot_console):
319 if not mmc_set_up:
320 pytest.skip('No SD/MMC/eMMC controller available')
321
322 if not devices:
323 pytest.skip('No devices detected')
324
325 part_detect = 0
326 fs = 'ext4'
327 for x in range(0, controllers):
328 if devices[x]['detected'] == 'yes':
329 u_boot_console.run_command('mmc dev %d' % x)
330 try:
331 partitions = devices[x][fs]
332 except:
333 print('No %s table on this device' % fs.upper())
334 continue
335
336 for part in partitions:
337 part_detect = 1
338 addr = u_boot_utils.find_ram_base(u_boot_console)
339 devices[x]['addr_%d' % part] = addr
340 size = random.randint(4, 1 * 1024 * 1024)
341 devices[x]['size_%d' % part] = size
342 # count CRC32
343 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
344 m = re.search('==> (.+?)', output)
345 if not m:
346 pytest.fail('CRC32 failed')
347 expected_crc32 = m.group(1)
348 devices[x]['expected_crc32_%d' % part] = expected_crc32
349 # do write
350
351 file = '%s_%d' % ('uboot_test', size)
352 devices[x]['file_%d' % part] = file
353 output = u_boot_console.run_command(
354 '%swrite mmc %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
355 )
356 assert 'Unable to write' not in output
357 assert 'Error' not in output
358 assert 'overflow' not in output
359 expected_text = '%d bytes written' % size
360 assert expected_text in output
361
362 offset = random.randrange(128, 1024, 128)
363 output = u_boot_console.run_command(
364 '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file)
365 )
366 expected_text = '%d bytes read' % size
367 assert expected_text in output
368
369 output = u_boot_console.run_command(
370 'crc32 %x $filesize' % (addr + offset)
371 )
372 assert expected_crc32 in output
373
374 if not part_detect:
375 pytest.skip('No %s partition detected' % fs.upper())
376
377@pytest.mark.buildconfigspec('cmd_mmc')
378@pytest.mark.buildconfigspec('cmd_ext2')
379def test_mmc_ext2ls(u_boot_console):
380 if not mmc_set_up:
381 pytest.skip('No SD/MMC/eMMC controller available')
382
383 if not devices:
384 pytest.skip('No devices detected')
385
386 part_detect = 0
387 fs = 'ext2'
388 for x in range(0, controllers):
389 if devices[x]['detected'] == 'yes':
390 u_boot_console.run_command('mmc dev %d' % x)
391 try:
392 partitions = devices[x][fs]
393 except:
394 print('No %s table on this device' % fs.upper())
395 continue
396
397 for part in partitions:
398 part_detect = 1
399 output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part))
400 if 'Unrecognized filesystem type' in output:
401 partitions.remove(part)
402 pytest.fail('Unrecognized filesystem')
403 part_detect = 1
404
405 if not part_detect:
406 pytest.skip('No %s partition detected' % fs.upper())
407
408@pytest.mark.buildconfigspec('cmd_mmc')
409@pytest.mark.buildconfigspec('cmd_ext2')
410@pytest.mark.buildconfigspec('cmd_ext4')
411@pytest.mark.buildconfigspec('ext4_write')
412@pytest.mark.buildconfigspec('cmd_memory')
413def test_mmc_ext2load(u_boot_console):
414 if not mmc_set_up:
415 pytest.skip('No SD/MMC/eMMC controller available')
416
417 if not devices:
418 pytest.skip('No devices detected')
419
420 part_detect = 0
421 fs = 'ext2'
422 for x in range(0, controllers):
423 if devices[x]['detected'] == 'yes':
424 u_boot_console.run_command('mmc dev %d' % x)
425 try:
426 partitions = devices[x][fs]
427 except:
428 print('No %s table on this device' % fs.upper())
429 continue
430
431 for part in partitions:
432 part_detect = 1
433 addr = devices[x]['addr_%d' % part]
434 size = devices[x]['size_%d' % part]
435 expected_crc32 = devices[x]['expected_crc32_%d' % part]
436 file = devices[x]['file_%d' % part]
437
438 offset = random.randrange(128, 1024, 128)
439 output = u_boot_console.run_command(
440 '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file)
441 )
442 expected_text = '%d bytes read' % size
443 assert expected_text in output
444
445 output = u_boot_console.run_command(
446 'crc32 %x $filesize' % (addr + offset)
447 )
448 assert expected_crc32 in output
449
450 if not part_detect:
451 pytest.skip('No %s partition detected' % fs.upper())
452
453@pytest.mark.buildconfigspec('cmd_mmc')
454@pytest.mark.buildconfigspec('cmd_fs_generic')
455def test_mmc_ls(u_boot_console):
456 if not mmc_set_up:
457 pytest.skip('No SD/MMC/eMMC controller available')
458
459 if not devices:
460 pytest.skip('No devices detected')
461
462 part_detect = 0
463 for x in range(0, controllers):
464 if devices[x]['detected'] == 'yes':
465 u_boot_console.run_command('mmc dev %d' % x)
466 for fs in ['fat', 'ext4']:
467 try:
468 partitions = devices[x][fs]
469 except:
470 print('No %s table on this device' % fs.upper())
471 continue
472
473 for part in partitions:
474 part_detect = 1
475 output = u_boot_console.run_command('ls mmc %d:%s' % (x, part))
476 if re.search(r'No \w+ table on this device', output):
477 pytest.fail(
478 '%s: Partition table not found %d' % (fs.upper(), x)
479 )
480
481 if not part_detect:
482 pytest.skip('No partition detected')
483
484@pytest.mark.buildconfigspec('cmd_mmc')
485@pytest.mark.buildconfigspec('cmd_fs_generic')
486def test_mmc_load(u_boot_console):
487 if not mmc_set_up:
488 pytest.skip('No SD/MMC/eMMC controller available')
489
490 if not devices:
491 pytest.skip('No devices detected')
492
493 part_detect = 0
494 for x in range(0, controllers):
495 if devices[x]['detected'] == 'yes':
496 u_boot_console.run_command('mmc dev %d' % x)
497 for fs in ['fat', 'ext4']:
498 try:
499 partitions = devices[x][fs]
500 except:
501 print('No %s table on this device' % fs.upper())
502 continue
503
504 for part in partitions:
505 part_detect = 1
506 addr = devices[x]['addr_%d' % part]
507 size = devices[x]['size_%d' % part]
508 expected_crc32 = devices[x]['expected_crc32_%d' % part]
509 file = devices[x]['file_%d' % part]
510
511 offset = random.randrange(128, 1024, 128)
512 output = u_boot_console.run_command(
513 'load mmc %d:%s %x /%s' % (x, part, addr + offset, file)
514 )
515 expected_text = '%d bytes read' % size
516 assert expected_text in output
517
518 output = u_boot_console.run_command(
519 'crc32 %x $filesize' % (addr + offset)
520 )
521 assert expected_crc32 in output
522
523 if not part_detect:
524 pytest.skip('No partition detected')
525
526@pytest.mark.buildconfigspec('cmd_mmc')
527@pytest.mark.buildconfigspec('cmd_fs_generic')
528def test_mmc_save(u_boot_console):
529 if not mmc_set_up:
530 pytest.skip('No SD/MMC/eMMC controller available')
531
532 if not devices:
533 pytest.skip('No devices detected')
534
535 part_detect = 0
536 for x in range(0, controllers):
537 if devices[x]['detected'] == 'yes':
538 u_boot_console.run_command('mmc dev %d' % x)
539 for fs in ['fat', 'ext4']:
540 try:
541 partitions = devices[x][fs]
542 except:
543 print('No %s table on this device' % fs.upper())
544 continue
545
546 for part in partitions:
547 part_detect = 1
548 addr = devices[x]['addr_%d' % part]
549 size = 0
550 file = devices[x]['file_%d' % part]
551
552 offset = random.randrange(128, 1024, 128)
553 output = u_boot_console.run_command(
554 'save mmc %d:%s %x /%s %d'
555 % (x, part, addr + offset, file, size)
556 )
557 expected_text = '%d bytes written' % size
558 assert expected_text in output
559
560 if not part_detect:
561 pytest.skip('No partition detected')
562
563@pytest.mark.buildconfigspec('cmd_mmc')
564@pytest.mark.buildconfigspec('cmd_fat')
565@pytest.mark.buildconfigspec('cmd_memory')
566def test_mmc_fat_read_write_files(u_boot_console):
567 test_mmc_list(u_boot_console)
568 test_mmc_dev(u_boot_console)
569 test_mmcinfo(u_boot_console)
570 test_mmc_part(u_boot_console)
571 if not mmc_set_up:
572 pytest.skip('No SD/MMC/eMMC controller available')
573
574 if not devices:
575 pytest.skip('No devices detected')
576
577 part_detect = 0
578 fs = 'fat'
579
580 # Number of files to be written/read in MMC card
581 num_files = 100
582
583 for x in range(0, controllers):
584 if devices[x]['detected'] == 'yes':
585 u_boot_console.run_command('mmc dev %d' % x)
586 try:
587 partitions = devices[x][fs]
588 except:
589 print('No %s table on this device' % fs.upper())
590 continue
591
592 for part in partitions:
593 part_detect = 1
594 addr = u_boot_utils.find_ram_base(u_boot_console)
595 count_f = 0
596 addr_l = []
597 size_l = []
598 file_l = []
599 crc32_l = []
600 offset_l = []
601 addr_l.append(addr)
602
603 while count_f < num_files:
604 size_l.append(random.randint(4, 1 * 1024 * 1024))
605
606 # CRC32 count
607 output = u_boot_console.run_command(
608 'crc32 %x %x' % (addr_l[count_f], size_l[count_f])
609 )
610 m = re.search('==> (.+?)', output)
611 if not m:
612 pytest.fail('CRC32 failed')
613 crc32_l.append(m.group(1))
614
615 # Write operation
616 file_l.append('%s_%d_%d' % ('uboot_test', count_f, size_l[count_f]))
617 output = u_boot_console.run_command(
618 '%swrite mmc %d:%s %x %s %x'
619 % (
620 fs,
621 x,
622 part,
623 addr_l[count_f],
624 file_l[count_f],
625 size_l[count_f],
626 )
627 )
628 assert 'Unable to write' not in output
629 assert 'Error' not in output
630 assert 'overflow' not in output
631 expected_text = '%d bytes written' % size_l[count_f]
632 assert expected_text in output
633
634 addr_l.append(addr_l[count_f] + size_l[count_f] + 1048576)
635 count_f += 1
636
637 count_f = 0
638 while count_f < num_files:
639 alignment = int(
640 u_boot_console.config.buildconfig.get(
641 'config_sys_cacheline_size', 128
642 )
643 )
644 offset_l.append(random.randrange(alignment, 1024, alignment))
645
646 # Read operation
647 output = u_boot_console.run_command(
648 '%sload mmc %d:%s %x %s'
649 % (
650 fs,
651 x,
652 part,
653 addr_l[count_f] + offset_l[count_f],
654 file_l[count_f],
655 )
656 )
657 assert 'Invalid FAT entry' not in output
658 assert 'Unable to read file' not in output
659 assert 'Misaligned buffer address' not in output
660 expected_text = '%d bytes read' % size_l[count_f]
661 assert expected_text in output
662
663 output = u_boot_console.run_command(
664 'crc32 %x $filesize' % (addr_l[count_f] + offset_l[count_f])
665 )
666 assert crc32_l[count_f] in output
667
668 count_f += 1
669
670 if not part_detect:
671 pytest.skip('No %s partition detected' % fs.upper())