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