OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """ | 6 """ |
7 This module provides convenience routines to access Flash ROM (EEPROM). | 7 This module provides convenience routines to access Flash ROM (EEPROM). |
8 - flashrom_util is a low level wrapper of flashrom(8) program. | 8 - flashrom_util is a low level wrapper of flashrom(8) program. |
9 - FlashromUtility is a high level object which provides more advanced | 9 - FlashromUtility is a high level object which provides more advanced |
10 features like journaling-alike (log-based) changing. | 10 features like journaling-alike (log-based) changing. |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 if len(data) != pos[1] - pos[0] + 1: | 395 if len(data) != pos[1] - pos[0] + 1: |
396 raise TestError('INTERNAL ERROR: unmatched data size.') | 396 raise TestError('INTERNAL ERROR: unmatched data size.') |
397 return base_image[0 : pos[0]] + data + base_image[pos[1] + 1 :] | 397 return base_image[0 : pos[0]] + data + base_image[pos[1] + 1 :] |
398 | 398 |
399 def get_size(self): | 399 def get_size(self): |
400 """ Gets size of current flash ROM """ | 400 """ Gets size of current flash ROM """ |
401 cmd = '%s"%s" --get-size' % (self.cmd_prefix, self.tool_path) | 401 cmd = '%s"%s" --get-size' % (self.cmd_prefix, self.tool_path) |
402 if self.verbose: | 402 if self.verbose: |
403 print 'flashrom_util.get_size(): ', cmd | 403 print 'flashrom_util.get_size(): ', cmd |
404 output = utils.system_output(cmd, ignore_status=True) | 404 output = utils.system_output(cmd, ignore_status=True) |
405 last_line = output.rpartition('\n')[2] | 405 last_line = output.rpartition('\n')[-1] |
406 try: | 406 try: |
407 size = long(last_line) | 407 size = long(last_line) |
408 except ValueError: | 408 except ValueError: |
409 raise TestError('INTERNAL ERROR: unable to get the flash size.') | 409 raise TestError('INTERNAL ERROR: unable to get the flash size.') |
410 return size | 410 return size |
411 | 411 |
412 def detect_target_map(self): | 412 def detect_target_map(self): |
413 """ | 413 """ |
414 Detects the target selection map. | 414 Detects the target selection map. |
415 Use machine architecture in current implementation. | 415 Use machine architecture in current implementation. |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 def enable_write_protect(self, layout_map, section): | 564 def enable_write_protect(self, layout_map, section): |
565 ''' | 565 ''' |
566 Enables the "write protection" for specified section on flashrom. | 566 Enables the "write protection" for specified section on flashrom. |
567 | 567 |
568 WARNING: YOU CANNOT CHANGE FLASHROM CONTENT AFTER THIS CALL. | 568 WARNING: YOU CANNOT CHANGE FLASHROM CONTENT AFTER THIS CALL. |
569 ''' | 569 ''' |
570 if section not in layout_map: | 570 if section not in layout_map: |
571 raise TestError('INTERNAL ERROR: unknown section.') | 571 raise TestError('INTERNAL ERROR: unknown section.') |
572 # syntax: flashrom --wp-range offset size | 572 # syntax: flashrom --wp-range offset size |
573 # flashrom --wp-enable | 573 # flashrom --wp-enable |
| 574 # NOTE: wp-* won't return error value even if they failed to change |
| 575 # the value/status due to WP already enabled, so we can't rely on the |
| 576 # return value; the real status must be verified by --wp-status. |
574 addr = layout_map[section] | 577 addr = layout_map[section] |
575 cmd = '%s"%s" --wp-range 0x%06X 0x%06X && "%s" --wp-enable' % ( | 578 cmd = ('%s"%s" --wp-disable && ' |
576 self.cmd_prefix, self.tool_path, | 579 '"%s" --wp-range 0x%06X 0x%06X && ' |
577 addr[0], addr[1] - addr[0] + 1, | 580 '"%s" --wp-enable' % ( |
578 self.tool_path) | 581 self.cmd_prefix, self.tool_path, |
| 582 self.tool_path, addr[0], addr[1] - addr[0] + 1, |
| 583 self.tool_path)) |
579 if self.verbose: | 584 if self.verbose: |
580 print 'flashrom.enable_write_protect(): ', cmd | 585 print 'flashrom.enable_write_protect(): ', cmd |
581 # failure for non-zero | 586 # failure for non-zero |
582 return utils.system(cmd, ignore_status=True) == 0 | 587 return utils.system(cmd, ignore_status=True) == 0 |
583 | 588 |
| 589 def disable_write_protect(self): |
| 590 ''' |
| 591 Disables whole "write protection" range and status. |
| 592 ''' |
| 593 # syntax: flashrom --wp-range offset size |
| 594 # flashrom --wp-disable |
| 595 cmd = '%s"%s" --wp-disable && "%s" --wp-range 0 0' % ( |
| 596 self.cmd_prefix, self.tool_path, self.tool_path) |
| 597 if self.verbose: |
| 598 print 'flashrom.disable_write_protect(): ', cmd |
| 599 # failure for non-zero |
| 600 return utils.system(cmd, ignore_status=True) == 0 |
| 601 |
| 602 def verify_write_protect(self, layout_map, section): |
| 603 ''' |
| 604 Verifies if write protection is configured correctly. |
| 605 ''' |
| 606 if section not in layout_map: |
| 607 raise TestError('INTERNAL ERROR: unknown section.') |
| 608 # syntax: flashrom --wp-status |
| 609 addr = layout_map[section] |
| 610 cmd = '%s"%s" --wp-status | grep "^WP: "' % ( |
| 611 self.cmd_prefix, self.tool_path) |
| 612 if self.verbose: |
| 613 print 'flashrom.verify_write_protect(): ', cmd |
| 614 results = utils.system_output(cmd, ignore_status=True).split('\n') |
| 615 # output: WP: status: 0x80 |
| 616 # WP: status.srp0: 1 |
| 617 # WP: write protect is %s. (disabled/enabled) |
| 618 # WP: write protect range: start=0x%8x, len=0x%08x |
| 619 wp_enabled = None |
| 620 wp_range_start = -1 |
| 621 wp_range_len = -1 |
| 622 for result in results: |
| 623 result = result.strip() |
| 624 if result.startswith('WP: write protect is '): |
| 625 result = result.rpartition(' ')[-1].strip('.') |
| 626 if result == 'enabled': |
| 627 wp_enabled = True |
| 628 elif result == 'disabled': |
| 629 wp_enabled = False |
| 630 else: |
| 631 if self.verbose: |
| 632 print 'flashrom.verify_write_protect: unknown status:', |
| 633 print result |
| 634 continue |
| 635 if result.startswith('WP: write protect range: '): |
| 636 value_start = re.findall('start=[0-9xXa-fA-F]+', result) |
| 637 value_len = re.findall('len=[0-9xXa-fA-F]+', result) |
| 638 if value_start and value_len: |
| 639 wp_range_start = int(value_start[0].rpartition('=')[-1], 0) |
| 640 wp_range_len = int(value_len[0].rpartition('=')[-1], 0) |
| 641 continue |
| 642 if self.verbose: |
| 643 print 'wp_enabled:', wp_enabled |
| 644 print 'wp_range_start:', wp_range_start |
| 645 print 'wp_range_len:', wp_range_len |
| 646 if (wp_enabled == None) or ((wp_range_start < 0) or (wp_range_len < 0)): |
| 647 if self.verbose: |
| 648 print 'flashrom.verify_write_protect(): invalid output:' |
| 649 print '\n'.join(results) |
| 650 return False |
| 651 |
| 652 # expected: enabled, and correct range |
| 653 addr = layout_map[section] |
| 654 addr_start = addr[0] |
| 655 addr_len = addr[1] - addr[0] + 1 |
| 656 if (wp_range_start != addr_start) or (wp_range_len != addr_len): |
| 657 if self.verbose: |
| 658 print ('flashrom.verify_write_protect(): unmatched range: ' |
| 659 'current (%08lx, %08lx), expected (%08lx,%08lx)' % |
| 660 (wp_range_start, wp_range_len, addr_start, addr_len)) |
| 661 return False |
| 662 if not wp_enabled: |
| 663 if self.verbose: |
| 664 print ('flashrom.verify_write_protect(): ' |
| 665 'write protect is not enabled.') |
| 666 return False |
| 667 |
| 668 # everything is correct. |
| 669 return True |
| 670 |
584 def select_target(self, target): | 671 def select_target(self, target): |
585 ''' | 672 ''' |
586 Selects (usually by setting BBS register) a target defined in target_map | 673 Selects (usually by setting BBS register) a target defined in target_map |
587 and then directs all further firmware access to certain region. | 674 and then directs all further firmware access to certain region. |
588 ''' | 675 ''' |
589 assert target in self.target_map, "Unknown target: " + target | 676 assert target in self.target_map, "Unknown target: " + target |
590 if not self.target_map[target]: | 677 if not self.target_map[target]: |
591 return True | 678 return True |
592 if self.verbose: | 679 if self.verbose: |
593 print 'flashrom.select_target("%s"): %s' % (target, | 680 print 'flashrom.select_target("%s"): %s' % (target, |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 except ImportError: | 1036 except ImportError: |
950 # print 'using mocks' | 1037 # print 'using mocks' |
951 utils = mock_utils() | 1038 utils = mock_utils() |
952 TestError = mock_TestError | 1039 TestError = mock_TestError |
953 | 1040 |
954 | 1041 |
955 # main stub | 1042 # main stub |
956 if __name__ == "__main__": | 1043 if __name__ == "__main__": |
957 # TODO(hungte) provide unit tests or command line usage | 1044 # TODO(hungte) provide unit tests or command line usage |
958 pass | 1045 pass |
OLD | NEW |