|  | # Copyright lowRISC contributors. | 
|  | # Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | # SPDX-License-Identifier: Apache-2.0 | 
|  |  | 
|  | load("@bazel_skylib//lib:structs.bzl", "structs") | 
|  |  | 
|  | CONST = struct( | 
|  | # Must match the definitions in hardened.h. | 
|  | TRUE = 0x739, | 
|  | FALSE = 0x1d4, | 
|  | # Must match the definitions in chip.h. | 
|  | ROM_EXT = 0x4552544f, | 
|  | OWNER = 0x3042544f, | 
|  | MANIFEST_SIZE = 896, | 
|  | ROM_EXT_SIZE_MIN = 896, | 
|  | ROM_EXT_SIZE_MAX = 0x10000, | 
|  | BL0_SIZE_MIN = 896, | 
|  | BL0_SIZE_MAX = 0x70000, | 
|  | DEFAULT_USAGE_CONSTRAINTS = 0xa5a5a5a5, | 
|  | # Must match the definitions in lc_ctrl_regs.h. | 
|  | LCV = struct( | 
|  | TEST_UNLOCKED0 = 0x02108421, | 
|  | DEV = 0x21084210, | 
|  | PROD = 0x2318c631, | 
|  | PROD_END = 0x25294a52, | 
|  | RMA = 0x2739ce73, | 
|  | ), | 
|  | # LC values used in software. Must match the definitions in lifecycle.h | 
|  | LCV_SW = struct( | 
|  | TEST = 0xb2865fbb, | 
|  | DEV = 0x0b5a75e0, | 
|  | PROD = 0x65f2520f, | 
|  | PROD_END = 0x91b9b68a, | 
|  | RMA = 0xcf8cfaab, | 
|  | ), | 
|  | # Must match the definitions in error.h. | 
|  | BFV = struct( | 
|  | INTERRUPT = struct( | 
|  | INSTRUCTION_ACCESS = 0x01495202, | 
|  | ILLEGAL_INSTRUCTION = 0x02495202, | 
|  | STORE_ACCESS = 0x07495202, | 
|  | ), | 
|  | SIGVERIFY = struct( | 
|  | BAD_ENCODED_MSG = 0x01535603, | 
|  | BAD_KEY = 0x02535603, | 
|  | ), | 
|  | BOOT_POLICY = struct( | 
|  | BAD_IDENTIFIER = 0x0142500d, | 
|  | BAD_LENGTH = 0x0242500d, | 
|  | ROLLBACK = 0x0342500d, | 
|  | ), | 
|  | MANIFEST = struct( | 
|  | BAD_ENTRY_POINT = 0x014d410d, | 
|  | BAD_CODE_REGION = 0x024d410d, | 
|  | ), | 
|  | BOOT_DATA = struct( | 
|  | NOT_FOUND = 0x0142440d, | 
|  | WRITE_CHECK = 0x0242440d, | 
|  | DATA_INVALID = 0x0342440d, | 
|  | ), | 
|  | UNKNOWN = 0xffffffff, | 
|  | OK = 0x739, | 
|  | ), | 
|  | # Must match the definitions in shutdown.h. | 
|  | SHUTDOWN = struct( | 
|  | PREFIX = struct( | 
|  | LCV = "LCV:", | 
|  | BFV = "BFV:", | 
|  | ), | 
|  | REDACT = struct( | 
|  | NONE = 0xe2290aa5, | 
|  | ERROR = 0x3367d3d4, | 
|  | MODULE = 0x1e791123, | 
|  | ALL = 0x48eb4bd9, | 
|  | ), | 
|  | ), | 
|  | # Must match the definitions in alert.h. | 
|  | ALERT = struct( | 
|  | NONE = 0xa9, | 
|  | ENABLE = 0x07, | 
|  | ENABLE_LOCKED = 0xd2, | 
|  | CLASS_X = 0x94, | 
|  | CLASS_A = 0xee, | 
|  | CLASS_B = 0x64, | 
|  | CLASS_C = 0xa7, | 
|  | CLASS_D = 0x32, | 
|  | ESC_NONE = 0xd1, | 
|  | ESC_PHASE_0 = 0xb9, | 
|  | ESC_PHASE_1 = 0xcb, | 
|  | ESC_PHASE_2 = 0x25, | 
|  | ESC_PHASE_3 = 0x76, | 
|  | ), | 
|  | ) | 
|  |  | 
|  | def get_lc_items(*want_lc_values): | 
|  | """Return a list of key-value pairs from CONST.LCV with lowercased keys. | 
|  |  | 
|  | If `want_lc_values` is empty, returns an unfiltered dict. Otherwise, only | 
|  | key-value pairs where the value is in `want_lc_values` are returned. | 
|  | """ | 
|  | lcv_dict = structs.to_dict(CONST.LCV) | 
|  | out = [(k.lower(), v) for k, v in lcv_dict.items() if not want_lc_values or v in want_lc_values] | 
|  | if want_lc_values and len(out) != len(want_lc_values): | 
|  | fail("get_lc_items would produce list with incorrect length") | 
|  | return out | 
|  |  | 
|  | def lcv_hw_to_sw(hw_lc_state_val): | 
|  | """Return the software LCV corresponding to the given hardware LCV.""" | 
|  | lcv_map = { | 
|  | CONST.LCV.DEV: CONST.LCV_SW.DEV, | 
|  | CONST.LCV.PROD: CONST.LCV_SW.PROD, | 
|  | CONST.LCV.PROD_END: CONST.LCV_SW.PROD_END, | 
|  | CONST.LCV.RMA: CONST.LCV_SW.RMA, | 
|  | CONST.LCV.TEST_UNLOCKED0: CONST.LCV_SW.TEST, | 
|  | } | 
|  | sw_lcv = lcv_map.get(hw_lc_state_val) | 
|  | if sw_lcv == None: | 
|  | fail("Could not find software LCV for hardware LCV: {}".format(hex(hw_lc_state_val))) | 
|  | return sw_lcv | 
|  |  | 
|  | _HEX_MAP = "0123456789abcdef" | 
|  |  | 
|  | def hex_digits(v): | 
|  | """Convert an int into a hex string without 0x prefix""" | 
|  |  | 
|  | # First "cast" `v` to a 32-bit unsigned int | 
|  | v &= 0xffffffff | 
|  | hex_digits = [_HEX_MAP[(v >> i) & 0xf] for i in range(0, 32, 4)] | 
|  | return "".join(reversed(hex_digits)) | 
|  |  | 
|  | def hex(v): | 
|  | """Convert an int into a hex string with 0x prefix""" | 
|  | return "0x{}".format(hex_digits(v)) | 
|  |  | 
|  | _REDACTION_MAP = { | 
|  | CONST.SHUTDOWN.REDACT.NONE: 0xffffffff, | 
|  | CONST.SHUTDOWN.REDACT.ERROR: 0x00ffffff, | 
|  | CONST.SHUTDOWN.REDACT.MODULE: 0x000000ff, | 
|  | } | 
|  |  | 
|  | _REDACTION_LC_STATES = [CONST.LCV.DEV, CONST.LCV.PROD, CONST.LCV.PROD_END] | 
|  |  | 
|  | def error_redact(error, lc_state, redact): | 
|  | if lc_state not in _REDACTION_LC_STATES: | 
|  | return error | 
|  | if redact == CONST.SHUTDOWN.REDACT.ALL or redact not in _REDACTION_MAP: | 
|  | return CONST.BFV.UNKNOWN | 
|  | return error & _REDACTION_MAP.get(redact) |