Пример #1
0
def generate_power_controller(xml_power_controller, hash_engine):
    """
    Create a power_controller object from parsed XML list

    :param xml_power_controller: List of parsed XML of power_controller to be included in 
        power_controller object
    :param hash_engine: Hashing engine

    :return Instance of a power_controller object, power_controller's TOC entry, 
        hash of power_controller object
    """

    if xml_power_controller["interface"]["type"] != 0:
        raise ValueError(
            "Unsupported power_controller interface type: {0}".format(
                xml_power_controller["interface"]["type"]))

    if "muxes" in xml_power_controller["interface"]:
        muxes, muxes_len, num_muxes = generate_muxes_buf(
            xml_power_controller["interface"]["muxes"])
    else:
        muxes = (ctypes.c_ubyte * 0)()
        muxes_len = 0
        num_muxes = 0

    bus = int(
        manifest_common.get_key_from_dict(xml_power_controller["interface"],
                                          "bus", "Power controller interface"))
    address = int(
        manifest_common.get_key_from_dict(xml_power_controller["interface"],
                                          "address",
                                          "Power controller interface"))
    eid = int(
        manifest_common.get_key_from_dict(xml_power_controller["interface"],
                                          "eid", "Power controller interface"))
    i2c_mode = int(
        manifest_common.get_key_from_dict(xml_power_controller["interface"],
                                          "i2c_mode",
                                          "Power controller interface"))

    i2c_flags = i2c_mode

    class pcd_power_controller_element(ctypes.LittleEndianStructure):
        _pack_ = 1
        _fields_ = [('mux_count', ctypes.c_ubyte, 4),
                    ('i2c_flags', ctypes.c_ubyte, 4), ('bus', ctypes.c_ubyte),
                    ('address', ctypes.c_ubyte), ('eid', ctypes.c_ubyte),
                    ('muxes', ctypes.c_ubyte * muxes_len)]

    power_controller = pcd_power_controller_element(num_muxes, i2c_flags, bus,
                                                    address, eid, muxes)
    power_controller_len = ctypes.sizeof(power_controller)
    power_controller_toc_entry = manifest_common.manifest_toc_entry(
        manifest_common.PCD_V2_I2C_POWER_CONTROLLER_TYPE_ID,
        manifest_common.V2_BASE_TYPE_ID, 1, 0, 0, power_controller_len)

    power_controller_hash = manifest_common.generate_hash(
        power_controller, hash_engine)

    return power_controller, power_controller_toc_entry, power_controller_hash
Пример #2
0
def generate_rot(xml_rot, num_components, num_ports, hash_engine):
    """
    Create an RoT object from parsed XML list and ports buffer

    :param xml_rot: List of parsed XML of RoT to be included in RoT object
    :param num_components: Number of components
    :param num_ports: Number of SPI flash ports
    :param hash_engine: Hashing engine

    :return Instance of an RoT object, RoT's TOC entry, RoT hash
    """

    rot_type = int(manifest_common.get_key_from_dict(xml_rot, "type", "RoT"))
    rot_address = int(
        manifest_common.get_key_from_dict(xml_rot["interface"], "address",
                                          "RoT interface"))
    rot_eid = int(
        manifest_common.get_key_from_dict(xml_rot["interface"], "rot_eid",
                                          "RoT interface"))
    bridge_eid = int(
        manifest_common.get_key_from_dict(xml_rot["interface"], "bridge_eid",
                                          "RoT interface"))
    bridge_address = int(
        manifest_common.get_key_from_dict(xml_rot["interface"],
                                          "bridge_address", "RoT interface"))

    rot_flags = rot_type

    class pcd_rot_element(ctypes.LittleEndianStructure):
        _pack_ = 1
        _fields_ = [('rot_flags', ctypes.c_ubyte),
                    ('port_count', ctypes.c_ubyte),
                    ('components_count', ctypes.c_ubyte),
                    ('rot_address', ctypes.c_ubyte),
                    ('rot_eid', ctypes.c_ubyte),
                    ('bridge_address', ctypes.c_ubyte),
                    ('bridge_eid', ctypes.c_ubyte),
                    ('reserved', ctypes.c_ubyte)]

    rot = pcd_rot_element(rot_flags, num_ports, num_components, rot_address,
                          rot_eid, bridge_address, bridge_eid, 0)
    rot_len = ctypes.sizeof(rot)
    rot_toc_entry = manifest_common.manifest_toc_entry(
        manifest_common.PCD_V2_ROT_TYPE_ID, manifest_common.V2_BASE_TYPE_ID, 1,
        0, 0, rot_len)

    rot_hash = manifest_common.generate_hash(rot, hash_engine)

    return rot, rot_toc_entry, rot_hash
