1# SPDX-License-Identifier: GPL-2.0 2# (C) Copyright 2024, Advanced Micro Devices, Inc. 3 4""" 5Note: This test relies on boardenv_* containing configuration values to define 6spi minimum and maximum frequencies at which the flash part can operate on and 7these tests run at different spi frequency randomised values in the range 8multiple times based on the user defined iteration value. 9It also defines the SPI bus number containing the SPI-flash chip, SPI 10chip-select, SPI mode, SPI flash part name and timeout parameters. If minimum 11and maximum frequency is not defined, it will run on freq 0 by default. 12 13Without the boardenv_* configuration, this test will be automatically skipped. 14 15It also relies on configuration values for supported flashes for lock and 16unlock cases for SPI family flash. It will run lock-unlock cases only for the 17supported flash parts. 18 19For Example: 20 21# Details of SPI device test parameters required for SPI device testing: 22 23# bus - SPI bus number to init the flash device 24# chip_select - SPI chip select number to init the flash device 25# min_freq - Minimum frequency in hz at which the flash part can operate, set 0 26# or None for default frequency 27# max_freq - Maximum frequency in hz at which the flash part can operate, set 0 28# or None for default frequency 29# mode - SPI mode to init the flash device 30# part_name - SPI flash part name to be detected 31# timeout - Default timeout to run the sf commands 32# iteration - No of iteration to run SPI flash test 33 34env__spi_device_test = { 35 'bus': 0, 36 'chip_select': 0, 37 'min_freq': 10000000, 38 'max_freq': 100000000, 39 'mode': 0, 40 'part_name': 'n25q00a', 41 'timeout': 100000, 42 'iteration': 5, 43} 44 45# supported_flash - Flash parts name which support lock-unlock functionality 46env__spi_lock_unlock = { 47 'supported_flash': 'mt25qu512a, n25q00a, n25q512ax3', 48} 49""" 50 51import random 52import re 53import pytest 54import utils 55 56SPI_DATA = {} 57EXPECTED_ERASE = 'Erased: OK' 58EXPECTED_WRITE = 'Written: OK' 59EXPECTED_READ = 'Read: OK' 60EXPECTED_ERASE_ERRORS = [ 61 'Erase operation failed', 62 'Attempted to modify a protected sector', 63 'Erased: ERROR', 64 'is protected and cannot be erased', 65 'ERROR: flash area is locked', 66] 67EXPECTED_WRITE_ERRORS = [ 68 'ERROR: flash area is locked', 69 'Program operation failed', 70 'Attempted to modify a protected sector', 71 'Written: ERROR', 72] 73 74def get_params_spi(ubman): 75 ''' Get SPI device test parameters from boardenv file ''' 76 f = ubman.config.env.get('env__spi_device_test', None) 77 if not f: 78 pytest.skip('No SPI test device configured') 79 80 bus = f.get('bus', 0) 81 cs = f.get('chip_select', 0) 82 mode = f.get('mode', 0) 83 part_name = f.get('part_name', None) 84 timeout = f.get('timeout', None) 85 86 if not part_name: 87 pytest.skip('No SPI test device configured') 88 89 return bus, cs, mode, part_name, timeout 90 91def spi_find_freq_range(ubman): 92 '''Find out minimum and maximum frequnecies that SPI device can operate''' 93 f = ubman.config.env.get('env__spi_device_test', None) 94 if not f: 95 pytest.skip('No SPI test device configured') 96 97 min_f = f.get('min_freq', None) 98 max_f = f.get('max_freq', None) 99 iterations = f.get('iteration', 1) 100 101 if not min_f: 102 min_f = 0 103 if not max_f: 104 max_f = 0 105 106 max_f = max(max_f, min_f) 107 108 return min_f, max_f, iterations 109 110def spi_pre_commands(ubman, freq): 111 ''' Find out SPI family flash memory parameters ''' 112 bus, cs, mode, part_name, timeout = get_params_spi(ubman) 113 114 output = ubman.run_command(f'sf probe {bus}:{cs} {freq} {mode}') 115 if not 'SF: Detected' in output: 116 pytest.fail('No SPI device available') 117 118 if not part_name in output: 119 pytest.fail('Not recognized the SPI flash part name') 120 121 m = re.search('page size (.+?) Bytes', output) 122 assert m 123 try: 124 page_size = int(m.group(1)) 125 except ValueError: 126 pytest.fail('Not recognized the SPI page size') 127 128 m = re.search('erase size (.+?) KiB', output) 129 assert m 130 try: 131 erase_size = int(m.group(1)) 132 erase_size *= 1024 133 except ValueError: 134 pytest.fail('Not recognized the SPI erase size') 135 136 m = re.search('total (.+?) MiB', output) 137 assert m 138 try: 139 total_size = int(m.group(1)) 140 total_size *= 1024 * 1024 141 except ValueError: 142 pytest.fail('Not recognized the SPI total size') 143 144 m = re.search('Detected (.+?) with', output) 145 assert m 146 try: 147 flash_part = m.group(1) 148 assert flash_part == part_name 149 except ValueError: 150 pytest.fail('Not recognized the SPI flash part') 151 152 global SPI_DATA 153 SPI_DATA = { 154 'page_size': page_size, 155 'erase_size': erase_size, 156 'total_size': total_size, 157 'flash_part': flash_part, 158 'timeout': timeout, 159 } 160 161def get_page_size(): 162 ''' Get the SPI page size from spi data ''' 163 return SPI_DATA['page_size'] 164 165def get_erase_size(): 166 ''' Get the SPI erase size from spi data ''' 167 return SPI_DATA['erase_size'] 168 169def get_total_size(): 170 ''' Get the SPI total size from spi data ''' 171 return SPI_DATA['total_size'] 172 173def get_flash_part(): 174 ''' Get the SPI flash part name from spi data ''' 175 return SPI_DATA['flash_part'] 176 177def get_timeout(): 178 ''' Get the SPI timeout from spi data ''' 179 return SPI_DATA['timeout'] 180 181def spi_erase_block(ubman, erase_size, total_size): 182 ''' Erase SPI flash memory block wise ''' 183 for start in range(0, total_size, erase_size): 184 output = ubman.run_command(f'sf erase {hex(start)} {hex(erase_size)}') 185 assert EXPECTED_ERASE in output 186 187@pytest.mark.buildconfigspec('cmd_sf') 188def test_spi_erase_block(ubman): 189 ''' Test case to check SPI erase functionality by erasing memory regions 190 block-wise ''' 191 192 min_f, max_f, loop = spi_find_freq_range(ubman) 193 i = 0 194 while i < loop: 195 spi_pre_commands(ubman, random.randint(min_f, max_f)) 196 spi_erase_block(ubman, get_erase_size(), get_total_size()) 197 i = i + 1 198 199def spi_write_twice(ubman, page_size, erase_size, total_size, timeout): 200 ''' Random write till page size, random till size and full size ''' 201 addr = utils.find_ram_base(ubman) 202 203 old_size = 0 204 for size in ( 205 random.randint(4, page_size), 206 random.randint(page_size, total_size), 207 total_size, 208 ): 209 offset = random.randint(4, page_size) 210 offset = offset & ~3 211 size = size & ~3 212 size = size - old_size 213 output = ubman.run_command(f'crc32 {hex(addr + total_size)} {hex(size)}') 214 m = re.search('==> (.+?)$', output) 215 if not m: 216 pytest.fail('CRC32 failed') 217 218 expected_crc32 = m.group(1) 219 if old_size % page_size: 220 old_size = int(old_size / page_size) 221 old_size *= page_size 222 223 if size % erase_size: 224 erasesize = int(size / erase_size + 1) 225 erasesize *= erase_size 226 227 eraseoffset = int(old_size / erase_size) 228 eraseoffset *= erase_size 229 230 timeout = 100000000 231 with ubman.temporary_timeout(timeout): 232 output = ubman.run_command( 233 f'sf erase {hex(eraseoffset)} {hex(erasesize)}' 234 ) 235 assert EXPECTED_ERASE in output 236 237 with ubman.temporary_timeout(timeout): 238 output = ubman.run_command( 239 f'sf write {hex(addr + total_size)} {hex(old_size)} {hex(size)}' 240 ) 241 assert EXPECTED_WRITE in output 242 with ubman.temporary_timeout(timeout): 243 output = ubman.run_command( 244 f'sf read {hex(addr + total_size + offset)} {hex(old_size)} {hex(size)}' 245 ) 246 assert EXPECTED_READ in output 247 output = ubman.run_command( 248 f'crc32 {hex(addr + total_size + offset)} {hex(size)}' 249 ) 250 assert expected_crc32 in output 251 old_size = size 252 253@pytest.mark.buildconfigspec('cmd_bdi') 254@pytest.mark.buildconfigspec('cmd_sf') 255@pytest.mark.buildconfigspec('cmd_memory') 256def test_spi_write_twice(ubman): 257 ''' Test to write data with random size twice for SPI ''' 258 min_f, max_f, loop = spi_find_freq_range(ubman) 259 i = 0 260 while i < loop: 261 spi_pre_commands(ubman, random.randint(min_f, max_f)) 262 spi_write_twice( 263 ubman, 264 get_page_size(), 265 get_erase_size(), 266 get_total_size(), 267 get_timeout() 268 ) 269 i = i + 1 270 271def spi_write_continues(ubman, page_size, erase_size, total_size, timeout): 272 ''' Write with random size of data to continue SPI write case ''' 273 spi_erase_block(ubman, erase_size, total_size) 274 addr = utils.find_ram_base(ubman) 275 276 output = ubman.run_command(f'crc32 {hex(addr + 0x10000)} {hex(total_size)}') 277 m = re.search('==> (.+?)$', output) 278 if not m: 279 pytest.fail('CRC32 failed') 280 expected_crc32 = m.group(1) 281 282 old_size = 0 283 for size in ( 284 random.randint(4, page_size), 285 random.randint(page_size, total_size), 286 total_size, 287 ): 288 size = size & ~3 289 size = size - old_size 290 with ubman.temporary_timeout(timeout): 291 output = ubman.run_command( 292 f'sf write {hex(addr + 0x10000 + old_size)} {hex(old_size)} {hex(size)}' 293 ) 294 assert EXPECTED_WRITE in output 295 old_size += size 296 297 with ubman.temporary_timeout(timeout): 298 output = ubman.run_command( 299 f'sf read {hex(addr + 0x10000 + total_size)} 0 {hex(total_size)}' 300 ) 301 assert EXPECTED_READ in output 302 303 output = ubman.run_command( 304 f'crc32 {hex(addr + 0x10000 + total_size)} {hex(total_size)}' 305 ) 306 assert expected_crc32 in output 307 308@pytest.mark.buildconfigspec('cmd_bdi') 309@pytest.mark.buildconfigspec('cmd_sf') 310@pytest.mark.buildconfigspec('cmd_memory') 311def test_spi_write_continues(ubman): 312 ''' Test to write more random size data for SPI ''' 313 min_f, max_f, loop = spi_find_freq_range(ubman) 314 i = 0 315 while i < loop: 316 spi_pre_commands(ubman, random.randint(min_f, max_f)) 317 spi_write_twice( 318 ubman, 319 get_page_size(), 320 get_erase_size(), 321 get_total_size(), 322 get_timeout(), 323 ) 324 i = i + 1 325 326def spi_read_twice(ubman, page_size, total_size, timeout): 327 ''' Read the whole SPI flash twice, random_size till full flash size, 328 random till page size ''' 329 for size in random.randint(4, page_size), random.randint(4, total_size), total_size: 330 addr = utils.find_ram_base(ubman) 331 size = size & ~3 332 with ubman.temporary_timeout(timeout): 333 output = ubman.run_command( 334 f'sf read {hex(addr + total_size)} 0 {hex(size)}' 335 ) 336 assert EXPECTED_READ in output 337 output = ubman.run_command(f'crc32 {hex(addr + total_size)} {hex(size)}') 338 m = re.search('==> (.+?)$', output) 339 if not m: 340 pytest.fail('CRC32 failed') 341 expected_crc32 = m.group(1) 342 with ubman.temporary_timeout(timeout): 343 output = ubman.run_command( 344 f'sf read {hex(addr + total_size + 10)} 0 {hex(size)}' 345 ) 346 assert EXPECTED_READ in output 347 output = ubman.run_command( 348 f'crc32 {hex(addr + total_size + 10)} {hex(size)}' 349 ) 350 assert expected_crc32 in output 351 352@pytest.mark.buildconfigspec('cmd_sf') 353@pytest.mark.buildconfigspec('cmd_bdi') 354@pytest.mark.buildconfigspec('cmd_memory') 355def test_spi_read_twice(ubman): 356 ''' Test to read random data twice from SPI ''' 357 min_f, max_f, loop = spi_find_freq_range(ubman) 358 i = 0 359 while i < loop: 360 spi_pre_commands(ubman, random.randint(min_f, max_f)) 361 spi_read_twice(ubman, get_page_size(), get_total_size(), get_timeout()) 362 i = i + 1 363 364def spi_erase_all(ubman, total_size, timeout): 365 ''' Erase the full chip SPI ''' 366 start = 0 367 with ubman.temporary_timeout(timeout): 368 output = ubman.run_command(f'sf erase {start} {hex(total_size)}') 369 assert EXPECTED_ERASE in output 370 371@pytest.mark.buildconfigspec('cmd_sf') 372def test_spi_erase_all(ubman): 373 ''' Test to check full chip erase for SPI ''' 374 min_f, max_f, loop = spi_find_freq_range(ubman) 375 i = 0 376 while i < loop: 377 spi_pre_commands(ubman, random.randint(min_f, max_f)) 378 spi_erase_all(ubman, get_total_size(), get_timeout()) 379 i = i + 1 380 381def flash_ops( 382 ubman, ops, start, size, offset=0, exp_ret=0, exp_str='', not_exp_str='' 383): 384 ''' Flash operations: erase, write and read ''' 385 386 f = ubman.config.env.get('env__spi_device_test', None) 387 if not f: 388 timeout = 1000000 389 390 timeout = f.get('timeout', 1000000) 391 392 if ops == 'erase': 393 with ubman.temporary_timeout(timeout): 394 output = ubman.run_command(f'sf erase {hex(start)} {hex(size)}') 395 else: 396 with ubman.temporary_timeout(timeout): 397 output = ubman.run_command( 398 f'sf {ops} {hex(offset)} {hex(start)} {hex(size)}' 399 ) 400 401 if exp_str: 402 assert exp_str in output 403 if not_exp_str: 404 assert not_exp_str not in output 405 406 ret_code = ubman.run_command('echo $?') 407 if exp_ret >= 0: 408 assert ret_code.endswith(str(exp_ret)) 409 410 return output, ret_code 411 412def spi_unlock_exit(ubman, addr, size): 413 ''' Unlock the flash before making it fail ''' 414 ubman.run_command(f'sf protect unlock {hex(addr)} {hex(size)}') 415 assert False, 'FAIL: Flash lock is unable to protect the data!' 416 417def find_prot_region(lock_addr, lock_size): 418 ''' Get the protected and un-protected region of flash ''' 419 total_size = get_total_size() 420 erase_size = get_erase_size() 421 422 if lock_addr < (total_size // 2): 423 sect_num = (lock_addr + lock_size) // erase_size 424 x = 1 425 while x < sect_num: 426 x *= 2 427 prot_start = 0 428 prot_size = x * erase_size 429 unprot_start = prot_start + prot_size 430 unprot_size = total_size - unprot_start 431 else: 432 sect_num = (total_size - lock_addr) // erase_size 433 x = 1 434 while x < sect_num: 435 x *= 2 436 prot_start = total_size - (x * erase_size) 437 prot_size = total_size - prot_start 438 unprot_start = 0 439 unprot_size = prot_start 440 441 return prot_start, prot_size, unprot_start, unprot_size 442 443def protect_ops(ubman, lock_addr, lock_size, ops="unlock"): 444 ''' Run the command to lock or Unlock the flash ''' 445 ubman.run_command(f'sf protect {ops} {hex(lock_addr)} {hex(lock_size)}') 446 output = ubman.run_command('echo $?') 447 if ops == "lock" and not output.endswith('0'): 448 ubman.run_command(f'sf protect unlock {hex(lock_addr)} {hex(lock_size)}') 449 assert False, "sf protect lock command exits with non-zero return code" 450 assert output.endswith('0') 451 452def erase_write_ops(ubman, start, size): 453 ''' Basic erase and write operation for flash ''' 454 addr = utils.find_ram_base(ubman) 455 flash_ops(ubman, 'erase', start, size, 0, 0, EXPECTED_ERASE) 456 flash_ops(ubman, 'write', start, size, addr, 0, EXPECTED_WRITE) 457 458def spi_lock_unlock(ubman, lock_addr, lock_size): 459 ''' Lock unlock operations for SPI family flash ''' 460 addr = utils.find_ram_base(ubman) 461 erase_size = get_erase_size() 462 463 # Find the protected/un-protected region 464 prot_start, prot_size, unprot_start, unprot_size = find_prot_region(lock_addr, lock_size) 465 466 # Check erase/write operation before locking 467 erase_write_ops(ubman, prot_start, prot_size) 468 469 # Locking the flash 470 protect_ops(ubman, lock_addr, lock_size, 'lock') 471 472 # Check erase/write operation after locking 473 output, ret_code = flash_ops(ubman, 'erase', prot_start, prot_size, 0, -1) 474 if not any(error in output for error in EXPECTED_ERASE_ERRORS) or ret_code.endswith( 475 '0' 476 ): 477 spi_unlock_exit(ubman, lock_addr, lock_size) 478 479 output, ret_code = flash_ops( 480 ubman, 'write', prot_start, prot_size, addr, -1 481 ) 482 if not any(error in output for error in EXPECTED_WRITE_ERRORS) or ret_code.endswith( 483 '0' 484 ): 485 spi_unlock_exit(ubman, lock_addr, lock_size) 486 487 # Check locked sectors 488 sect_lock_start = random.randrange(prot_start, (prot_start + prot_size), erase_size) 489 if prot_size > erase_size: 490 sect_lock_size = random.randrange( 491 erase_size, (prot_start + prot_size - sect_lock_start), erase_size 492 ) 493 else: 494 sect_lock_size = erase_size 495 sect_write_size = random.randint(1, sect_lock_size) 496 497 output, ret_code = flash_ops( 498 ubman, 'erase', sect_lock_start, sect_lock_size, 0, -1 499 ) 500 if not any(error in output for error in EXPECTED_ERASE_ERRORS) or ret_code.endswith( 501 '0' 502 ): 503 spi_unlock_exit(ubman, lock_addr, lock_size) 504 505 output, ret_code = flash_ops( 506 ubman, 'write', sect_lock_start, sect_write_size, addr, -1 507 ) 508 if not any(error in output for error in EXPECTED_WRITE_ERRORS) or ret_code.endswith( 509 '0' 510 ): 511 spi_unlock_exit(ubman, lock_addr, lock_size) 512 513 # Check unlocked sectors 514 if unprot_size != 0: 515 sect_unlock_start = random.randrange( 516 unprot_start, (unprot_start + unprot_size), erase_size 517 ) 518 if unprot_size > erase_size: 519 sect_unlock_size = random.randrange( 520 erase_size, (unprot_start + unprot_size - sect_unlock_start), erase_size 521 ) 522 else: 523 sect_unlock_size = erase_size 524 sect_write_size = random.randint(1, sect_unlock_size) 525 526 output, ret_code = flash_ops( 527 ubman, 'erase', sect_unlock_start, sect_unlock_size, 0, -1 528 ) 529 if EXPECTED_ERASE not in output or ret_code.endswith('1'): 530 spi_unlock_exit(ubman, lock_addr, lock_size) 531 532 output, ret_code = flash_ops( 533 ubman, 'write', sect_unlock_start, sect_write_size, addr, -1 534 ) 535 if EXPECTED_WRITE not in output or ret_code.endswith('1'): 536 spi_unlock_exit(ubman, lock_addr, lock_size) 537 538 # Unlocking the flash 539 protect_ops(ubman, lock_addr, lock_size, 'unlock') 540 541 # Check erase/write operation after un-locking 542 erase_write_ops(ubman, prot_start, prot_size) 543 544 # Check previous locked sectors 545 sect_lock_start = random.randrange(prot_start, (prot_start + prot_size), erase_size) 546 if prot_size > erase_size: 547 sect_lock_size = random.randrange( 548 erase_size, (prot_start + prot_size - sect_lock_start), erase_size 549 ) 550 else: 551 sect_lock_size = erase_size 552 sect_write_size = random.randint(1, sect_lock_size) 553 554 flash_ops( 555 ubman, 'erase', sect_lock_start, sect_lock_size, 0, 0, EXPECTED_ERASE 556 ) 557 flash_ops( 558 ubman, 559 'write', 560 sect_lock_start, 561 sect_write_size, 562 addr, 563 0, 564 EXPECTED_WRITE, 565 ) 566 567@pytest.mark.buildconfigspec('cmd_bdi') 568@pytest.mark.buildconfigspec('cmd_sf') 569@pytest.mark.buildconfigspec('cmd_memory') 570def test_spi_lock_unlock(ubman): 571 ''' Test to check the lock-unlock functionality for SPI family flash ''' 572 min_f, max_f, loop = spi_find_freq_range(ubman) 573 flashes = ubman.config.env.get('env__spi_lock_unlock', False) 574 if not flashes: 575 pytest.skip('No SPI test device configured for lock/unlock') 576 577 i = 0 578 while i < loop: 579 spi_pre_commands(ubman, random.randint(min_f, max_f)) 580 total_size = get_total_size() 581 flash_part = get_flash_part() 582 583 flashes_list = flashes.get('supported_flash', None).split(',') 584 flashes_list = [x.strip() for x in flashes_list] 585 if flash_part not in flashes_list: 586 pytest.skip('Detected flash does not support lock/unlock') 587 588 # For lower half of memory 589 lock_addr = random.randint(0, (total_size // 2) - 1) 590 lock_size = random.randint(1, ((total_size // 2) - lock_addr)) 591 spi_lock_unlock(ubman, lock_addr, lock_size) 592 593 # For upper half of memory 594 lock_addr = random.randint((total_size // 2), total_size - 1) 595 lock_size = random.randint(1, (total_size - lock_addr)) 596 spi_lock_unlock(ubman, lock_addr, lock_size) 597 598 # For entire flash 599 lock_addr = random.randint(0, total_size - 1) 600 lock_size = random.randint(1, (total_size - lock_addr)) 601 spi_lock_unlock(ubman, lock_addr, lock_size) 602 603 i = i + 1 604 605@pytest.mark.buildconfigspec('cmd_bdi') 606@pytest.mark.buildconfigspec('cmd_sf') 607@pytest.mark.buildconfigspec('cmd_memory') 608def test_spi_negative(ubman): 609 ''' Negative tests for SPI ''' 610 min_f, max_f, loop = spi_find_freq_range(ubman) 611 spi_pre_commands(ubman, random.randint(min_f, max_f)) 612 total_size = get_total_size() 613 erase_size = get_erase_size() 614 page_size = get_page_size() 615 addr = utils.find_ram_base(ubman) 616 i = 0 617 while i < loop: 618 # Erase negative test 619 start = random.randint(0, total_size) 620 esize = erase_size 621 622 # If erasesize is not multiple of flash's erase size 623 while esize % erase_size == 0: 624 esize = random.randint(0, total_size - start) 625 626 error_msg = 'Erased: ERROR' 627 flash_ops( 628 ubman, 'erase', start, esize, 0, 1, error_msg, EXPECTED_ERASE 629 ) 630 631 # If eraseoffset exceeds beyond flash size 632 eoffset = random.randint(total_size, (total_size + int(0x1000000))) 633 error_msg = 'Offset exceeds device limit' 634 flash_ops( 635 ubman, 'erase', eoffset, esize, 0, 1, error_msg, EXPECTED_ERASE 636 ) 637 638 # If erasesize exceeds beyond flash size 639 esize = random.randint((total_size - start), (total_size + int(0x1000000))) 640 error_msg = 'ERROR: attempting erase past flash size' 641 flash_ops( 642 ubman, 'erase', start, esize, 0, 1, error_msg, EXPECTED_ERASE 643 ) 644 645 # If erase size is 0 646 esize = 0 647 error_msg = None 648 flash_ops( 649 ubman, 'erase', start, esize, 0, 1, error_msg, EXPECTED_ERASE 650 ) 651 652 # If erasesize is less than flash's page size 653 esize = random.randint(0, page_size) 654 start = random.randint(0, (total_size - page_size)) 655 error_msg = 'Erased: ERROR' 656 flash_ops( 657 ubman, 'erase', start, esize, 0, 1, error_msg, EXPECTED_ERASE 658 ) 659 660 # Write/Read negative test 661 # if Write/Read size exceeds beyond flash size 662 offset = random.randint(0, total_size) 663 size = random.randint((total_size - offset), (total_size + int(0x1000000))) 664 error_msg = 'Size exceeds partition or device limit' 665 flash_ops( 666 ubman, 'write', offset, size, addr, 1, error_msg, EXPECTED_WRITE 667 ) 668 flash_ops( 669 ubman, 'read', offset, size, addr, 1, error_msg, EXPECTED_READ 670 ) 671 672 # if Write/Read offset exceeds beyond flash size 673 offset = random.randint(total_size, (total_size + int(0x1000000))) 674 size = random.randint(0, total_size) 675 error_msg = 'Offset exceeds device limit' 676 flash_ops( 677 ubman, 'write', offset, size, addr, 1, error_msg, EXPECTED_WRITE 678 ) 679 flash_ops( 680 ubman, 'read', offset, size, addr, 1, error_msg, EXPECTED_READ 681 ) 682 683 # if Write/Read size is 0 684 offset = random.randint(0, 2) 685 size = 0 686 error_msg = None 687 flash_ops( 688 ubman, 'write', offset, size, addr, 1, error_msg, EXPECTED_WRITE 689 ) 690 flash_ops( 691 ubman, 'read', offset, size, addr, 1, error_msg, EXPECTED_READ 692 ) 693 694 # Read to relocation address 695 output = ubman.run_command('bdinfo') 696 m = re.search(r'relocaddr\s*= (.+)', output) 697 res_area = int(m.group(1), 16) 698 699 start = 0 700 size = 0x2000 701 error_msg = 'ERROR: trying to overwrite reserved memory' 702 flash_ops( 703 ubman, 'read', start, size, res_area, 1, error_msg, EXPECTED_READ 704 ) 705 706 # Start reading from the reserved area 707 m = re.search(r'reserved\[0\]\s*\[(0x.+)-(0x.+)\]', output) 708 if not m or int(m.group(1), 16) == 0: 709 ubman.log.info('No reserved area is defined or start addr is 0x0!') 710 else: 711 rstart_area = int(m.group(1), 16) 712 rend_area = int(m.group(2), 16) 713 714 # Case 1: Start reading from the middle of the reserved area 715 r_size = rend_area - rstart_area 716 r_area = rstart_area + r_size 717 flash_ops( 718 ubman, 'read', start, size, r_area, 1, error_msg, EXPECTED_READ 719 ) 720 721 # Case 2: Start reading from before the reserved area to cross-over 722 # the reserved area 723 rstart_area = rstart_area - int(size/2) 724 flash_ops( 725 ubman, 'read', start, size, rstart_area, 1, error_msg, EXPECTED_READ 726 ) 727 728 # Case 3: Start reading till after the reserved area to cross-over 729 # the reserved area 730 rend_area = rend_area - int(size/2) 731 flash_ops( 732 ubman, 'read', start, size, rend_area, 1, error_msg, EXPECTED_READ 733 ) 734 735 i = i + 1 736