# 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)
