From 75c6f34b0f891476dc317cb37ee79c7ee65a0ca5 Mon Sep 17 00:00:00 2001 From: Trung Tran Date: Thu, 9 May 2019 16:35:21 -0700 Subject: mpm: Change SW/HW compat check to use last_rev_compat Newer revisions of the E320 and N3xx motherboards use EEPROM version 3, and store a rev_compat field. The rev_compat is the last revision that this hardware is compatible with. We now use that instead of simply the revision. --- mpm/python/usrp_mpm/bist.py | 2 +- mpm/python/usrp_mpm/periph_manager/base.py | 45 ++++++++++++++++++++---------- mpm/python/usrp_mpm/periph_manager/e320.py | 2 +- mpm/python/usrp_mpm/periph_manager/n3xx.py | 2 +- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/mpm/python/usrp_mpm/bist.py b/mpm/python/usrp_mpm/bist.py index e26d6d36c..7957f2f37 100644 --- a/mpm/python/usrp_mpm/bist.py +++ b/mpm/python/usrp_mpm/bist.py @@ -495,7 +495,7 @@ class UsrpBIST(object): # If this is true, trigger a reload of the default FPGA image self.reload_fpga_image = False try: - default_rev = self.get_mb_periph_mgr().mboard_max_rev + default_rev = self.get_mb_periph_mgr().mboard_last_rev_compat except ImportError: # This means we're in dry run mode or something like that, so just # pick something diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py index 2dc69e908..8c3937702 100644 --- a/mpm/python/usrp_mpm/periph_manager/base.py +++ b/mpm/python/usrp_mpm/periph_manager/base.py @@ -85,7 +85,7 @@ class PeriphManagerBase(object): # For checking revision numbers, this is the highest revision that this # particular version of MPM supports. Leave at None to skip a max rev # check. - mboard_max_rev = None + mboard_last_rev_compat = None # A list of available sensors on the motherboard. This dictionary is a map # of the form sensor_name -> method name mboard_sensor_callback_map = {} @@ -281,22 +281,37 @@ class PeriphManagerBase(object): ) ) raise RuntimeError("Invalid PID found in EEPROM.") - if 'rev' in eeprom_head: - try: - rev_numeric = int(eeprom_head.get('rev')) - except (ValueError, TypeError): + # The rev_compat is either directly stored in the EEPROM, or we fall + # back first to the dt_compat, then the rev itself (because every rev is + # compatible with itself). + # The dt_compat solution is a technically a hack, but it works because + # all hardware we have released until we made this change happened to + # have a dt_compat that also works as a rev_compat. + rev_compat = \ + eeprom_head.get('rev_compat', + eeprom_head.get('dt_compat', + eeprom_head.get('rev'))) + try: + rev_compat = int(rev_compat) + except (ValueError, TypeError): + raise RuntimeError( + "Invalid revision compat info read from EEPROM!" + ) + # We check if this software is actually compatible with the hardware. + # In order for the software to be able to understand the hardware, the + # rev_compat value (stored on the EEPROM) must be smaller or equal to + # the value stored in the software itself. + if self.mboard_last_rev_compat is None: + self.log.warning("Skipping HW/SW compatibility check!") + else: + if rev_compat > self.mboard_last_rev_compat: raise RuntimeError( - "Invalid revision info read from EEPROM!" + "Software is maximally compatible with revision `{}', but " + "the hardware has revision `{}' and is minimally compatible " + "with hardware revision `{}'. Please upgrade your version of" + "MPM in order to use this device." + .format(self.mboard_last_rev_compat, mboard_info['rev'], rev_compat) ) - if self.mboard_max_rev is not None \ - and rev_numeric > self.mboard_max_rev: - raise RuntimeError( - "Device has revision `{}', but max supported " \ - "revision is `{}'".format( - rev_numeric, self.mboard_max_rev - )) - else: - raise RuntimeError("No revision found in EEPROM.") return mboard_info def _get_dboard_eeprom_info(self): diff --git a/mpm/python/usrp_mpm/periph_manager/e320.py b/mpm/python/usrp_mpm/periph_manager/e320.py index 96a184477..3135a6994 100644 --- a/mpm/python/usrp_mpm/periph_manager/e320.py +++ b/mpm/python/usrp_mpm/periph_manager/e320.py @@ -78,7 +78,7 @@ class e320(ZynqComponents, PeriphManagerBase): mboard_info = {"type": "e3xx", "product": "e320" } - mboard_max_rev = 4 # Rev E + mboard_last_rev_compat = 0 mboard_sensor_callback_map = { 'ref_locked': 'get_ref_lock_sensor', 'gps_locked': 'get_gps_lock_sensor', diff --git a/mpm/python/usrp_mpm/periph_manager/n3xx.py b/mpm/python/usrp_mpm/periph_manager/n3xx.py index 5856036e3..0a2801f44 100644 --- a/mpm/python/usrp_mpm/periph_manager/n3xx.py +++ b/mpm/python/usrp_mpm/periph_manager/n3xx.py @@ -131,7 +131,7 @@ class n3xx(ZynqComponents, PeriphManagerBase): mboard_eeprom_offset = 0 mboard_eeprom_max_len = 256 mboard_info = {"type": "n3xx"} - mboard_max_rev = 7 # 7 == RevH + mboard_last_rev_compat = 5 # last known compat through dt_compat field mboard_sensor_callback_map = { 'ref_locked': 'get_ref_lock_sensor', 'gps_locked': 'get_gps_lock_sensor', -- cgit v1.2.3