diff --git a/sw/host/provisioning/orchestrator/src/device_id.py b/sw/host/provisioning/orchestrator/src/device_id.py index 3dc66a1024ab11..3a144271b07170 100644 --- a/sw/host/provisioning/orchestrator/src/device_id.py +++ b/sw/host/provisioning/orchestrator/src/device_id.py @@ -53,22 +53,22 @@ def validate(self) -> None: def to_int(self) -> int: din = 0 - din |= self.wafer_y_coord << 44 - din |= self.wafer_x_coord << 32 - din |= self.wafer << 24 - din |= self.lot << 12 - din |= self.week << 4 + din |= util.bcd_encode(self.wafer_y_coord) << 44 + din |= util.bcd_encode(self.wafer_x_coord) << 32 + din |= util.bcd_encode(self.wafer) << 24 + din |= util.bcd_encode(self.lot) << 12 + din |= util.bcd_encode(self.week) << 4 din |= self.year return din @staticmethod def from_int(din: int) -> "DeviceIdentificationNumber": - year = util.read_int_as_decimal_str(din & 0xF) - week = util.read_int_as_decimal_str((din >> 4) & 0xFF) - lot = util.read_int_as_decimal_str((din >> 12) & 0xFFF) - wafer = util.read_int_as_decimal_str((din >> 24) & 0xFF) - wafer_x_coord = util.read_int_as_decimal_str((din >> 32) & 0xFFF) - wafer_y_coord = util.read_int_as_decimal_str((din >> 44) & 0xFFF) + year = util.bcd_decode(din & 0xF) + week = util.bcd_decode((din >> 4) & 0xFF) + lot = util.bcd_decode((din >> 12) & 0xFFF) + wafer = util.bcd_decode((din >> 24) & 0xFF) + wafer_x_coord = util.bcd_decode((din >> 32) & 0xFFF) + wafer_y_coord = util.bcd_decode((din >> 44) & 0xFFF) return DeviceIdentificationNumber(year=year, week=week, lot=lot, @@ -149,7 +149,7 @@ def update_base_id(self, other: "DeviceId") -> None: self.product_id = other.product_id self._hw_origin = other._hw_origin - self.din = other.din + self.din = other.din.to_int() self._base_uid = other._base_uid self.device_id = (self.sku_specific << 128) | self._base_uid diff --git a/sw/host/provisioning/orchestrator/src/util.py b/sw/host/provisioning/orchestrator/src/util.py index 48ac56655ab8af..08ece655da4495 100644 --- a/sw/host/provisioning/orchestrator/src/util.py +++ b/sw/host/provisioning/orchestrator/src/util.py @@ -25,14 +25,21 @@ def format_hex(n, width=8): return format(n, f"#0{width + 2}x") # + 2 to account for 0x chars -def read_int_as_decimal_str(x: int) -> int: - """Interpret a number by reading its hexadecimal representation as a decimal number. +def bcd_decode(x: int) -> int: + """Convert a BCD int to a packed int. - For example, `70` in hex is `0x46` and should be read as the decimal value 46. + For example, `0x46` in hex is `46` and should be converted to the int 46. This encoding is a manufacturing equipment constraint. """ return int(hex(x)[2:]) +def bcd_encode(x: int) -> int: + """Converts an int to a BCD int. + + For example, `46` is encoded as `0x46`. + """ + return int("0x" + str(x), 16) + def confirm(): """Get user confirmation to continue.""" diff --git a/sw/host/provisioning/orchestrator/tests/BUILD b/sw/host/provisioning/orchestrator/tests/BUILD index b5fdabf7bd0b58..ed064b24391c47 100644 --- a/sw/host/provisioning/orchestrator/tests/BUILD +++ b/sw/host/provisioning/orchestrator/tests/BUILD @@ -22,7 +22,7 @@ py_test( "//sw/device/silicon_creator/manuf/keys/fake:dice_ca.pem", "//sw/device/silicon_creator/manuf/keys/fake:ext_ca.pem", "//sw/device/silicon_creator/manuf/keys/fake:sk.pkcs8.der", - "//sw/host/provisioning/orchestrator/configs/skus:sival.hjson", + "//sw/host/provisioning/orchestrator/configs/skus:emulation.hjson", ], deps = [ requirement("hjson"), diff --git a/sw/host/provisioning/orchestrator/tests/device_id_test.py b/sw/host/provisioning/orchestrator/tests/device_id_test.py index 8c18503a440e7b..388b56b792b955 100644 --- a/sw/host/provisioning/orchestrator/tests/device_id_test.py +++ b/sw/host/provisioning/orchestrator/tests/device_id_test.py @@ -8,9 +8,9 @@ import hjson from device_id import DeviceId, DeviceIdentificationNumber from sku_config import SkuConfig -from util import bytes_to_int, format_hex +from util import bcd_encode, bytes_to_int, format_hex -_SIVAL_SKU_CONFIG = "sw/host/provisioning/orchestrator/configs/skus/sival.hjson" +_SIVAL_SKU_CONFIG = "sw/host/provisioning/orchestrator/configs/skus/emulation.hjson" class TestDeviceId(unittest.TestCase): @@ -57,7 +57,7 @@ def test_din_year_field(self): format_hex(expected_field, width=1))) def test_din_week_field(self): - expected_field = 49 + expected_field = bcd_encode(49) actual_field = (self.device_id.to_int() >> 36) & 0xff self.assertEqual( actual_field, expected_field, "actual: {}, expected: {}.".format( @@ -65,7 +65,7 @@ def test_din_week_field(self): format_hex(expected_field, width=2))) def test_din_lot_field(self): - expected_field = 343 + expected_field = bcd_encode(343) actual_field = (self.device_id.to_int() >> 44) & 0xfff self.assertEqual( actual_field, expected_field, "actual: {}, expected: {}.".format( @@ -73,7 +73,7 @@ def test_din_lot_field(self): format_hex(expected_field, width=3))) def test_din_wafer_field(self): - expected_field = 72 + expected_field = bcd_encode(72) actual_field = (self.device_id.to_int() >> 56) & 0xff self.assertEqual( actual_field, expected_field, "actual: {}, expected: {}.".format( @@ -81,7 +81,7 @@ def test_din_wafer_field(self): format_hex(expected_field, width=2))) def test_din_wafer_x_coord_field(self): - expected_field = 635 + expected_field = bcd_encode(635) actual_field = (self.device_id.to_int() >> 64) & 0xfff self.assertEqual( actual_field, expected_field, "actual: {}, expected: {}.".format( @@ -89,7 +89,7 @@ def test_din_wafer_x_coord_field(self): format_hex(expected_field, width=3))) def test_din_wafer_y_coord_field(self): - expected_field = 242 + expected_field = bcd_encode(242) actual_field = (self.device_id.to_int() >> 76) & 0xfff self.assertEqual( actual_field, expected_field, "actual: {}, expected: {}.".format( @@ -129,7 +129,7 @@ def test_sku_specific_reserved_field_0(self): format_hex(expected_field, width=4))) def test_sku_id_field(self): - expected_field = bytes_to_int("AVIS".encode("utf-8")) + expected_field = bytes_to_int("LUME".encode("utf-8")) actual_field = (self.device_id.to_int() >> 160) & 0xffffffff self.assertEqual( actual_field, expected_field, "actual: {}, expected: {}.".format( @@ -157,6 +157,8 @@ def test_from_hexstr(self): wafer_y_coord=100) expected = DeviceId(sku_config=self.sku_config, din=din) hexstr = expected.to_hexstr() + print("HERE:", hexstr) + print("HERE:", hex((expected.to_int() >> 32) & 0xFFFFFFFFFFFFFFFF)) cp_device_id = DeviceId.from_hexstr(hexstr) self.device_id.update_base_id(cp_device_id)