blob: fb3d20f0826b9622d75e73f427d608d6ed31787f [file] [log] [blame]
Love Kumar6c91f092024-01-19 19:56:02 +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 USB file system cases (fat32, ext2, ext4),
12USB 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 USB device is not detected.
15
16For example:
17
18# Setup env__usb_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 USB device.
20env__usb_device_test_skip = False
21"""
22
23def setup_usb(u_boot_console):
24 if u_boot_console.config.env.get('env__usb_device_test_skip', True):
25 pytest.skip('USB device test is not enabled')
26
27@pytest.mark.buildconfigspec('cmd_usb')
28def test_usb_start(u_boot_console):
29 setup_usb(u_boot_console)
30 output = u_boot_console.run_command('usb start')
31
32 # if output is empty, usb start may already run as part of preboot command
33 # re-start the usb, in that case
34 if not output:
35 u_boot_console.run_command('usb stop')
36 output = u_boot_console.run_command('usb start')
37
38 if 'No USB device found' in output:
39 pytest.skip('No USB controller available')
40
41 if 'Card did not respond to voltage select' in output:
42 pytest.skip('No USB device present')
43
44 controllers = 0
45 storage_device = 0
46 obj = re.search(r'\d USB Device\(s\) found', output)
47 controllers = int(obj.group()[0])
48
49 if not controllers:
50 pytest.skip('No USB device present')
51
52 obj = re.search(r'\d Storage Device\(s\) found', output)
53 storage_device = int(obj.group()[0])
54
55 if not storage_device:
56 pytest.skip('No USB storage device present')
57
58 assert 'USB init failed' not in output
59 assert 'starting USB...' in output
60
61 if 'Starting the controller' in output:
62 assert 'USB XHCI' in output
63
64 output = u_boot_console.run_command('echo $?')
65 assert output.endswith('0')
66 return controllers, storage_device
67
68@pytest.mark.buildconfigspec('cmd_usb')
69def test_usb_stop(u_boot_console):
70 setup_usb(u_boot_console)
71 output = u_boot_console.run_command('usb stop')
72 assert 'stopping USB..' in output
73
74 output = u_boot_console.run_command('echo $?')
75 assert output.endswith('0')
76
77 output = u_boot_console.run_command('usb dev')
78 assert "USB is stopped. Please issue 'usb start' first." in output
79
80@pytest.mark.buildconfigspec('cmd_usb')
81def test_usb_reset(u_boot_console):
82 setup_usb(u_boot_console)
83 output = u_boot_console.run_command('usb reset')
84
85 if 'No USB device found' in output:
86 pytest.skip('No USB controller available')
87
88 if 'Card did not respond to voltage select' in output:
89 pytest.skip('No USB device present')
90
91 obj = re.search(r'\d USB Device\(s\) found', output)
92 usb_dev_num = int(obj.group()[0])
93
94 if not usb_dev_num:
95 pytest.skip('No USB device present')
96
97 obj = re.search(r'\d Storage Device\(s\) found', output)
98 usb_stor_num = int(obj.group()[0])
99
100 if not usb_stor_num:
101 pytest.skip('No USB storage device present')
102
103 assert 'BUG' not in output
104 assert 'USB init failed' not in output
105 assert 'resetting USB...' in output
106
107 if 'Starting the controller' in output:
108 assert 'USB XHCI' in output
109
110 output = u_boot_console.run_command('echo $?')
111 assert output.endswith('0')
112
113@pytest.mark.buildconfigspec('cmd_usb')
114def test_usb_info(u_boot_console):
115 controllers, storage_device = test_usb_start(u_boot_console)
116 output = u_boot_console.run_command('usb info')
117
118 num_controller = len(re.findall(': Hub,', output))
119 num_mass_storage = len(re.findall(': Mass Storage,', output))
120
121 assert num_controller == controllers - 1
122 assert num_mass_storage == storage_device
123
124 output = u_boot_console.run_command('echo $?')
125 assert output.endswith('0')
126
127 for i in range(0, storage_device + controllers - 1):
128 output = u_boot_console.run_command('usb info %d' % i)
129 num_controller = len(re.findall(': Hub,', output))
130 num_mass_storage = len(re.findall(': Mass Storage,', output))
131 assert num_controller + num_mass_storage == 1
132 assert 'No device available' not in output
133 output = u_boot_console.run_command('echo $?')
134 assert output.endswith('0')
135
136@pytest.mark.buildconfigspec('cmd_usb')
137def test_usb_tree(u_boot_console):
138 controllers, storage_device = test_usb_start(u_boot_console)
139 output = u_boot_console.run_command('usb tree')
140
141 num_controller = len(re.findall('Hub', output))
142 num_mass_storage = len(re.findall('Mass Storage', output))
143
144 assert num_controller == controllers - 1
145 assert num_mass_storage == storage_device
146
147 output = u_boot_console.run_command('echo $?')
148 assert output.endswith('0')
149
150@pytest.mark.buildconfigspec('cmd_usb')
151@pytest.mark.buildconfigspec('usb_storage')
152def test_usb_storage(u_boot_console):
153 controllers, storage_device = test_usb_start(u_boot_console)
154 output = u_boot_console.run_command('usb storage')
155
156 obj = re.findall(r'Capacity: (\d+|\d+[\.]?\d)', output)
157 devices = {}
158
159 for key in range(int(storage_device)):
160 devices[key] = {}
161
162 for x in range(int(storage_device)):
163 try:
164 capacity = float(obj[x].split()[0])
165 devices[x]['capacity'] = capacity
166 print('USB storage device %d capacity is: %g MB' % (x, capacity))
167 except ValueError:
168 pytest.fail('USB storage device capacity not recognized')
169
170 output = u_boot_console.run_command('echo $?')
171 assert output.endswith('0')
172
173@pytest.mark.buildconfigspec('cmd_usb')
174def test_usb_dev(u_boot_console):
175 controllers, storage_device = test_usb_start(u_boot_console)
176 output = u_boot_console.run_command('usb dev')
177
178 assert 'no usb devices available' not in output
179
180 output = u_boot_console.run_command('echo $?')
181 assert output.endswith('0')
182
183 devices = {}
184
185 for key in range(int(storage_device)):
186 devices[key] = {}
187
188 fail = 0
189 for x in range(0, storage_device):
190 devices[x]['detected'] = 'yes'
191 output = u_boot_console.run_command('usb dev %d' % x)
192
193 if 'Card did not respond to voltage select' in output:
194 fail = 1
195 devices[x]['detected'] = 'no'
196
197 if 'No USB device found' in output:
198 devices[x]['detected'] = 'no'
199
200 if 'unknown device' in output:
201 devices[x]['detected'] = 'no'
202
203 assert 'is now current device' in output
204 output = u_boot_console.run_command('echo $?')
205 assert output.endswith('0')
206
207 if fail:
208 pytest.fail('USB device not present')
209
210 return devices, controllers, storage_device
211
212@pytest.mark.buildconfigspec('cmd_usb')
213def test_usb_part(u_boot_console):
214 devices, controllers, storage_device = test_usb_dev(u_boot_console)
215 if not devices:
216 pytest.skip('No devices detected')
217
218 u_boot_console.run_command('usb part')
219
220 output = u_boot_console.run_command('echo $?')
221 assert output.endswith('0')
222
223 for i in range(0, storage_device):
224 if devices[i]['detected'] == 'yes':
225 u_boot_console.run_command('usb dev %d' % i)
226 output = u_boot_console.run_command('usb part')
227
228 lines = output.split('\n')
229 part_fat = []
230 part_ext = []
231 for line in lines:
232 obj = re.search(r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line)
233 if obj:
234 part_id = int(obj.groups()[0])
235 part_type = obj.groups()[1]
236 print('part_id:%d, part_type:%s' % (part_id, part_type))
237
238 if part_type == '0c' or part_type == '0b' or part_type == '0e':
239 print('Fat detected')
240 part_fat.append(part_id)
241 elif part_type == '83':
242 print('ext detected')
243 part_ext.append(part_id)
244 else:
245 pytest.fail('Unsupported Filesystem on device %d' % i)
246 devices[i]['ext4'] = part_ext
247 devices[i]['ext2'] = part_ext
248 devices[i]['fat'] = part_fat
249
250 if not part_ext and not part_fat:
251 pytest.fail('No partition detected on device %d' % i)
252
253 return devices, controllers, storage_device
254
255@pytest.mark.buildconfigspec('cmd_usb')
256@pytest.mark.buildconfigspec('cmd_fat')
257def test_usb_fatls_fatinfo(u_boot_console):
258 devices, controllers, storage_device = test_usb_part(u_boot_console)
259 if not devices:
260 pytest.skip('No devices detected')
261
262 part_detect = 0
263 fs = 'fat'
264 for x in range(0, int(storage_device)):
265 if devices[x]['detected'] == 'yes':
266 u_boot_console.run_command('usb dev %d' % x)
267 try:
268 partitions = devices[x][fs]
269 except:
270 print('No %s table on this device' % fs.upper())
271 continue
272
273 for part in partitions:
274 output = u_boot_console.run_command('fatls usb %d:%s' % (x, part))
275 if 'Unrecognized filesystem type' in output:
276 partitions.remove(part)
277 pytest.fail('Unrecognized filesystem')
278
279 if not re.search(r'\d file\(s\), \d dir\(s\)', output):
280 pytest.fail('%s read failed on device %d' % (fs.upper, x))
281
282 output = u_boot_console.run_command('fatinfo usb %d:%s' % (x, part))
283 string = 'Filesystem: %s' % fs.upper
284 if re.search(string, output):
285 pytest.fail('%s FS failed on device %d' % (fs.upper(), x))
286 part_detect = 1
287
288 if not part_detect:
289 pytest.skip('No %s partition detected' % fs.upper())
290
291@pytest.mark.buildconfigspec('cmd_usb')
292@pytest.mark.buildconfigspec('cmd_fat')
293@pytest.mark.buildconfigspec('cmd_memory')
294def test_usb_fatload_fatwrite(u_boot_console):
295 devices, controllers, storage_device = test_usb_part(u_boot_console)
296 if not devices:
297 pytest.skip('No devices detected')
298
299 part_detect = 0
300 fs = 'fat'
301 for x in range(0, int(storage_device)):
302 if devices[x]['detected'] == 'yes':
303 u_boot_console.run_command('usb dev %d' % x)
304 try:
305 partitions = devices[x][fs]
306 except:
307 print('No %s table on this device' % fs.upper())
308 continue
309
310 for part in partitions:
311 part_detect = 1
312 addr = u_boot_utils.find_ram_base(u_boot_console)
313 size = random.randint(4, 1 * 1024 * 1024)
314 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
315 m = re.search('==> (.+?)', output)
316 if not m:
317 pytest.fail('CRC32 failed')
318 expected_crc32 = m.group(1)
319
320 file = '%s_%d' % ('uboot_test', size)
321 output = u_boot_console.run_command(
322 '%swrite usb %d:%s %x %s %x' % (fs, x, part, addr, file, size)
323 )
324 assert 'Unable to write' not in output
325 assert 'Error' not in output
326 assert 'overflow' not in output
327 expected_text = '%d bytes written' % size
328 assert expected_text in output
329
330 alignment = int(
331 u_boot_console.config.buildconfig.get(
332 'config_sys_cacheline_size', 128
333 )
334 )
335 offset = random.randrange(alignment, 1024, alignment)
336 output = u_boot_console.run_command(
337 '%sload usb %d:%s %x %s' % (fs, x, part, addr + offset, file)
338 )
339 assert 'Invalid FAT entry' not in output
340 assert 'Unable to read file' not in output
341 assert 'Misaligned buffer address' not in output
342 expected_text = '%d bytes read' % size
343 assert expected_text in output
344
345 output = u_boot_console.run_command(
346 'crc32 %x $filesize' % (addr + offset)
347 )
348 assert expected_crc32 in output
349
350 if not part_detect:
351 pytest.skip('No %s partition detected' % fs.upper())
352
353 return file, size
354
355@pytest.mark.buildconfigspec('cmd_usb')
356@pytest.mark.buildconfigspec('cmd_ext4')
357def test_usb_ext4ls(u_boot_console):
358 devices, controllers, storage_device = test_usb_part(u_boot_console)
359 if not devices:
360 pytest.skip('No devices detected')
361
362 part_detect = 0
363 fs = 'ext4'
364 for x in range(0, int(storage_device)):
365 if devices[x]['detected'] == 'yes':
366 try:
367 partitions = devices[x][fs]
368 except:
369 print('No %s table on this device' % fs.upper())
370 continue
371
372 u_boot_console.run_command('usb dev %d' % x)
373 for part in partitions:
374 output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part))
375 if 'Unrecognized filesystem type' in output:
376 partitions.remove(part)
377 pytest.fail('Unrecognized filesystem')
378 part_detect = 1
379
380 if not part_detect:
381 pytest.skip('No %s partition detected' % fs.upper())
382
383@pytest.mark.buildconfigspec('cmd_usb')
384@pytest.mark.buildconfigspec('cmd_ext4')
385@pytest.mark.buildconfigspec('ext4_write')
386@pytest.mark.buildconfigspec('cmd_memory')
387def test_usb_ext4load_ext4write(u_boot_console):
388 devices, controllers, storage_device = test_usb_part(u_boot_console)
389 if not devices:
390 pytest.skip('No devices detected')
391
392 part_detect = 0
393 fs = 'ext4'
394 for x in range(0, int(storage_device)):
395 if devices[x]['detected'] == 'yes':
396 u_boot_console.run_command('usb dev %d' % x)
397 try:
398 partitions = devices[x][fs]
399 except:
400 print('No %s table on this device' % fs.upper())
401 continue
402
403 for part in partitions:
404 part_detect = 1
405 addr = u_boot_utils.find_ram_base(u_boot_console)
406 size = random.randint(4, 1 * 1024 * 1024)
407 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
408 m = re.search('==> (.+?)', output)
409 if not m:
410 pytest.fail('CRC32 failed')
411 expected_crc32 = m.group(1)
412 file = '%s_%d' % ('uboot_test', size)
413
414 output = u_boot_console.run_command(
415 '%swrite usb %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
416 )
417 assert 'Unable to write' not in output
418 assert 'Error' not in output
419 assert 'overflow' not in output
420 expected_text = '%d bytes written' % size
421 assert expected_text in output
422
423 offset = random.randrange(128, 1024, 128)
424 output = u_boot_console.run_command(
425 '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
426 )
427 expected_text = '%d bytes read' % size
428 assert expected_text in output
429
430 output = u_boot_console.run_command(
431 'crc32 %x $filesize' % (addr + offset)
432 )
433 assert expected_crc32 in output
434
435 if not part_detect:
436 pytest.skip('No %s partition detected' % fs.upper())
437
438 return file, size
439
440@pytest.mark.buildconfigspec('cmd_usb')
441@pytest.mark.buildconfigspec('cmd_ext2')
442def test_usb_ext2ls(u_boot_console):
443 devices, controllers, storage_device = test_usb_part(u_boot_console)
444 if not devices:
445 pytest.skip('No devices detected')
446
447 part_detect = 0
448 fs = 'ext2'
449 for x in range(0, int(storage_device)):
450 if devices[x]['detected'] == 'yes':
451 u_boot_console.run_command('usb dev %d' % x)
452 try:
453 partitions = devices[x][fs]
454 except:
455 print('No %s table on this device' % fs.upper())
456 continue
457
458 for part in partitions:
459 part_detect = 1
460 output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part))
461 if 'Unrecognized filesystem type' in output:
462 partitions.remove(part)
463 pytest.fail('Unrecognized filesystem')
464 part_detect = 1
465
466 if not part_detect:
467 pytest.skip('No %s partition detected' % fs.upper())
468
469@pytest.mark.buildconfigspec('cmd_usb')
470@pytest.mark.buildconfigspec('cmd_ext2')
471@pytest.mark.buildconfigspec('cmd_ext4')
472@pytest.mark.buildconfigspec('ext4_write')
473@pytest.mark.buildconfigspec('cmd_memory')
474def test_usb_ext2load(u_boot_console):
475 devices, controllers, storage_device = test_usb_part(u_boot_console)
476 file, size = test_usb_ext4load_ext4write(u_boot_console)
477
478 if not devices:
479 pytest.skip('No devices detected')
480
481 part_detect = 0
482 fs = 'ext2'
483 for x in range(0, int(storage_device)):
484 if devices[x]['detected'] == 'yes':
485 u_boot_console.run_command('usb dev %d' % x)
486 try:
487 partitions = devices[x][fs]
488 except:
489 print('No %s table on this device' % fs.upper())
490 continue
491
492 for part in partitions:
493 part_detect = 1
494 addr = u_boot_utils.find_ram_base(u_boot_console)
495 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
496 m = re.search('==> (.+?)', output)
497 if not m:
498 pytest.fail('CRC32 failed')
499 expected_crc32 = m.group(1)
500
501 offset = random.randrange(128, 1024, 128)
502 output = u_boot_console.run_command(
503 '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
504 )
505 expected_text = '%d bytes read' % size
506 assert expected_text in output
507
508 output = u_boot_console.run_command(
509 'crc32 %x $filesize' % (addr + offset)
510 )
511 assert expected_crc32 in output
512
513 if not part_detect:
514 pytest.skip('No %s partition detected' % fs.upper())
515
516@pytest.mark.buildconfigspec('cmd_usb')
517@pytest.mark.buildconfigspec('cmd_fs_generic')
518def test_usb_ls(u_boot_console):
519 devices, controllers, storage_device = test_usb_part(u_boot_console)
520 if not devices:
521 pytest.skip('No devices detected')
522
523 part_detect = 0
524 for x in range(0, int(storage_device)):
525 if devices[x]['detected'] == 'yes':
526 u_boot_console.run_command('usb dev %d' % x)
527 for fs in ['fat', 'ext4']:
528 try:
529 partitions = devices[x][fs]
530 except:
531 print('No %s table on this device' % fs.upper())
532 continue
533
534 for part in partitions:
535 part_detect = 1
536 output = u_boot_console.run_command('ls usb %d:%s' % (x, part))
537 if re.search(r'No \w+ table on this device', output):
538 pytest.fail(
539 '%s: Partition table not found %d' % (fs.upper(), x)
540 )
541
542 if not part_detect:
543 pytest.skip('No partition detected')
544
545@pytest.mark.buildconfigspec('cmd_usb')
546@pytest.mark.buildconfigspec('cmd_fs_generic')
547def test_usb_load(u_boot_console):
548 devices, controllers, storage_device = test_usb_part(u_boot_console)
549 if not devices:
550 pytest.skip('No devices detected')
551
552 part_detect = 0
553 for x in range(0, int(storage_device)):
554 if devices[x]['detected'] == 'yes':
555 u_boot_console.run_command('usb dev %d' % x)
556 for fs in ['fat', 'ext4']:
557 try:
558 partitions = devices[x][fs]
559 except:
560 print('No %s table on this device' % fs.upper())
561 continue
562
563 for part in partitions:
564 part_detect = 1
565 addr = u_boot_utils.find_ram_base(u_boot_console)
566
567 if fs == 'fat':
568 file, size = test_usb_fatload_fatwrite(u_boot_console)
569 elif fs == 'ext4':
570 file, size = test_usb_ext4load_ext4write(u_boot_console)
571
572 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
573 m = re.search('==> (.+?)', output)
574 if not m:
575 pytest.fail('CRC32 failed')
576 expected_crc32 = m.group(1)
577
578 offset = random.randrange(128, 1024, 128)
579 output = u_boot_console.run_command(
580 'load usb %d:%s %x /%s' % (x, part, addr + offset, file)
581 )
582 expected_text = '%d bytes read' % size
583 assert expected_text in output
584
585 output = u_boot_console.run_command(
586 'crc32 %x $filesize' % (addr + offset)
587 )
588 assert expected_crc32 in output
589
590 if not part_detect:
591 pytest.skip('No partition detected')
592
593@pytest.mark.buildconfigspec('cmd_usb')
594@pytest.mark.buildconfigspec('cmd_fs_generic')
595def test_usb_save(u_boot_console):
596 devices, controllers, storage_device = test_usb_part(u_boot_console)
597 if not devices:
598 pytest.skip('No devices detected')
599
600 part_detect = 0
601 for x in range(0, int(storage_device)):
602 if devices[x]['detected'] == 'yes':
603 u_boot_console.run_command('usb dev %d' % x)
604 for fs in ['fat', 'ext4']:
605 try:
606 partitions = devices[x][fs]
607 except:
608 print('No %s table on this device' % fs.upper())
609 continue
610
611 for part in partitions:
612 part_detect = 1
613 addr = u_boot_utils.find_ram_base(u_boot_console)
614 size = random.randint(4, 1 * 1024 * 1024)
615 file = '%s_%d' % ('uboot_test', size)
616
617 offset = random.randrange(128, 1024, 128)
618 output = u_boot_console.run_command(
619 'save usb %d:%s %x /%s %x'
620 % (x, part, addr + offset, file, size)
621 )
622 expected_text = '%d bytes written' % size
623 assert expected_text in output
624
625 if not part_detect:
626 pytest.skip('No partition detected')