Index: gft_wpfw.py |
diff --git a/gft_wpfw.py b/gft_wpfw.py |
index e113ed41309e3b41494a76f0e4c005f554e8173f..0b392cc5ef6c9e2470c799ccdf5aa114c543c053 100755 |
--- a/gft_wpfw.py |
+++ b/gft_wpfw.py |
@@ -20,11 +20,11 @@ import gft_common |
from gft_common import DebugMsg, VerboseMsg, ErrorDie |
-def EnableWriteProtect(target): |
+def EnableWriteProtect(target, image=None): |
""" Enables and verifies firmware write protection status. |
ARGS |
target: the flashrom_util target code, 'bios' or 'ec'. |
- verbose: verbosity for flashrom_util. |
+ image: a reference image for layout detection. |
""" |
flashrom = flashrom_util.flashrom_util(verbose_msg=VerboseMsg, |
@@ -32,25 +32,29 @@ def EnableWriteProtect(target): |
system_output=gft_common.SystemOutput) |
# The EEPROM should be programmed as: |
+ # x86: |
# (BIOS) LSB [ RW | RO ] MSB |
# (EC) LSB [ RO | RW ] MSB |
+ # arm: |
+ # (BIOS) LSB [ RO | RW ] MSB |
# Each part of RW/RO section occupies half of the EEPROM. |
+ # To simplify the arch detection, we trust the FMAP. |
+ |
+ layout_rw_ro = 'rw|ro' |
+ layout_ro_rw = 'ro|rw' |
eeprom_sets = ({ # BIOS |
'name': 'BIOS', |
- 'layout': 'rw|ro', |
+ 'layout': layout_rw_ro, |
'target': 'bios', |
- 'trust_fmap': False, |
+ 'fmap_conversion': {'RO_SECTION': 'ro'}, |
}, { # Embedded Controller |
'name': 'EC', |
- 'layout': 'ro|rw', |
+ 'layout': layout_ro_rw, |
'target': 'ec', |
- 'trust_fmap': True, |
- 'fmap_conversion': {'EC_RO': 'ro', 'EC_RW': 'rw'}, |
+ 'fmap_conversion': {'EC_RO': 'ro'}, |
}) |
- # TODO(hungte) BIOS on ARM is using different layout, |
- # so we must also trust fmap for BIOS in the future. |
matched = [eeprom for eeprom in eeprom_sets |
if eeprom['target'] == target] |
if not matched: |
@@ -67,27 +71,47 @@ def EnableWriteProtect(target): |
if not eeprom_size: |
ErrorDie('wpfw: cannot get size for ' + name) |
layout = None |
- if conf['trust_fmap']: |
- DebugMsg(' - Trying to use FMAP layout for %s' % name) |
+ layout_desc = conf['layout'] |
+ DebugMsg(' - Trying to use FMAP layout for %s' % name) |
+ if not image: |
image = flashrom.read_whole() |
- assert eeprom_size == len(image) |
- layout = flashrom_util.decode_fmap_layout(conf['fmap_conversion'], image) |
- if 'ro' not in layout: |
- layout = None |
+ assert eeprom_size == len(image) |
+ fmap_layout = flashrom_util.decode_fmap_layout(conf['fmap_conversion'], image) |
+ |
+ if 'ro' in fmap_layout: |
+ # Verify if the layout is in valid size. Most chips support only setting |
+ # write protection on half of the total size, so we always devide the |
+ # flashrom into 2 slots. |
+ slot_size = int(eeprom_size / 2) |
+ # fmap_layout is a (offset, offset) structure, not (offset, size) |
+ (ro_begin_offset, ro_end_offset) = fmap_layout['ro'] |
+ ro_begin_slot = int(ro_begin_offset / slot_size) |
+ ro_end_slot = int(ro_end_offset / slot_size) |
+ error_reason = None |
+ if ro_begin_slot != ro_end_slot: |
+ error_reason = 'section accross valid slot range' |
+ # flashrom layout does not really support a section of '1 byte in size'. |
+ # Both 0/1 sized sections are invalid. |
+ if ro_begin_offset >= ro_end_offset: |
+ error_reason = 'invalid section size' |
+ if error_reason: |
+ ErrorDie('Invalid RO section in layout: %s (%s,%s)' % |
+ (error_reason, ro_begin_offset, ro_end_offset)) |
+ assert ro_begin_slot == 0 or ro_begin_slot == 1 |
+ |
+ # decide ro, rw according to the offset of 'ro'. |
+ if ro_begin_slot == 0: |
+ layout_desc = layout_ro_rw |
else: |
- VerboseMsg(' - Using layout by FMAP in %s' % name) |
+ layout_desc = layout_rw_ro |
+ VerboseMsg(' - Using layout by FMAP in %s: %s' % (name, layout_desc)) |
+ else: |
+ VerboseMsg(' - Using hard-coded layout for %s: %s' % name, layout_desc) |
- if not layout: |
- # do not trust current image when detecting layout. |
- layout = flashrom.detect_layout(conf['layout'], eeprom_size, None) |
- VerboseMsg(' - Using hard-coded layout for %s' % name) |
+ layout = flashrom.detect_layout(layout_desc, eeprom_size, None) |
if not layout: |
ErrorDie('wpfw: cannot detect %s layout' % name) |
- # verify if the layout is half of firmware. |
- if layout['ro'][1] - layout['ro'][0] + 1 != eeprom_size / 2: |
- ErrorDie('Invalid RO section in flash rom layout.') |
- |
VerboseMsg(' - Enable Write Protection for ' + name) |
# only configure (enable) write protection if current status is not |
# correct, because sometimes the factory test is executed several |