blob: 2397fd3c2e7a8e12de425c27bd996cc5f3376e42 [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
Andrew Goodbody97086f92024-10-15 13:19:16 +0100291def usb_fatload_fatwrite(u_boot_console, fs, x, part):
292 addr = u_boot_utils.find_ram_base(u_boot_console)
293 size = random.randint(4, 1 * 1024 * 1024)
294 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
295 m = re.search('==> (.+?)', output)
296 if not m:
297 pytest.fail('CRC32 failed')
298 expected_crc32 = m.group(1)
299
300 file = '%s_%d' % ('uboot_test', size)
301 output = u_boot_console.run_command(
302 '%swrite usb %d:%s %x %s %x' % (fs, x, part, addr, file, size)
303 )
304 assert 'Unable to write' not in output
305 assert 'Error' not in output
306 assert 'overflow' not in output
307 expected_text = '%d bytes written' % size
308 assert expected_text in output
309
310 alignment = int(
311 u_boot_console.config.buildconfig.get(
312 'config_sys_cacheline_size', 128
313 )
314 )
315 offset = random.randrange(alignment, 1024, alignment)
316 output = u_boot_console.run_command(
317 '%sload usb %d:%s %x %s' % (fs, x, part, addr + offset, file)
318 )
319 assert 'Invalid FAT entry' not in output
320 assert 'Unable to read file' not in output
321 assert 'Misaligned buffer address' not in output
322 expected_text = '%d bytes read' % size
323 assert expected_text in output
324
325 output = u_boot_console.run_command(
326 'crc32 %x $filesize' % (addr + offset)
327 )
328 assert expected_crc32 in output
329
330 return file, size, expected_crc32
331
Love Kumar6c91f092024-01-19 19:56:02 +0530332@pytest.mark.buildconfigspec('cmd_usb')
333@pytest.mark.buildconfigspec('cmd_fat')
334@pytest.mark.buildconfigspec('cmd_memory')
335def test_usb_fatload_fatwrite(u_boot_console):
336 devices, controllers, storage_device = test_usb_part(u_boot_console)
337 if not devices:
338 pytest.skip('No devices detected')
339
340 part_detect = 0
341 fs = 'fat'
342 for x in range(0, int(storage_device)):
343 if devices[x]['detected'] == 'yes':
344 u_boot_console.run_command('usb dev %d' % x)
345 try:
346 partitions = devices[x][fs]
347 except:
348 print('No %s table on this device' % fs.upper())
349 continue
350
351 for part in partitions:
352 part_detect = 1
Andrew Goodbody97086f92024-10-15 13:19:16 +0100353 usb_fatload_fatwrite(u_boot_console, fs, x, part)
Love Kumar6c91f092024-01-19 19:56:02 +0530354
355 if not part_detect:
356 pytest.skip('No %s partition detected' % fs.upper())
357
Love Kumar6c91f092024-01-19 19:56:02 +0530358@pytest.mark.buildconfigspec('cmd_usb')
359@pytest.mark.buildconfigspec('cmd_ext4')
360def test_usb_ext4ls(u_boot_console):
361 devices, controllers, storage_device = test_usb_part(u_boot_console)
362 if not devices:
363 pytest.skip('No devices detected')
364
365 part_detect = 0
366 fs = 'ext4'
367 for x in range(0, int(storage_device)):
368 if devices[x]['detected'] == 'yes':
369 try:
370 partitions = devices[x][fs]
371 except:
372 print('No %s table on this device' % fs.upper())
373 continue
374
375 u_boot_console.run_command('usb dev %d' % x)
376 for part in partitions:
377 output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part))
378 if 'Unrecognized filesystem type' in output:
379 partitions.remove(part)
380 pytest.fail('Unrecognized filesystem')
381 part_detect = 1
382
383 if not part_detect:
384 pytest.skip('No %s partition detected' % fs.upper())
385
Andrew Goodbody97086f92024-10-15 13:19:16 +0100386def usb_ext4load_ext4write(u_boot_console, fs, x, part):
387 addr = u_boot_utils.find_ram_base(u_boot_console)
388 size = random.randint(4, 1 * 1024 * 1024)
389 output = u_boot_console.run_command('crc32 %x %x' % (addr, size))
390 m = re.search('==> (.+?)', output)
391 if not m:
392 pytest.fail('CRC32 failed')
393 expected_crc32 = m.group(1)
394 file = '%s_%d' % ('uboot_test', size)
395
396 output = u_boot_console.run_command(
397 '%swrite usb %d:%s %x /%s %x' % (fs, x, part, addr, file, size)
398 )
399 assert 'Unable to write' not in output
400 assert 'Error' not in output
401 assert 'overflow' not in output
402 expected_text = '%d bytes written' % size
403 assert expected_text in output
404
405 offset = random.randrange(128, 1024, 128)
406 output = u_boot_console.run_command(
407 '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
408 )
409 expected_text = '%d bytes read' % size
410 assert expected_text in output
411
412 output = u_boot_console.run_command(
413 'crc32 %x $filesize' % (addr + offset)
414 )
415 assert expected_crc32 in output
416
417 return file, size, expected_crc32
418
Love Kumar6c91f092024-01-19 19:56:02 +0530419@pytest.mark.buildconfigspec('cmd_usb')
420@pytest.mark.buildconfigspec('cmd_ext4')
Andrew Goodbodyedef1c62024-10-15 15:17:37 +0100421@pytest.mark.buildconfigspec('cmd_ext4_write')
Love Kumar6c91f092024-01-19 19:56:02 +0530422@pytest.mark.buildconfigspec('cmd_memory')
423def test_usb_ext4load_ext4write(u_boot_console):
424 devices, controllers, storage_device = test_usb_part(u_boot_console)
425 if not devices:
426 pytest.skip('No devices detected')
427
428 part_detect = 0
429 fs = 'ext4'
430 for x in range(0, int(storage_device)):
431 if devices[x]['detected'] == 'yes':
432 u_boot_console.run_command('usb dev %d' % x)
433 try:
434 partitions = devices[x][fs]
435 except:
436 print('No %s table on this device' % fs.upper())
437 continue
438
439 for part in partitions:
440 part_detect = 1
Andrew Goodbody97086f92024-10-15 13:19:16 +0100441 usb_ext4load_ext4write(u_boot_console, fs, x, part)
Love Kumar6c91f092024-01-19 19:56:02 +0530442
443 if not part_detect:
444 pytest.skip('No %s partition detected' % fs.upper())
445
Love Kumar6c91f092024-01-19 19:56:02 +0530446@pytest.mark.buildconfigspec('cmd_usb')
447@pytest.mark.buildconfigspec('cmd_ext2')
448def test_usb_ext2ls(u_boot_console):
449 devices, controllers, storage_device = test_usb_part(u_boot_console)
450 if not devices:
451 pytest.skip('No devices detected')
452
453 part_detect = 0
454 fs = 'ext2'
455 for x in range(0, int(storage_device)):
456 if devices[x]['detected'] == 'yes':
457 u_boot_console.run_command('usb dev %d' % x)
458 try:
459 partitions = devices[x][fs]
460 except:
461 print('No %s table on this device' % fs.upper())
462 continue
463
464 for part in partitions:
465 part_detect = 1
466 output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part))
467 if 'Unrecognized filesystem type' in output:
468 partitions.remove(part)
469 pytest.fail('Unrecognized filesystem')
470 part_detect = 1
471
472 if not part_detect:
473 pytest.skip('No %s partition detected' % fs.upper())
474
475@pytest.mark.buildconfigspec('cmd_usb')
476@pytest.mark.buildconfigspec('cmd_ext2')
477@pytest.mark.buildconfigspec('cmd_ext4')
Andrew Goodbodyedef1c62024-10-15 15:17:37 +0100478@pytest.mark.buildconfigspec('cmd_ext4_write')
Love Kumar6c91f092024-01-19 19:56:02 +0530479@pytest.mark.buildconfigspec('cmd_memory')
480def test_usb_ext2load(u_boot_console):
481 devices, controllers, storage_device = test_usb_part(u_boot_console)
Love Kumar6c91f092024-01-19 19:56:02 +0530482
483 if not devices:
484 pytest.skip('No devices detected')
485
486 part_detect = 0
487 fs = 'ext2'
488 for x in range(0, int(storage_device)):
489 if devices[x]['detected'] == 'yes':
490 u_boot_console.run_command('usb dev %d' % x)
491 try:
492 partitions = devices[x][fs]
493 except:
494 print('No %s table on this device' % fs.upper())
495 continue
496
497 for part in partitions:
498 part_detect = 1
Andrew Goodbody97086f92024-10-15 13:19:16 +0100499 file, size, expected_crc32 = \
500 usb_ext4load_ext4write(u_boot_console, 'ext4', x, part)
Love Kumar6c91f092024-01-19 19:56:02 +0530501 addr = u_boot_utils.find_ram_base(u_boot_console)
Love Kumar6c91f092024-01-19 19:56:02 +0530502
503 offset = random.randrange(128, 1024, 128)
504 output = u_boot_console.run_command(
505 '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file)
506 )
507 expected_text = '%d bytes read' % size
508 assert expected_text in output
509
510 output = u_boot_console.run_command(
511 'crc32 %x $filesize' % (addr + offset)
512 )
513 assert expected_crc32 in output
514
515 if not part_detect:
516 pytest.skip('No %s partition detected' % fs.upper())
517
518@pytest.mark.buildconfigspec('cmd_usb')
519@pytest.mark.buildconfigspec('cmd_fs_generic')
520def test_usb_ls(u_boot_console):
521 devices, controllers, storage_device = test_usb_part(u_boot_console)
522 if not devices:
523 pytest.skip('No devices detected')
524
525 part_detect = 0
526 for x in range(0, int(storage_device)):
527 if devices[x]['detected'] == 'yes':
528 u_boot_console.run_command('usb dev %d' % x)
529 for fs in ['fat', 'ext4']:
530 try:
531 partitions = devices[x][fs]
532 except:
533 print('No %s table on this device' % fs.upper())
534 continue
535
536 for part in partitions:
537 part_detect = 1
538 output = u_boot_console.run_command('ls usb %d:%s' % (x, part))
539 if re.search(r'No \w+ table on this device', output):
540 pytest.fail(
541 '%s: Partition table not found %d' % (fs.upper(), x)
542 )
543
544 if not part_detect:
545 pytest.skip('No partition detected')
546
547@pytest.mark.buildconfigspec('cmd_usb')
Andrew Goodbodyedef1c62024-10-15 15:17:37 +0100548@pytest.mark.buildconfigspec('cmd_ext4_write')
Love Kumar6c91f092024-01-19 19:56:02 +0530549@pytest.mark.buildconfigspec('cmd_fs_generic')
550def test_usb_load(u_boot_console):
551 devices, controllers, storage_device = test_usb_part(u_boot_console)
552 if not devices:
553 pytest.skip('No devices detected')
554
555 part_detect = 0
556 for x in range(0, int(storage_device)):
557 if devices[x]['detected'] == 'yes':
558 u_boot_console.run_command('usb dev %d' % x)
559 for fs in ['fat', 'ext4']:
560 try:
561 partitions = devices[x][fs]
562 except:
563 print('No %s table on this device' % fs.upper())
564 continue
565
566 for part in partitions:
567 part_detect = 1
568 addr = u_boot_utils.find_ram_base(u_boot_console)
569
570 if fs == 'fat':
Andrew Goodbody97086f92024-10-15 13:19:16 +0100571 file, size, expected_crc32 = \
572 usb_fatload_fatwrite(u_boot_console, fs, x, part)
Love Kumar6c91f092024-01-19 19:56:02 +0530573 elif fs == 'ext4':
Andrew Goodbody97086f92024-10-15 13:19:16 +0100574 file, size, expected_crc32 = \
575 usb_ext4load_ext4write(u_boot_console, fs, x, part)
Love Kumar6c91f092024-01-19 19:56:02 +0530576
577 offset = random.randrange(128, 1024, 128)
578 output = u_boot_console.run_command(
579 'load usb %d:%s %x /%s' % (x, part, addr + offset, file)
580 )
581 expected_text = '%d bytes read' % size
582 assert expected_text in output
583
584 output = u_boot_console.run_command(
585 'crc32 %x $filesize' % (addr + offset)
586 )
587 assert expected_crc32 in output
588
589 if not part_detect:
590 pytest.skip('No partition detected')
591
592@pytest.mark.buildconfigspec('cmd_usb')
593@pytest.mark.buildconfigspec('cmd_fs_generic')
594def test_usb_save(u_boot_console):
595 devices, controllers, storage_device = test_usb_part(u_boot_console)
596 if not devices:
597 pytest.skip('No devices detected')
598
599 part_detect = 0
600 for x in range(0, int(storage_device)):
601 if devices[x]['detected'] == 'yes':
602 u_boot_console.run_command('usb dev %d' % x)
603 for fs in ['fat', 'ext4']:
604 try:
605 partitions = devices[x][fs]
606 except:
607 print('No %s table on this device' % fs.upper())
608 continue
609
610 for part in partitions:
611 part_detect = 1
612 addr = u_boot_utils.find_ram_base(u_boot_console)
613 size = random.randint(4, 1 * 1024 * 1024)
614 file = '%s_%d' % ('uboot_test', size)
615
616 offset = random.randrange(128, 1024, 128)
617 output = u_boot_console.run_command(
618 'save usb %d:%s %x /%s %x'
619 % (x, part, addr + offset, file, size)
620 )
621 expected_text = '%d bytes written' % size
622 assert expected_text in output
623
624 if not part_detect:
625 pytest.skip('No partition detected')