Пример #3
0
def generate_pfm_toc(manifest_header_len, toc_header, platform_id_element,
                     flash_device_element, fw_id_element_list, fw_id_list,
                     allowable_fw_list, hash_type):
    """
    Create a manifest table of contents

    :param manifest_header_len: Length of the manifest header
    :param toc_header: Table of contents header
    :platform_id_element_len: Platform ID header instance
    :flash_device_header_len: Flash device header instance
    :param fw_id_list: List of FW with different FW IDs
    :param hash_type: Hash to be used

    :return List of a manifest table of contents instances
    """
    toc_elements_list = []
    toc_elements_hash_list = []
    hash_id = 0
    hash_len = None

    if hash_type == 2:
        hash_algo = SHA512
        hash_len = 64
    elif hash_type == 1:
        hash_algo = SHA384
        hash_len = 48
    elif hash_type == 0:
        hash_algo = SHA256
        hash_len = 32
    else:
        raise ValueError("Invalid manifest hash type: {0}".format(hash_type))

    offset = manifest_header_len + ctypes.sizeof (toc_header) + \
        (toc_header.entry_count * ctypes.sizeof (manifest_common.manifest_toc_entry)) + \
        (hash_len * (toc_header.hash_count + 1))

    platform_id_entry = manifest_common.manifest_toc_entry(
        manifest_common.V2_PLATFORM_TYPE_ID, manifest_common.V2_BASE_TYPE_ID,
        1, hash_id, offset, ctypes.sizeof(platform_id_element))
    toc_elements_list.append(platform_id_entry)
    hash_id += 1
    offset += platform_id_entry.length

    toc_elements_hash_list.append(
        manifest_common.generate_hash(platform_id_element, hash_algo))

    if flash_device_element != None:
        flash_device_entry = manifest_common.manifest_toc_entry(
            manifest_common.PFM_V2_FLASH_DEVICE_TYPE_ID,
            manifest_common.V2_BASE_TYPE_ID, 0, hash_id, offset,
            ctypes.sizeof(flash_device_element))
        toc_elements_list.append(flash_device_entry)
        hash_id += 1
        offset += flash_device_entry.length

        toc_elements_hash_list.append(
            manifest_common.generate_hash(flash_device_element, hash_algo))

        for fw_type, count in fw_id_list.items():
            fw_id_entry = manifest_common.manifest_toc_entry(
                manifest_common.PFM_V2_FW_TYPE_ID,
                manifest_common.V2_BASE_TYPE_ID, 1, hash_id, offset,
                ctypes.sizeof(fw_id_element_list[fw_type]))
            toc_elements_list.append(fw_id_entry)

            hash_id += 1
            offset += fw_id_entry.length

            toc_elements_hash_list.append(
                manifest_common.generate_hash(fw_id_element_list[fw_type],
                                              hash_algo))

            fw_list = allowable_fw_list.get(fw_type)
            for num in range(0, count):
                fw_version_element = manifest_common.manifest_toc_entry(
                    manifest_common.PFM_V2_FW_VERSION_TYPE_ID,
                    manifest_common.PFM_V2_FW_TYPE_ID, 1, hash_id, offset,
                    ctypes.sizeof(fw_list[num]))
                toc_elements_list.append(fw_version_element)
                hash_id += 1
                offset += fw_version_element.length
                toc_elements_hash_list.append(
                    manifest_common.generate_hash(fw_list[num], hash_algo))

    return toc_elements_list, toc_elements_hash_list, hash_len
