blob: 1193f4a95737e8460d16c4782de8eebc79621b29 [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 = []
Love Kumar1ff2ed82024-11-12 14:27:27 +0530151 part_ext2 = []
152 part_ext4 = []
Love Kumar40598bd2024-01-19 19:55:50 +0530153 for line in lines:
154 obj = re.search(
155 r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line)
156 if obj:
157 part_id = int(obj.groups()[0])
158 part_type = obj.groups()[1]
159 print('part_id:%d, part_type:%s' % (part_id, part_type))
160
161 if part_type in ['0c', '0b', '0e']:
162 print('Fat detected')
163 part_fat.append(part_id)
164 elif part_type == '83':
Love Kumar1ff2ed82024-11-12 14:27:27 +0530165 print('ext(2/4) detected')
166 output = u_boot_console.run_command(
167 'fstype mmc %d:%d' % x, part_id
168 )
169 if 'ext2' in output:
170 part_ext2.append(part_id)
171 elif 'ext4' in output:
172 part_ext4.append(part_id)
Love Kumar40598bd2024-01-19 19:55:50 +0530173 else:
174 pytest.fail('Unsupported Filesystem on device %d' % x)
Love Kumar1ff2ed82024-11-12 14:27:27 +0530175 devices[x]['ext4'] = part_ext4
176 devices[x]['ext2'] = part_ext2
Love Kumar40598bd2024-01-19 19:55:50 +0530177 devices[x]['fat'] = part_fat
178
Love Kumar1ff2ed82024-11-12 14:27:27 +0530179 if not part_ext2 and not part_ext4 and not part_fat:
Love Kumar40598bd2024-01-19 19:55:50 +0530180 pytest.fail('No partition detected on device %d' % x)
181
182@pytest.mark.buildconfigspec('cmd_mmc')
183@pytest.mark.buildconfigspec('cmd_fat')
184def test_mmc_fatls_fatinfo(u_boot_console):
185 if not mmc_set_up:
186 pytest.skip('No SD/MMC/eMMC controller available')
187
188 if not devices:
189 pytest.skip('No devices detected')
190
191 part_detect = 0
192 fs = 'fat'
193 for x in range(0, controllers):
194 if devices[x]['detected'] == 'yes':
195 u_boot_console.run_command('mmc dev %d' % x)
196 try:
197 partitions = devices[x][fs]
198 except:
199 print('No %s table on this device' % fs.upper())
200 continue
201
202 for part in partitions:
203 output = u_boot_console.run_command(
204 'fatls mmc %d:%s' % (x, part))
205 if 'Unrecognized filesystem type' in output:
206 partitions.remove(part)
207 pytest.fail('Unrecognized filesystem')
208
209 if not re.search(r'\d file\(s\), \d dir\(s\)', output):
210 pytest.fail('%s read failed on device %d' % (fs.upper, x))
211 output = u_boot_console.run_command(
212 'fatinfo mmc %d:%s' % (x, part))
213 string = 'Filesystem: %s' % fs.upper
214 if re.search(string, output):
215 pytest.fail('%s FS failed on device %d' % (fs.upper(), x))
216 part_detect = 1
217
218 if not part_detect:
219 pytest.skip('No %s partition detected' % fs.upper())
220
221
222@pytest.mark.buildconfigspec('cmd_mmc')
223@pytest.mark.buildconfigspec('cmd_fat')
224@pytest.mark.buildconfigspec('cmd_memory')
225def test_mmc_fatload_fatwrite(u_boot_console):
226 if not mmc_set_up:
227 pytest.skip('No SD/MMC/eMMC controller available')
228
229 if not devices:
230 pytest.skip('No devices detected')
231
232 part_detect = 0
233 fs = 'fat'
234 for x in range(0, controllers):
235 if devices[x]['detected'] == 'yes':
236 u_boot_console.run_command('mmc dev %d' % x)
237 try:
238 partitions = devices[x][fs]
239 except:
240 print('No %s table on this device' % fs.upper())
241 continue
242
243 for part in partitions:
244 part_detect = 1
245 addr = u_boot_utils.find_ram_base(u_boot_console)
246 devices[x]['addr_%d' % part] = addr
247 size = random.randint(4, 1 * 1024 * 1024)
248 devices[x]['size_%d' % part] = size
249 # count CRC32
250 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
251 m = re.search('==> (.+?)', output)
252 if not m:
253 pytest.fail('CRC32 failed')
254 expected_crc32 = m.group(1)
255 devices[x]['expected_crc32_%d' % part] = expected_crc32
256 # do write
257 file = '%s_%d' % ('uboot_test', size)
258 devices[x]['file_%d' % part] = file
259 output = u_boot_console.run_command(
260 '%swrite mmc %d:%s %x %s %x' % (fs, x, part, addr, file, size)
261 )
262 assert 'Unable to write' not in output
263 assert 'Error' not in output
264 assert 'overflow' not in output
265 expected_text = '%d bytes written' % size
266 assert expected_text in output
267
268 alignment = int(
269 u_boot_console.config.buildconfig.get(
270 'config_sys_cacheline_size', 128
271 )
272 )
273 offset = random.randrange(alignment, 1024, alignment)
274 output = u_boot_console.run_command(
275 '%sload mmc %d:%s %x %s' % (fs, x, part, addr + offset, file)
276 )
277 assert 'Invalid FAT entry' not in output
278 assert 'Unable to read file' not in output
279 assert 'Misaligned buffer address' not in output
280 expected_text = '%d bytes read' % size
281 assert expected_text in output
282
283 output = u_boot_console.run_command(
284 'crc32 %x $filesize' % (addr + offset)
285 )
286 assert expected_crc32 in output
287
288 if not part_detect:
289 pytest.skip('No %s partition detected' % fs.upper())
290
291@pytest.mark.buildconfigspec('cmd_mmc')
292@pytest.mark.buildconfigspec('cmd_ext4')
293def test_mmc_ext4ls(u_boot_console):
294 if not mmc_set_up:
295 pytest.skip('No SD/MMC/eMMC controller available')
296
297 if not devices:
298 pytest.skip('No devices detected')
299
300 part_detect = 0
301 fs = 'ext4'
302 for x in range(0, controllers):
303 if devices[x]['detected'] == 'yes':
304 try:
305 partitions = devices[x][fs]
306 except:
307 print('No %s table on this device' % fs.upper())
308 continue
309
310 u_boot_console.run_command('mmc dev %d' % x)
311 for part in partitions:
312 output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part))
313 if 'Unrecognized filesystem type' in output:
314 partitions.remove(part)
315 pytest.fail('Unrecognized filesystem')
316 part_detect = 1
317
318 if not part_detect:
319 pytest.skip('No %s partition detected' % fs.upper())
320
321@pytest.mark.buildconfigspec('cmd_mmc')
322@pytest.mark.buildconfigspec('cmd_ext4')
323@pytest.mark.buildconfigspec('ext4_write')
324@pytest.mark.buildconfigspec('cmd_memory')
325def test_mmc_ext4load_ext4write(u_boot_console):
326 if not mmc_set_up:
327 pytest.skip('No SD/MMC/eMMC controller available')
328
329 if not devices:
330 pytest.skip('No devices detected')
331
332 part_detect = 0
333 fs = 'ext4'
334 for x in range(0, controllers):
335 if devices[x]['detected'] == 'yes':
336 u_boot_console.run_command('mmc dev %d' % x)
337 try:
338 partitions = devices[x][fs]
339 except:
340 print('No %s table on this device' % fs.upper())
341 continue
342
343 for part in partitions:
344 part_detect = 1
345 addr = u_boot_utils.find_ram_base(u_boot_console)
346 devices[x]['addr_%d' % part] = addr
347 size = random.randint(4, 1 * 1024 * 1024)
348 devices[x]['size_%d' % part] = size
349 # count CRC32
350 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
351 m = re.search('==> (.+?)', output)
352 if not m:
353 pytest.fail('CRC32 failed')
354 expected_crc32 = m.group(1)
355 devices[x]['expected_crc32_%d' % part] = expected_crc32
356 # do write
357
358 file = '%s_%d' % ('uboot_test', size)
359 devices[x]['file_%d' % part] = file
360 output = u_boot_console.run_command(
361 '%swrite mmc %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
362 )
363 assert 'Unable to write' not in output
364 assert 'Error' not in output
365 assert 'overflow' not in output
366 expected_text = '%d bytes written' % size
367 assert expected_text in output
368
369 offset = random.randrange(128, 1024, 128)
370 output = u_boot_console.run_command(
371 '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file)
372 )
373 expected_text = '%d bytes read' % size
374 assert expected_text in output
375
376 output = u_boot_console.run_command(
377 'crc32 %x $filesize' % (addr + offset)
378 )
379 assert expected_crc32 in output
380
381 if not part_detect:
382 pytest.skip('No %s partition detected' % fs.upper())
383
384@pytest.mark.buildconfigspec('cmd_mmc')
385@pytest.mark.buildconfigspec('cmd_ext2')
386def test_mmc_ext2ls(u_boot_console):
387 if not mmc_set_up:
388 pytest.skip('No SD/MMC/eMMC controller available')
389
390 if not devices:
391 pytest.skip('No devices detected')
392
393 part_detect = 0
394 fs = 'ext2'
395 for x in range(0, controllers):
396 if devices[x]['detected'] == 'yes':
397 u_boot_console.run_command('mmc dev %d' % x)
398 try:
399 partitions = devices[x][fs]
400 except:
401 print('No %s table on this device' % fs.upper())
402 continue
403
404 for part in partitions:
405 part_detect = 1
406 output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part))
407 if 'Unrecognized filesystem type' in output:
408 partitions.remove(part)
409 pytest.fail('Unrecognized filesystem')
410 part_detect = 1
411
412 if not part_detect:
413 pytest.skip('No %s partition detected' % fs.upper())
414
415@pytest.mark.buildconfigspec('cmd_mmc')
416@pytest.mark.buildconfigspec('cmd_ext2')
417@pytest.mark.buildconfigspec('cmd_ext4')
418@pytest.mark.buildconfigspec('ext4_write')
419@pytest.mark.buildconfigspec('cmd_memory')
420def test_mmc_ext2load(u_boot_console):
421 if not mmc_set_up:
422 pytest.skip('No SD/MMC/eMMC controller available')
423
424 if not devices:
425 pytest.skip('No devices detected')
426
427 part_detect = 0
428 fs = 'ext2'
429 for x in range(0, controllers):
430 if devices[x]['detected'] == 'yes':
431 u_boot_console.run_command('mmc dev %d' % x)
432 try:
433 partitions = devices[x][fs]
434 except:
435 print('No %s table on this device' % fs.upper())
436 continue
437
438 for part in partitions:
439 part_detect = 1
440 addr = devices[x]['addr_%d' % part]
441 size = devices[x]['size_%d' % part]
442 expected_crc32 = devices[x]['expected_crc32_%d' % part]
443 file = devices[x]['file_%d' % part]
444
445 offset = random.randrange(128, 1024, 128)
446 output = u_boot_console.run_command(
447 '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file)
448 )
449 expected_text = '%d bytes read' % size
450 assert expected_text in output
451
452 output = u_boot_console.run_command(
453 'crc32 %x $filesize' % (addr + offset)
454 )
455 assert expected_crc32 in output
456
457 if not part_detect:
458 pytest.skip('No %s partition detected' % fs.upper())
459
460@pytest.mark.buildconfigspec('cmd_mmc')
461@pytest.mark.buildconfigspec('cmd_fs_generic')
462def test_mmc_ls(u_boot_console):
463 if not mmc_set_up:
464 pytest.skip('No SD/MMC/eMMC controller available')
465
466 if not devices:
467 pytest.skip('No devices detected')
468
469 part_detect = 0
470 for x in range(0, controllers):
471 if devices[x]['detected'] == 'yes':
472 u_boot_console.run_command('mmc dev %d' % x)
Love Kumar1ff2ed82024-11-12 14:27:27 +0530473 for fs in ['fat', 'ext4', 'ext2']:
Love Kumar40598bd2024-01-19 19:55:50 +0530474 try:
475 partitions = devices[x][fs]
476 except:
477 print('No %s table on this device' % fs.upper())
478 continue
479
480 for part in partitions:
481 part_detect = 1
482 output = u_boot_console.run_command('ls mmc %d:%s' % (x, part))
483 if re.search(r'No \w+ table on this device', output):
484 pytest.fail(
485 '%s: Partition table not found %d' % (fs.upper(), x)
486 )
487
488 if not part_detect:
489 pytest.skip('No partition detected')
490
491@pytest.mark.buildconfigspec('cmd_mmc')
492@pytest.mark.buildconfigspec('cmd_fs_generic')
493def test_mmc_load(u_boot_console):
494 if not mmc_set_up:
495 pytest.skip('No SD/MMC/eMMC controller available')
496
497 if not devices:
498 pytest.skip('No devices detected')
499
500 part_detect = 0
501 for x in range(0, controllers):
502 if devices[x]['detected'] == 'yes':
503 u_boot_console.run_command('mmc dev %d' % x)
Love Kumar1ff2ed82024-11-12 14:27:27 +0530504 for fs in ['fat', 'ext4', 'ext2']:
Love Kumar40598bd2024-01-19 19:55:50 +0530505 try:
506 partitions = devices[x][fs]
507 except:
508 print('No %s table on this device' % fs.upper())
509 continue
510
511 for part in partitions:
512 part_detect = 1
513 addr = devices[x]['addr_%d' % part]
514 size = devices[x]['size_%d' % part]
515 expected_crc32 = devices[x]['expected_crc32_%d' % part]
516 file = devices[x]['file_%d' % part]
517
518 offset = random.randrange(128, 1024, 128)
519 output = u_boot_console.run_command(
520 'load mmc %d:%s %x /%s' % (x, part, addr + offset, file)
521 )
522 expected_text = '%d bytes read' % size
523 assert expected_text in output
524
525 output = u_boot_console.run_command(
526 'crc32 %x $filesize' % (addr + offset)
527 )
528 assert expected_crc32 in output
529
530 if not part_detect:
531 pytest.skip('No partition detected')
532
533@pytest.mark.buildconfigspec('cmd_mmc')
534@pytest.mark.buildconfigspec('cmd_fs_generic')
535def test_mmc_save(u_boot_console):
536 if not mmc_set_up:
537 pytest.skip('No SD/MMC/eMMC controller available')
538
539 if not devices:
540 pytest.skip('No devices detected')
541
542 part_detect = 0
543 for x in range(0, controllers):
544 if devices[x]['detected'] == 'yes':
545 u_boot_console.run_command('mmc dev %d' % x)
Love Kumar1ff2ed82024-11-12 14:27:27 +0530546 for fs in ['fat', 'ext4', 'ext2']:
Love Kumar40598bd2024-01-19 19:55:50 +0530547 try:
548 partitions = devices[x][fs]
549 except:
550 print('No %s table on this device' % fs.upper())
551 continue
552
553 for part in partitions:
554 part_detect = 1
555 addr = devices[x]['addr_%d' % part]
556 size = 0
557 file = devices[x]['file_%d' % part]
558
559 offset = random.randrange(128, 1024, 128)
560 output = u_boot_console.run_command(
561 'save mmc %d:%s %x /%s %d'
562 % (x, part, addr + offset, file, size)
563 )
564 expected_text = '%d bytes written' % size
565 assert expected_text in output
566
567 if not part_detect:
568 pytest.skip('No partition detected')
569
570@pytest.mark.buildconfigspec('cmd_mmc')
571@pytest.mark.buildconfigspec('cmd_fat')
572@pytest.mark.buildconfigspec('cmd_memory')
573def test_mmc_fat_read_write_files(u_boot_console):
574 test_mmc_list(u_boot_console)
575 test_mmc_dev(u_boot_console)
576 test_mmcinfo(u_boot_console)
577 test_mmc_part(u_boot_console)
578 if not mmc_set_up:
579 pytest.skip('No SD/MMC/eMMC controller available')
580
581 if not devices:
582 pytest.skip('No devices detected')
583
584 part_detect = 0
585 fs = 'fat'
586
587 # Number of files to be written/read in MMC card
588 num_files = 100
589
590 for x in range(0, controllers):
591 if devices[x]['detected'] == 'yes':
592 u_boot_console.run_command('mmc dev %d' % x)
593 try:
594 partitions = devices[x][fs]
595 except:
596 print('No %s table on this device' % fs.upper())
597 continue
598
599 for part in partitions:
600 part_detect = 1
601 addr = u_boot_utils.find_ram_base(u_boot_console)
602 count_f = 0
603 addr_l = []
604 size_l = []
605 file_l = []
606 crc32_l = []
607 offset_l = []
608 addr_l.append(addr)
609
610 while count_f < num_files:
611 size_l.append(random.randint(4, 1 * 1024 * 1024))
612
613 # CRC32 count
614 output = u_boot_console.run_command(
615 'crc32 %x %x' % (addr_l[count_f], size_l[count_f])
616 )
617 m = re.search('==> (.+?)', output)
618 if not m:
619 pytest.fail('CRC32 failed')
620 crc32_l.append(m.group(1))
621
622 # Write operation
623 file_l.append('%s_%d_%d' % ('uboot_test', count_f, size_l[count_f]))
624 output = u_boot_console.run_command(
625 '%swrite mmc %d:%s %x %s %x'
626 % (
627 fs,
628 x,
629 part,
630 addr_l[count_f],
631 file_l[count_f],
632 size_l[count_f],
633 )
634 )
635 assert 'Unable to write' not in output
636 assert 'Error' not in output
637 assert 'overflow' not in output
638 expected_text = '%d bytes written' % size_l[count_f]
639 assert expected_text in output
640
641 addr_l.append(addr_l[count_f] + size_l[count_f] + 1048576)
642 count_f += 1
643
644 count_f = 0
645 while count_f < num_files:
646 alignment = int(
647 u_boot_console.config.buildconfig.get(
648 'config_sys_cacheline_size', 128
649 )
650 )
651 offset_l.append(random.randrange(alignment, 1024, alignment))
652
653 # Read operation
654 output = u_boot_console.run_command(
655 '%sload mmc %d:%s %x %s'
656 % (
657 fs,
658 x,
659 part,
660 addr_l[count_f] + offset_l[count_f],
661 file_l[count_f],
662 )
663 )
664 assert 'Invalid FAT entry' not in output
665 assert 'Unable to read file' not in output
666 assert 'Misaligned buffer address' not in output
667 expected_text = '%d bytes read' % size_l[count_f]
668 assert expected_text in output
669
670 output = u_boot_console.run_command(
671 'crc32 %x $filesize' % (addr_l[count_f] + offset_l[count_f])
672 )
673 assert crc32_l[count_f] in output
674
675 count_f += 1
676
677 if not part_detect:
678 pytest.skip('No %s partition detected' % fs.upper())