Пример #4
0
def generate_mctp_bridge_component_buf(xml_component):
    """
    Create an MCTP bridges component object from parsed XML list

    :param xml_component: List of parsed XML of component to be included in MCTP bridge component 
        object

    :return Instance of a component object, component's TOC entry, component hash
    """

    policy = int(
        manifest_common.get_key_from_dict(xml_component, "policy",
                                          "MCTP Bridge Component"))
    powerctrl_reg = int(
        manifest_common.get_key_from_dict(xml_component["powerctrl"],
                                          "register", "MCTP Bridge Component"))
    powerctrl_mask = int(
        manifest_common.get_key_from_dict(xml_component["powerctrl"], "mask",
                                          "MCTP Bridge Component"))
    component_type = manifest_common.get_key_from_dict(
        xml_component, "type", "MCTP Bridge Component")
    device_id = int(
        manifest_common.get_key_from_dict(xml_component, "deviceid",
                                          "MCTP Bridge Component"))
    vendor_id = int(
        manifest_common.get_key_from_dict(xml_component, "vendorid",
                                          "MCTP Bridge Component"))
    sub_device_id = int(
        manifest_common.get_key_from_dict(xml_component, "subdeviceid",
                                          "MCTP Bridge Component"))
    sub_vendor_id = int(
        manifest_common.get_key_from_dict(xml_component, "subvendorid",
                                          "MCTP Bridge Component"))
    sub_vendor_id = int(
        manifest_common.get_key_from_dict(xml_component, "subvendorid",
                                          "MCTP Bridge Component"))
    components_count = int(
        manifest_common.get_key_from_dict(xml_component, "count",
                                          "MCTP Bridge Component"))
    eid = int(
        manifest_common.get_key_from_dict(xml_component, "eid",
                                          "MCTP Bridge Component"))

    type_len = len(component_type)

    if type_len <= 255:
        padding_len = ((type_len + 3) & (~3)) - type_len
    else:
        raise ValueError("Component type too long: {0}".format(type_len))

    padding = (ctypes.c_ubyte * padding_len)()
    ctypes.memset(padding, 0, ctypes.sizeof(ctypes.c_ubyte) * padding_len)

    class pcd_mctp_bridge_component_element(ctypes.LittleEndianStructure):
        _pack_ = 1
        _fields_ = [('policy', ctypes.c_ubyte),
                    ('power_ctrl_reg', ctypes.c_ubyte),
                    ('power_ctrl_mask', ctypes.c_ubyte),
                    ('type_len', ctypes.c_ubyte),
                    ('type', ctypes.c_char * type_len),
                    ('type_padding', ctypes.c_ubyte * padding_len),
                    ('device_id', ctypes.c_ushort),
                    ('vendor_id', ctypes.c_ushort),
                    ('subsystem_device_id', ctypes.c_ushort),
                    ('subsystem_vendor_id', ctypes.c_ushort),
                    ('components_count', ctypes.c_ubyte),
                    ('eid', ctypes.c_ubyte), ('reserved', ctypes.c_ushort)]

    component = pcd_mctp_bridge_component_element(
        policy, powerctrl_reg, powerctrl_mask, type_len,
        component_type.encode('utf-8'), padding, device_id, vendor_id,
        sub_device_id, sub_vendor_id, components_count, eid, 0)
    component_len = ctypes.sizeof(component)

    component_toc_entry = manifest_common.manifest_toc_entry(
        manifest_common.PCD_V2_MCTP_BRIDGE_COMPONENT_TYPE_ID,
        manifest_common.V2_BASE_TYPE_ID, 1, 0, 0, component_len)

    component_hash = manifest_common.generate_hash(component, hash_engine)

    return component, component_toc_entry, component_hash
Пример #5
0
def generate_ports(xml_ports, hash_engine):
    """
    Create a list of SPI flash port objects from parsed XML list

    :param xml_ports: List of parsed XML of ports to be included in PCD

    :return Ports buffer, number of ports, list of port ToC entries, list of port hashes
    """

    if xml_ports is None or len(xml_ports) < 1:
        return None, 0, None, None

    ports = []
    toc_entries = []
    hashes = []
    num_ports = len(xml_ports)
    ports_len = 0

    class pcd_port(ctypes.LittleEndianStructure):
        _pack_ = 1
        _fields_ = [('port_id', ctypes.c_ubyte),
                    ('port_flags', ctypes.c_ubyte), ('policy', ctypes.c_ubyte),
                    ('pulse_interval', ctypes.c_ubyte),
                    ('spi_frequency_hz', ctypes.c_uint)]

    for id, port in xml_ports.items():
        spi_freq = int(
            manifest_common.get_key_from_dict(port, "spi_freq", "Port"))
        reset_ctrl = int(
            manifest_common.get_key_from_dict(port, "reset_ctrl", "Port"))
        flash_mode = int(
            manifest_common.get_key_from_dict(port, "flash_mode", "Port"))
        policy = int(manifest_common.get_key_from_dict(port, "policy", "Port"))
        runtime_verification = int(
            manifest_common.get_key_from_dict(port, "runtime_verification",
                                              "Port"))
        watchdog_monitoring = int(
            manifest_common.get_key_from_dict(port, "watchdog_monitoring",
                                              "Port"))
        pulse_interval = int(
            manifest_common.get_key_from_dict(port, "pulse_interval", "Port"))

        port_flags = (watchdog_monitoring << 5) | (runtime_verification << 4) | \
            (flash_mode << 2) | reset_ctrl

        port_buf = pcd_port(int(id), port_flags, policy, pulse_interval,
                            spi_freq)
        port_toc_entry = manifest_common.manifest_toc_entry(
            manifest_common.PCD_V2_SPI_FLASH_PORT_TYPE_ID,
            manifest_common.PCD_V2_ROT_TYPE_ID, 1, 0, 0,
            ctypes.sizeof(pcd_port))
        port_hash = manifest_common.generate_hash(port_buf, hash_engine)

        ports.append(port_buf)
        toc_entries.append(port_toc_entry)
        hashes.append(port_hash)

        ports_len += ctypes.sizeof(port_buf)

    ports_buf = (ctypes.c_ubyte * ports_len)()
    offset = 0

    for port in ports:
        port_len = ctypes.sizeof(port)
        ctypes.memmove(
            ctypes.addressof(ports_buf) + offset, ctypes.addressof(port),
            port_len)

        offset += port_len

    return ports_buf, num_ports, toc_entries, hashes
Пример #6
0
def generate_direct_component_buf(xml_component):
    """
    Create a direct component object from parsed XML list

    :param xml_component: List of parsed XML of component to be included in direct component object

    :return Instance of a component object, component's TOC entry, component hash
    """

    if xml_component["interface"]["type"] != 0:
        raise ValueError(
            "Unsupported direct component interface type: {0}".format(
                xml_component["interface"]["type"]))

    policy = int(
        manifest_common.get_key_from_dict(xml_component, "policy",
                                          "Direct Component"))
    powerctrl_reg = int(
        manifest_common.get_key_from_dict(xml_component["powerctrl"],
                                          "register", "Direct Component"))
    powerctrl_mask = int(
        manifest_common.get_key_from_dict(xml_component["powerctrl"], "mask",
                                          "Direct Component"))
    component_type = manifest_common.get_key_from_dict(xml_component, "type",
                                                       "Direct Component")
    i2c_mode = int(
        manifest_common.get_key_from_dict(xml_component["interface"],
                                          "i2c_mode", "Direct Component"))
    bus = int(
        manifest_common.get_key_from_dict(xml_component["interface"], "bus",
                                          "Direct Component"))
    address = int(
        manifest_common.get_key_from_dict(xml_component["interface"],
                                          "address", "Direct Component"))
    eid = int(
        manifest_common.get_key_from_dict(xml_component["interface"], "eid",
                                          "Direct Component"))

    type_len = len(component_type)
    i2c_flags = i2c_mode

    if type_len <= 255:
        padding_len = ((type_len + 3) & (~3)) - type_len
    else:
        raise ValueError("Component type too long: {0}".format(type_len))

    padding = (ctypes.c_ubyte * padding_len)()
    ctypes.memset(padding, 0, ctypes.sizeof(ctypes.c_ubyte) * padding_len)

    if "muxes" in xml_component["interface"]:
        muxes, muxes_len, num_muxes = generate_muxes_buf(
            xml_component["interface"]["muxes"])
    else:
        muxes = (ctypes.c_ubyte * 0)()
        muxes_len = 0
        num_muxes = 0

    class pcd_direct_i2c_component_element(ctypes.LittleEndianStructure):
        _pack_ = 1
        _fields_ = [('policy', ctypes.c_ubyte),
                    ('power_ctrl_reg', ctypes.c_ubyte),
                    ('power_ctrl_mask', ctypes.c_ubyte),
                    ('type_len', ctypes.c_ubyte),
                    ('type', ctypes.c_char * type_len),
                    ('type_padding', ctypes.c_ubyte * padding_len),
                    ('mux_count', ctypes.c_ubyte, 4),
                    ('i2c_flags', ctypes.c_ubyte, 4), ('bus', ctypes.c_ubyte),
                    ('address', ctypes.c_ubyte), ('eid', ctypes.c_ubyte),
                    ('muxes', ctypes.c_ubyte * muxes_len)]

    component = pcd_direct_i2c_component_element(
        policy, powerctrl_reg, powerctrl_mask, type_len,
        component_type.encode('utf-8'), padding, num_muxes, i2c_flags, bus,
        address, eid, muxes)
    component_len = ctypes.sizeof(component)

    component_toc_entry = manifest_common.manifest_toc_entry(
        manifest_common.PCD_V2_DIRECT_COMPONENT_TYPE_ID,
        manifest_common.V2_BASE_TYPE_ID, 1, 0, 0, component_len)

    component_hash = manifest_common.generate_hash(component, hash_engine)

    return component, component_toc_entry, component_hash