Merged PR 1626: support v2 pcds

support v2 pcds

Related work items: #499, #840, #863, #885
This commit is contained in:
Akram Hamdy 2021-02-24 22:33:45 +00:00
Родитель de051b8c0d
Коммит 6306b55da5
14 изменённых файлов: 2722 добавлений и 3072 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -11,4 +11,4 @@ build
*~
*.bin
*.pyc
tools/manifest_visualizer/manifest_visualizor

Просмотреть файл

@ -19,8 +19,8 @@
#define PFM_V2_MAGIC_NUM 0x706D
#define CFM_MAGIC_NUM 0xA592
#define CFM_V2_MAGIC_NUM MANIFEST_NOT_SUPPORTED
#define PCD_MAGIC_NUM 0x8EBC
#define PCD_V2_MAGIC_NUM MANIFEST_NOT_SUPPORTED
#define PCD_MAGIC_NUM MANIFEST_NOT_SUPPORTED
#define PCD_V2_MAGIC_NUM 0x1029
/**
* Identifier for the hash algorithm used for signatures and other verificitaion hashes in
@ -58,6 +58,7 @@ enum manifest_key_type {
*/
#define manifest_get_key_type(sig_type) ((enum manifest_key_type) ((sig_type) & 0xf8))
#pragma pack(push, 1)
/**
* The header information on a manifest.
*/
@ -138,6 +139,7 @@ struct manifest_platform_id {
uint8_t id_length; /**< Length of the platform ID string. */
uint8_t reserved[3]; /**< Unused. */
};
#pragma pack(pop)
#endif /* MANIFEST_FORMAT_H_ */

Просмотреть файл

@ -13,28 +13,45 @@
/**
* I2C interface modes
*/
enum {
PCD_I2C_MULTIMASTER = 0,
PCD_I2C_MASTER_SLAVE,
NUM_PCD_I2C_MODES
};
/**
* Container for a RoT info.
* Container for RoT info.
*/
struct pcd_rot_info {
bool is_pa_rot; /**< Flag indicating if RoT is a PA-RoT */
uint8_t port_count; /**< Number of ports directly protected by RoT */
uint8_t components_count; /**< Number of componenets attested by RoT */
uint8_t i2c_slave_addr; /**< I2C slave address */
uint8_t bmc_i2c_addr; /**< BMC I2C address */
uint8_t eid; /**< MCTP EID */
uint8_t bridge_i2c_addr; /**< MCTP bridge I2C address */
uint8_t bridge_eid; /**< MCTP bridge EID */
};
/**
* Container for an RoT port info.
* Container for RoT port info.
*/
struct pcd_port_info {
uint32_t spi_freq; /**< Port SPI frequency */
uint8_t flash_mode; /**< Port flash mode */
uint8_t reset_ctrl; /**< Port reset control */
uint8_t policy; /**< Port attestation policy */
};
/**
* Container for power controller info.
*/
struct pcd_power_controller_info {
uint8_t mux_count; /**< Number of muxes to reach power controller */
uint8_t i2c_mode; /**< Power controller I2C mode */
uint8_t bus; /**< Bus power controller is on */
uint8_t address; /**< Power controller address */
uint8_t eid; /**< MCTP EID used by power controller if any */
};
/**
* Containter for mux info.
*/
struct pcd_mux_info {
uint8_t address; /**< Mux address */
uint8_t channel; /**< Mux channel to utilize */
};
/**
@ -76,6 +93,16 @@ struct pcd {
* @return 0 if the port info was retrieved successfully or an error code.
*/
int (*get_port_info) (struct pcd *pcd, uint8_t port_id, struct pcd_port_info *info);
/**
* Get power controller info.
*
* @param pcd The PCD to query.
* @param info Container with power controller info.
*
* @return 0 if the power controller info was retrieved successfully or an error code.
*/
int (*get_power_controller_info) (struct pcd *pcd, struct pcd_power_controller_info *info);
};
@ -85,13 +112,13 @@ struct pcd {
* Error codes that can be generated by a PCD.
*/
enum {
PCD_INVALID_ARGUMENT = PCD_ERROR (0x00), /**< Input parameter is null or not valid. */
PCD_NO_MEMORY = PCD_ERROR (0x01), /**< Memory allocation failed. */
PCD_BUF_TOO_SMALL = PCD_ERROR (0x02), /**< The buffer provided is too small for requested contents. */
PCD_UNKNOWN_COMPONENT = PCD_ERROR (0x03), /**< The component identifier is not present in the PCD. */
PCD_INVALID_SEG_LEN = PCD_ERROR (0x04), /**< Segment in PCD has invalid length. */
PCD_INVALID_SEG_HDR_LEN = PCD_ERROR (0x05), /**< Segment header in PCD has invalid length. */
PCD_INVALID_PORT = PCD_ERROR (0x06), /**< Port not found in PCD. */
PCD_INVALID_ARGUMENT = PCD_ERROR (0x00), /**< Input parameter is null or not valid. */
PCD_NO_MEMORY = PCD_ERROR (0x01), /**< Memory allocation failed. */
PCD_INVALID_PORT = PCD_ERROR (0x02), /**< Port not found in PCD. */
PCD_UNKNOWN_COMPONENT = PCD_ERROR (0x03), /**< The component identifier is not present in the PCD. */
PCD_MALFORMED_ROT_ELEMENT = PCD_ERROR (0x04), /**< PCD RoT element too short. */
PCD_MALFORMED_DIRECT_I2C_COMPONENT_ELEMENT = PCD_ERROR (0x05), /**< PCD direct i2c component element too short. */
PCD_MALFORMED_BRIDGE_COMPONENT_ELEMENT = PCD_ERROR (0x06), /**< PCD bridge component element too short. */
};

Просмотреть файл

@ -16,176 +16,13 @@ static int pcd_flash_verify (struct manifest *pcd, struct hash_engine *hash,
struct signature_verification *verification, uint8_t *hash_out, size_t hash_length)
{
struct pcd_flash *pcd_flash = (struct pcd_flash*) pcd;
struct flash *flash_device;
struct pcd_header pcd_header;
struct pcd_rot_header pcd_rot_header;
struct pcd_port_header pcd_port_header;
struct pcd_components_header pcd_components_header;
struct pcd_component_header pcd_component_header;
struct pcd_mux_header pcd_mux_header;
struct pcd_platform_header pcd_platform_header;
uint32_t pcd_addr;
uint16_t pcd_len;
uint16_t pcd_rot_len;
uint16_t pcd_components_len;
uint16_t pcd_component_len;
uint8_t index;
uint8_t index2;
int status;
if ((pcd_flash == NULL) || (hash == NULL) || (verification == NULL)) {
if (pcd_flash == NULL) {
return PCD_INVALID_ARGUMENT;
}
status = manifest_flash_verify (&pcd_flash->base_flash, hash, verification, hash_out,
return manifest_flash_verify (&pcd_flash->base_flash, hash, verification, hash_out,
hash_length);
if (status != 0) {
return status;
}
pcd_len = pcd_flash->base_flash.header.length -
(pcd_flash->base_flash.header.sig_length + sizeof (struct manifest_header));
pcd_addr = pcd_flash->base_flash.addr + sizeof (struct manifest_header);
flash_device = pcd_flash->base_flash.flash;
status = flash_device->read (flash_device, pcd_addr, (uint8_t*) &pcd_header,
sizeof (struct pcd_header));
if (status != 0) {
goto error;
}
if (pcd_len != pcd_header.length) {
status = PCD_INVALID_SEG_LEN;
goto error;
}
pcd_len -= pcd_header.header_len;
pcd_addr += pcd_header.header_len;
status = flash_device->read (flash_device, pcd_addr, (uint8_t*) &pcd_rot_header,
sizeof (struct pcd_rot_header));
if (status != 0) {
goto error;
}
if (pcd_len < pcd_rot_header.length) {
status = PCD_INVALID_SEG_LEN;
goto error;
}
pcd_rot_len = pcd_rot_header.length - pcd_rot_header.header_len;
pcd_addr += pcd_rot_header.header_len;
for (index = 0; index < pcd_rot_header.num_ports; ++index) {
status = flash_device->read (flash_device, pcd_addr, (uint8_t*) &pcd_port_header,
sizeof (struct pcd_port_header));
if (status != 0) {
goto error;
}
pcd_addr += pcd_port_header.length;
pcd_rot_len -= pcd_port_header.length;
}
if (pcd_rot_len != 0) {
status = PCD_INVALID_SEG_LEN;
goto error;
}
pcd_len -= pcd_rot_header.length;
status = flash_device->read (flash_device, pcd_addr, (uint8_t*) &pcd_components_header,
sizeof (struct pcd_components_header));
if (status != 0) {
goto error;
}
if (pcd_len < pcd_components_header.length) {
status = PCD_INVALID_SEG_LEN;
goto error;
}
pcd_addr += pcd_components_header.header_len;
pcd_components_len = pcd_components_header.length - pcd_components_header.header_len;
for (index = 0; index < pcd_components_header.num_components; ++index) {
status = flash_device->read (flash_device, pcd_addr, (uint8_t*) &pcd_component_header,
sizeof (struct pcd_component_header));
if (status != 0) {
goto error;
}
pcd_component_len = pcd_component_header.length - pcd_component_header.header_len;
if (pcd_components_len < pcd_component_len) {
status = PCD_INVALID_SEG_LEN;
goto error;
}
pcd_addr += pcd_component_header.header_len;
for (index2 = 0; index2 < pcd_component_header.num_muxes; ++index2) {
status = flash_device->read (flash_device, pcd_addr, (uint8_t*) &pcd_mux_header,
sizeof (struct pcd_mux_header));
if (status != 0) {
goto error;
}
pcd_addr += pcd_mux_header.length;
pcd_component_len -= pcd_mux_header.length;
}
if (pcd_component_len != 0) {
status = PCD_INVALID_SEG_LEN;
goto error;
}
pcd_components_len -= pcd_component_header.length;
}
if (pcd_components_len != 0) {
status = PCD_INVALID_SEG_LEN;
goto error;
}
pcd_len -= pcd_components_header.length;
status = flash_device->read (flash_device, pcd_addr, (uint8_t*) &pcd_platform_header,
sizeof (struct pcd_platform_header));
if (status != 0) {
goto error;
}
if (pcd_len != pcd_platform_header.length) {
status = PCD_INVALID_SEG_LEN;
goto error;
}
if (pcd_platform_header.length !=
(pcd_platform_header.header_len + pcd_platform_header.id_len)) {
status = PCD_INVALID_SEG_HDR_LEN;
goto error;
}
if (pcd_platform_header.length >= pcd_flash->base_flash.max_platform_id) {
status = MANIFEST_PLAT_ID_BUFFER_TOO_SMALL;
goto error;
}
pcd_addr += sizeof (struct pcd_platform_header);
status = flash_device->read (flash_device, pcd_addr,
(uint8_t*) pcd_flash->base_flash.platform_id, pcd_platform_header.id_len);
if (status != 0) {
goto error;
}
pcd_flash->base_flash.platform_id[pcd_platform_header.id_len] = '\0';
return 0;
error:
/* Clearing this flag in validation error cases is not tested but is only temporary as v1 PCDs
* will be unsupported with the move to v2. */
pcd_flash->base_flash.manifest_valid = false;
return status;
}
static int pcd_flash_get_id (struct manifest *pcd, uint32_t *id)
@ -241,12 +78,9 @@ static int pcd_flash_get_signature (struct manifest *pcd, uint8_t *signature, si
static int pcd_flash_get_port_info (struct pcd *pcd, uint8_t port_id, struct pcd_port_info *info)
{
struct pcd_flash *pcd_flash = (struct pcd_flash*) pcd;
struct pcd_header pcd_header;
struct pcd_rot_header rot_header;
struct pcd_port_header port_header;
struct flash *flash_device;
uint32_t next_addr;
size_t i_port;
struct pcd_rot_element *rot_element = NULL;
struct pcd_port *port_element;
int i_port;
int status;
if ((pcd_flash == NULL) || (info == NULL)) {
@ -257,49 +91,55 @@ static int pcd_flash_get_port_info (struct pcd *pcd, uint8_t port_id, struct pcd
return MANIFEST_NO_MANIFEST;
}
flash_device = pcd_flash->base_flash.flash;
status = flash_device->read (flash_device, pcd_flash->base_flash.addr +
sizeof (struct manifest_header), (uint8_t*) &pcd_header, sizeof (struct pcd_header));
if (status != 0) {
status = manifest_flash_read_element_data (&pcd_flash->base_flash, pcd_flash->base_flash.hash,
PCD_ROT, 0, MANIFEST_NO_PARENT, 0, NULL, NULL, NULL, (uint8_t**) &rot_element, 0);
if (ROT_IS_ERROR (status)) {
return status;
}
next_addr = pcd_flash->base_flash.addr + sizeof (struct manifest_header) +
pcd_header.header_len;
status = flash_device->read (flash_device, next_addr, (uint8_t*) &rot_header,
sizeof (struct pcd_rot_header));
if (status != 0) {
return status;
if (status < (int) (sizeof (struct pcd_rot_element))) {
status = PCD_MALFORMED_ROT_ELEMENT;
goto done;
}
next_addr += sizeof (struct pcd_rot_header);
for (i_port = 0; i_port < rot_header.num_ports; ++i_port) {
status = flash_device->read (flash_device, next_addr, (uint8_t*) &port_header,
sizeof (struct pcd_port_header));
if (status != 0) {
return status;
}
if (port_header.id == port_id) {
info->spi_freq = port_header.frequency;
return 0;
}
next_addr += sizeof (struct pcd_port_header);
if (rot_element->port_count == 0) {
goto port_not_found;
}
return PCD_INVALID_PORT;
if (status < (int) (sizeof (struct pcd_rot_element) +
sizeof (struct pcd_port) * rot_element->port_count)) {
status = PCD_MALFORMED_ROT_ELEMENT;
goto done;
}
port_element = (struct pcd_port*) (((uint8_t*) rot_element) + sizeof (struct pcd_rot_element));
for (i_port = 0; i_port < rot_element->port_count; ++i_port, ++port_element) {
if (port_element->port_id == port_id) {
info->spi_freq = port_element->spi_frequency_hz;
info->flash_mode = pcd_get_port_flash_mode (port_element);
info->reset_ctrl = pcd_get_port_reset_control (port_element);
info->policy = port_element->policy;
status = 0;
goto done;
}
}
port_not_found:
status = PCD_INVALID_PORT;
done:
platform_free (rot_element);
return status;
}
static int pcd_flash_get_rot_info (struct pcd *pcd, struct pcd_rot_info *info)
{
struct pcd_flash *pcd_flash = (struct pcd_flash*) pcd;
struct pcd_header pcd_header;
struct pcd_rot_header rot_header;
struct flash *flash_device;
uint32_t next_addr;
struct pcd_rot_element rot_element;
uint8_t *rot_element_ptr = (uint8_t*) &rot_element;
int status;
if ((pcd_flash == NULL) || (info == NULL)) {
@ -310,25 +150,56 @@ static int pcd_flash_get_rot_info (struct pcd *pcd, struct pcd_rot_info *info)
return MANIFEST_NO_MANIFEST;
}
flash_device = pcd_flash->base_flash.flash;
status = flash_device->read (flash_device, pcd_flash->base_flash.addr +
sizeof (struct manifest_header), (uint8_t*) &pcd_header, sizeof (struct pcd_header));
if (status != 0) {
status = manifest_flash_read_element_data (&pcd_flash->base_flash, pcd_flash->base_flash.hash,
PCD_ROT, 0, MANIFEST_NO_PARENT, 0, NULL, NULL, NULL, &rot_element_ptr,
sizeof (struct pcd_rot_element));
if (ROT_IS_ERROR (status)) {
return status;
}
next_addr = pcd_flash->base_flash.addr + sizeof (struct manifest_header) +
pcd_header.header_len;
status = flash_device->read (flash_device, next_addr, (uint8_t*) &rot_header,
sizeof (struct pcd_rot_header));
if (status != 0) {
if (status < (int) sizeof (struct pcd_rot_element)) {
return PCD_MALFORMED_ROT_ELEMENT;
}
info->is_pa_rot = (pcd_get_rot_type (&rot_element) == PCD_ROT_TYPE_PA_ROT);
info->port_count = rot_element.port_count;
info->components_count = rot_element.components_count;
info->i2c_slave_addr = rot_element.rot_address;
info->eid = rot_element.rot_eid;
info->bridge_i2c_addr = rot_element.bridge_address;
info->bridge_eid = rot_element.bridge_eid;
return 0;
}
static int pcd_flash_get_power_controller_info (struct pcd *pcd,
struct pcd_power_controller_info *info)
{
struct pcd_flash *pcd_flash = (struct pcd_flash*) pcd;
struct pcd_power_controller_element power_controller_element;
uint8_t *power_controller_element_ptr = (uint8_t*) &power_controller_element;
int status;
if ((pcd_flash == NULL) || (info == NULL)) {
return PCD_INVALID_ARGUMENT;
}
if (!pcd_flash->base_flash.manifest_valid) {
return MANIFEST_NO_MANIFEST;
}
status = manifest_flash_read_element_data (&pcd_flash->base_flash, pcd_flash->base_flash.hash,
PCD_POWER_CONTROLLER, 0, MANIFEST_NO_PARENT, 0, NULL, NULL, NULL,
&power_controller_element_ptr, sizeof (struct pcd_power_controller_element));
if (ROT_IS_ERROR (status)) {
return status;
}
info->is_pa_rot = (rot_header.flags & PCD_ROT_HDR_IS_PA_ROT_SET_MASK);
info->i2c_slave_addr = rot_header.addr;
info->bmc_i2c_addr = rot_header.bmc_i2c_addr;
info->mux_count = power_controller_element.i2c.mux_count;
info->i2c_mode = pcd_get_i2c_interface_i2c_mode (&power_controller_element.i2c);
info->bus = power_controller_element.i2c.bus;
info->address = power_controller_element.i2c.address;
info->eid = power_controller_element.i2c.eid;
return 0;
}
@ -337,23 +208,22 @@ static int pcd_flash_get_devices_info (struct pcd *pcd, struct device_manager_in
size_t *num_devices)
{
struct pcd_flash *pcd_flash = (struct pcd_flash*) pcd;
struct pcd_header pcd_header;
struct pcd_rot_header rot_header;
struct pcd_components_header components_header;
struct pcd_component_header component_header;
struct flash *flash_device;
uint32_t next_addr;
size_t i_component;
struct device_manager_info *device_ptr;
struct pcd_i2c_interface *interface;
struct pcd_mctp_bridge_component_connection *connection;
union {
struct pcd_rot_info rot_info;
struct pcd_direct_i2c_component_element direct_component;
struct pcd_mctp_bridge_component_element bridge_component;
} buffer;
uint8_t *element_ptr;
uint8_t i_component;
uint8_t found;
size_t type_len;
int start = 0;
int status;
if ((devices == NULL) || (num_devices == NULL)) {
return PCD_INVALID_ARGUMENT;
}
*devices = NULL;
*num_devices = 0;
if (pcd_flash == NULL) {
if ((pcd_flash == NULL) || (devices == NULL) || (num_devices == NULL)) {
return PCD_INVALID_ARGUMENT;
}
@ -361,57 +231,83 @@ static int pcd_flash_get_devices_info (struct pcd *pcd, struct device_manager_in
return MANIFEST_NO_MANIFEST;
}
flash_device = pcd_flash->base_flash.flash;
status = flash_device->read (flash_device, pcd_flash->base_flash.addr +
sizeof (struct manifest_header), (uint8_t*) &pcd_header, sizeof (struct pcd_header));
status = pcd_flash_get_rot_info (pcd, &buffer.rot_info);
if (status != 0) {
return status;
}
next_addr = pcd_flash->base_flash.addr + sizeof (struct manifest_header) +
pcd_header.header_len;
status = flash_device->read (flash_device, next_addr, (uint8_t*) &rot_header,
sizeof (struct pcd_rot_header));
if (status != 0) {
return status;
if (buffer.rot_info.components_count == 0) {
*num_devices = 0;
return 0;
}
next_addr += rot_header.length;
status = flash_device->read (flash_device, next_addr, (uint8_t*) &components_header,
sizeof (struct pcd_components_header));
if (status != 0) {
return status;
}
*devices = platform_calloc (components_header.num_components,
sizeof (struct device_manager_info));
*num_devices = buffer.rot_info.components_count;
*devices = platform_calloc (*num_devices, sizeof (struct device_manager_info));
if (*devices == NULL) {
return PCD_NO_MEMORY;
}
*num_devices = components_header.num_components;
next_addr += sizeof (struct pcd_components_header);
device_ptr = *devices;
element_ptr = (uint8_t*) &buffer.direct_component;
for (i_component = 0; i_component < components_header.num_components; ++i_component) {
status = flash_device->read (flash_device, next_addr, (uint8_t*) &component_header,
sizeof (struct pcd_component_header));
if (status != 0) {
platform_free ((void*) *devices);
*num_devices = 0;
*devices = NULL;
return status;
for (i_component = 0; i_component < *num_devices; ++i_component) {
status = manifest_flash_read_element_data (&pcd_flash->base_flash,
pcd_flash->base_flash.hash, PCD_COMPONENT_DIRECT, start, MANIFEST_NO_PARENT, 0, &found,
NULL, NULL, &element_ptr, sizeof (struct pcd_direct_i2c_component_element));
if (status == MANIFEST_ELEMENT_NOT_FOUND) {
break;
}
if (ROT_IS_ERROR (status)) {
goto fail;
}
if (((size_t) status) <
(sizeof (struct pcd_direct_i2c_component_element) - MANIFEST_MAX_STRING)) {
status = PCD_MALFORMED_DIRECT_I2C_COMPONENT_ELEMENT;
goto fail;
}
next_addr += sizeof (struct pcd_component_header);
type_len = ((buffer.direct_component.component.type_len + 3) & ~((size_t) 3));
interface = (struct pcd_i2c_interface*) (element_ptr +
(sizeof (struct pcd_component_common) - MANIFEST_MAX_STRING + type_len));
(*devices)[i_component].smbus_addr = component_header.addr;
(*devices)[i_component].eid = component_header.eid;
device_ptr->eid = interface->eid;
device_ptr->smbus_addr = interface->address;
start = found + 1;
++device_ptr;
}
start = 0;
element_ptr = (uint8_t*) &buffer.bridge_component;
for (; i_component < *num_devices; ++i_component) {
status = manifest_flash_read_element_data (&pcd_flash->base_flash,
pcd_flash->base_flash.hash, PCD_COMPONENT_MCTP_BRIDGE, start, MANIFEST_NO_PARENT, 0,
&found, NULL, NULL, &element_ptr, sizeof (struct pcd_mctp_bridge_component_element));
if (ROT_IS_ERROR (status)) {
goto fail;
}
if ((size_t) status <
(sizeof (struct pcd_mctp_bridge_component_element) - MANIFEST_MAX_STRING)) {
status = PCD_MALFORMED_BRIDGE_COMPONENT_ELEMENT;
goto fail;
}
connection = pcd_get_mctp_bridge_component_connection (element_ptr, status);
device_ptr->eid = connection->eid;
start = found + 1;
++device_ptr;
}
return 0;
fail:
platform_free (*devices);
return status;
}
/**
@ -419,6 +315,9 @@ static int pcd_flash_get_devices_info (struct pcd *pcd, struct device_manager_in
*
* @param pcd The PCD instance to initialize.
* @param flash The flash device that contains the PCD.
* @param hash A hash engine to use for validating run-time access to PCD information. If it is
* possible for any PCD information to be requested concurrently by different threads, this hash
* engine MUST be thread-safe. There is no internal synchronization around the hashing operations.
* @param base_addr The starting address of the PCD storage location.
* @param signature_cache Buffer to hold the manifest signature.
* @param max_signature The maximum supported length for a manifest signature.
@ -427,8 +326,8 @@ static int pcd_flash_get_devices_info (struct pcd *pcd, struct device_manager_in
*
* @return 0 if the PCD instance was initialized successfully or an error code.
*/
int pcd_flash_init (struct pcd_flash *pcd, struct flash *flash, uint32_t base_addr,
uint8_t *signature_cache, size_t max_signature, uint8_t *platform_id_cache,
int pcd_flash_init (struct pcd_flash *pcd, struct flash *flash, struct hash_engine *hash,
uint32_t base_addr, uint8_t *signature_cache, size_t max_signature, uint8_t *platform_id_cache,
size_t max_platform_id)
{
int status;
@ -439,7 +338,7 @@ int pcd_flash_init (struct pcd_flash *pcd, struct flash *flash, uint32_t base_ad
memset (pcd, 0, sizeof (struct pcd_flash));
status = manifest_flash_v2_init (&pcd->base_flash, flash, NULL, base_addr, PCD_MAGIC_NUM,
status = manifest_flash_v2_init (&pcd->base_flash, flash, hash, base_addr, PCD_MAGIC_NUM,
PCD_V2_MAGIC_NUM, signature_cache, max_signature, platform_id_cache, max_platform_id);
if (status != 0) {
return status;
@ -455,6 +354,7 @@ int pcd_flash_init (struct pcd_flash *pcd, struct flash *flash, uint32_t base_ad
pcd->base.get_port_info = pcd_flash_get_port_info;
pcd->base.get_rot_info = pcd_flash_get_rot_info;
pcd->base.get_devices_info = pcd_flash_get_devices_info;
pcd->base.get_power_controller_info = pcd_flash_get_power_controller_info;
return 0;
}

Просмотреть файл

@ -19,8 +19,8 @@ struct pcd_flash {
};
int pcd_flash_init (struct pcd_flash *pcd, struct flash *flash, uint32_t base_addr,
uint8_t *signature_cache, size_t max_signature, uint8_t *platform_id_cache,
int pcd_flash_init (struct pcd_flash *pcd, struct flash *flash, struct hash_engine *hash,
uint32_t base_addr, uint8_t *signature_cache, size_t max_signature, uint8_t *platform_id_cache,
size_t max_platform_id);
void pcd_flash_release (struct pcd_flash *pcd);

Просмотреть файл

@ -8,135 +8,200 @@
#include "manifest/manifest_format.h"
#define PCD_ROT_HDR_IS_PA_ROT_SHIFT 0
#define PCD_ROT_HDR_IS_PA_ROT_SET_MASK (1U << PCD_ROT_HDR_IS_PA_ROT_SHIFT)
#define PCD_ROT_HDR_IS_PA_ROT_CLR_MASK (~PCD_ROT_HDR_IS_PA_ROT_SET_MASK)
#define PCD_COMPONENT_HDR_I2C_MODE_SHIFT 0
#define PCD_COMPONENT_HDR_I2C_MODE_SET_MASK (1U << PCD_COMPONENT_HDR_I2C_MODE_SHIFT)
#define PCD_COMPONENT_HDR_I2C_MODE_CLR_MASK (~PCD_COMPONENT_HDR_I2C_MODE_SET_MASK)
/**
* Type identifiers for PCD v2 elements.
*/
enum pcd_element_type {
PCD_ROT = 0x40, /**< Information about the RoT configuration. */
PCD_POWER_CONTROLLER = 0x41, /**< Information about power controller utilized by RoT. */
PCD_COMPONENT_DIRECT = 0x42, /**< A single component connected directly to RoT. */
PCD_COMPONENT_MCTP_BRIDGE = 0x43, /**< A components connected to RoT through an MCTP bridge. */
};
/**
* The PCD is a variable length structure that has the following format:
* Flags for policy failure action.
*/
enum pcd_policy_failure_action {
PCD_POLICY_FAILURE_ACTION_PASSIVE = 0x0, /**< Report policy failure through attestation. */
PCD_POLICY_FAILURE_ACTION_ACTIVE = 0x1, /**< Prevent failed device from booting. */
};
#pragma pack(push, 1)
struct pcd_rot_element {
uint8_t rot_flags; /**< Flags pertaining to RoT configuration. */
uint8_t port_count; /**< The number of ports protected by RoT. */
uint8_t components_count; /**< The number of components attested by RoT. */
uint8_t rot_address; /**< RoT slave address to utilize. */
uint8_t rot_eid; /**< Default RoT MCTP EID to utilize. */
uint8_t bridge_address; /**< MCTP bridge slave address. */
uint8_t bridge_eid; /**< MCTP bridge EID. */
uint8_t reserved; /**< Unused. */
};
#define PCD_ROT_FLAGS_ROT_TYPE_SHIFT 0
#define PCD_ROT_FLAGS_ROT_TYPE_SET_MASK (1 << PCD_ROT_FLAGS_ROT_TYPE_SHIFT)
/**
* Flags for RoT configuration.
*/
enum pcd_rot_type_flags {
PCD_ROT_TYPE_PA_ROT = 0x0, /**< PA-ROT. */
PCD_ROT_TYPE_AC_ROT = 0x1, /**< AC-ROT. */
};
/**
* Get RoT type.
*
* struct {
* struct manifest_header
* struct pcd_header
* struct pcd_rot_header
* <struct pcd_port_header> [pcd_rot_header.num_ports]
* struct pcd_components_header
* <components> [pcd_components_header.num_components]
* struct pcd_platform_header
* char platform_id[pcd_platform_header.id_len]
* uint8_t signature[manifest_header.sig_length]
* }
* @param rot Pointer to a pcd_rot element.
*/
#define pcd_get_rot_type(rot) (enum pcd_rot_type_flags) (((rot)->rot_flags) & \
PCD_ROT_FLAGS_ROT_TYPE_SET_MASK)
/**
* A port section defined in PCD as part of RoT element.
*/
struct pcd_port {
uint8_t port_id; /**< Port ID. */
uint8_t port_flags; /**< Flags with port configuration. */
uint8_t policy; /**< Port attestation policy. */
uint8_t reserved; /**< Unused. */
uint32_t spi_frequency_hz; /**< Flash SPI frequency in Hz. */
};
#define PCD_PORT_FLAGS_FLASH_MODE_SHIFT 2
#define PCD_PORT_FLAGS_FLASH_MODE_SET_MASK (3 << PCD_PORT_FLAGS_FLASH_MODE_SHIFT)
#define PCD_PORT_FLAGS_RESET_CTRL_SHIFT 0
#define PCD_PORT_FLAGS_RESET_CTRL_SET_MASK (3 << PCD_PORT_FLAGS_RESET_CTRL_SHIFT)
/**
* Flags for port flash mode.
*/
enum pcd_port_flash_mode {
PCD_PORT_FLASH_MODE_DUAL = 0x0, /**< Dual flash mode. */
PCD_PORT_FLASH_MODE_SINGLE = 0x1, /**< Single flash mode. */
};
/**
* Flags for port reset control.
*/
enum pcd_port_reset_control {
PCD_PORT_RESET_CTRL_NOTIFY = 0x0, /**< Notify when port reset pin toggled. */
PCD_PORT_RESET_CTRL_RESET = 0x1, /**< Reset port when port reset pin toggled. */
};
/**
* Get port flash mode.
*
* Each component is a variable length structure that has the following format:
* @param port Pointer to a pcd_port element.
*/
#define pcd_get_port_flash_mode(port) (enum pcd_port_flash_mode) ((((port)->port_flags) & \
PCD_PORT_FLAGS_FLASH_MODE_SET_MASK) >> PCD_PORT_FLAGS_FLASH_MODE_SHIFT)
/**
* Get port reset control setting.
*
* struct {
* struct pcd_component_header
* <struct pcd_mux_header> [pcd_component_header.num_muxes]
* }
* @param port Pointer to a pcd_port element.
*/
#define pcd_get_port_reset_control(port) (enum pcd_port_reset_control) (((port)->port_flags) & \
PCD_PORT_FLAGS_RESET_CTRL_SET_MASK)
/**
* The header information for the PCD.
* A single I2C mux section.
*/
struct pcd_header {
uint16_t length; /**< Total length of PCD without manifest header and signature. */
uint16_t header_len; /**< PCD header length. */
uint8_t format_id; /**< PCD format ID. */
uint8_t reserved1; /**< Reserved. */
uint8_t reserved2; /**< Reserved. */
uint8_t reserved3; /**< Reserved. */
struct pcd_mux {
uint8_t mux_address; /**< I2C slave address of mux. */
uint8_t mux_channel; /**< Channel to activate on mux. */
uint16_t reserved; /**< Unused. */
};
/**
* The header information for the PCD RoT.
* Container for fields common to I2C interface sections in elements.
*/
struct pcd_rot_header {
uint16_t length; /**< Total length of PCD RoT section including header. */
uint16_t header_len; /**< Length of PCD RoT header. */
uint8_t format_id; /**< PCD RoT format ID. */
uint8_t num_ports; /**< Number of ports in RoT. */
uint8_t addr; /**< I2C slave address */
uint8_t bmc_i2c_addr; /**< BMC I2C address */
uint8_t cpld_addr; /**< CPLD I2C slave address */
uint8_t cpld_channel; /**< CPLD I2C bus channel */
uint8_t active; /**< Policy active */
uint8_t default_failure_action; /**< Default action on attestation failure */
uint8_t flags; /**< Field for flags */
uint8_t reserved1; /**< Reserved. */
uint8_t reserved2; /**< Reserved. */
uint8_t reserved3; /**< Reserved. */
struct pcd_i2c_interface {
uint8_t mux_count:4; /**< Number of muxes in I2C path from RoT to device. */
uint8_t i2c_flags:4; /**< Flags with I2C configuration. */
uint8_t bus; /**< I2C bus device is on. */
uint8_t address; /**< Device I2C slave address. */
uint8_t eid; /**< Device MCTP EID, 0x00 if not utilizing MCTP. */
};
#define PCD_I2C_FLAGS_I2C_MODE_SHIFT 0
#define PCD_I2C_FLAGS_I2C_MODE_SET_MASK (3 << PCD_I2C_FLAGS_I2C_MODE_SHIFT)
/**
* Flags for I2C mode.
*/
enum pcd_i2c_mode {
PCD_I2C_MODE_MULTIMASTER = 0x0, /**< MultiMaster I2C communication scheme. */
PCD_I2C_MODE_MASTER_SLAVE = 0x1, /**< Master/Slave I2C communication scheme. */
};
/**
* The header information for a RoT port section.
* Get i2c mode for i2c interface.
*
* @param i2c Pointer to a pcd_i2c_interface element.
*/
struct pcd_port_header {
uint16_t length; /**< Total length of RoT ports section. */
uint16_t header_len; /**< Length of PCD port header. */
uint8_t format_id; /**< RoT ports format ID. */
uint8_t id; /**< Port ID */
uint8_t reserverd1; /**< Reserved. */
uint8_t reserverd2; /**< Reserved. */
uint32_t frequency; /**< Bus frequency */
#define pcd_get_i2c_interface_i2c_mode(i2c) (enum pcd_i2c_mode) (((i2c)->i2c_flags) & \
PCD_I2C_FLAGS_I2C_MODE_SET_MASK)
/**
* An I2C power controller element.
*/
struct pcd_power_controller_element {
struct pcd_i2c_interface i2c; /**< Power controller I2C interface. */
};
/**
* The header information for the PCD components section.
* Container for fields common to component elements.
*/
struct pcd_components_header {
uint16_t length; /**< Total length of PCD components section. */
uint16_t header_len; /**< Length of PCD components header. */
uint8_t format_id; /**< PCD components format ID. */
uint8_t num_components; /**< Number of components in PCD. */
uint8_t reserved1; /**< Reserved. */
uint8_t reserved2; /**< Reserved. */
struct pcd_component_common {
uint8_t policy; /**< Component attestation policy. */
uint8_t power_ctrl_reg; /**< Power control register. */
uint8_t power_ctrl_mask; /**< Power control mask. */
uint8_t type_len; /**< Component type length. */
uint8_t type[MANIFEST_MAX_STRING]; /**< Component type. */
};
/**
* The header information for a PCD component.
* Element for a component with direct I2C connection to RoT.
*/
struct pcd_component_header {
uint16_t length; /**< Total length of PCD component. */
uint16_t header_len; /**< Length of PCD component header. */
uint8_t format_id; /**< PCD component format ID. */
uint8_t num_muxes; /**< Number of muxes in component. */
uint8_t addr; /**< I2C slave address */
uint8_t channel; /**< I2C bus channel */
uint8_t flags; /**< Field for flags */
uint8_t eid; /**< MCTP EID */
uint8_t power_ctrl_reg; /**< Power control register */
uint8_t power_ctrl_mask; /**< Power control bitmask */
uint32_t id; /**< Component ID. */
struct pcd_direct_i2c_component_element {
struct pcd_component_common component; /**< Common component configuration. */
struct pcd_i2c_interface i2c; /**< Component I2C interface. */
};
/**
* The header information for a mux section.
* Container for connection information for a component with connection to RoT through MCTP bridge.
*/
struct pcd_mux_header {
uint16_t length; /**< Total length of component mux section. */
uint16_t header_len; /**< Length of PCD mux header */
uint8_t format_id; /**< Component mux format ID. */
uint8_t addr; /**< I2C slave address */
uint8_t channel; /**< I2C bus channel */
uint8_t mux_level; /**< Mux level */
struct pcd_mctp_bridge_component_connection {
uint16_t device_id; /**< Device ID. */
uint16_t vendor_id; /**< Vendor ID. */
uint16_t subsystem_device_id; /**< Subsystem device ID. */
uint16_t subsystem_vendor_id; /**< Subsystem vendor ID. */
uint8_t components_count; /**< Number of identical components this element describes. */
uint8_t eid; /**< Default EID to use if cannot retrieve EID table from MCTP bridge. */
uint16_t reserved; /**< Unused. */
};
/**
* The header information for the platform information.
* Element for a component with connection to RoT through MCTP bridge.
*/
struct pcd_platform_header {
uint16_t length; /**< The total length of the platform descriptor. */
uint16_t header_len; /**< Length of PCD platform header. */
uint8_t format_id; /**< PCD platform header format ID. */
uint8_t id_len; /**< Platform ID length. */
uint8_t reserved1; /**< Reserved. */
uint8_t reserved2; /**< Reserved. */
struct pcd_mctp_bridge_component_element {
struct pcd_component_common component; /**< Common component configuration. */
struct pcd_mctp_bridge_component_connection connection; /**< Component connection information. */
};
/**
* Get component connection portion from a MCTP bridge component element container.
*
* @param component Pointer to a buffer containing a pcd_mctp_bridge_component_element element.
* @param len Length of buffer
*/
#define pcd_get_mctp_bridge_component_connection(component, len) ((struct pcd_mctp_bridge_component_connection*) \
((component) + len - sizeof (struct pcd_mctp_bridge_component_connection)))
#pragma pack(pop)
#endif /* PCD_FORMAT_H_ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -5,6 +5,31 @@
#define PCD_TESTING_H_
#include <stdint.h>
#include "manifest_v2_testing.h"
/**
* Describe a test PFM structure.
*/
struct pcd_testing_data {
struct manifest_v2_testing_data manifest; /**< Common manifest components. */
size_t rot_len; /**< RoT element data length. */
uint32_t rot_offset; /**< Offset of the RoT element. */
int rot_entry; /**< TOC entry for the RoT element. */
int rot_hash; /**< TOC hash for the RoT element. */
size_t power_ctrl_len; /**< Power controller element data length. */
uint32_t power_ctrl_offset; /**< Offset of a power controller element. */
int power_ctrl_entry; /**< TOC entry for a power controller element. */
int power_ctrl_hash; /**< TOC hash for a power controller element. */
size_t bridge_component_len; /**< Bridge component element data length. */
uint32_t bridge_component_offset; /**< Offset of a bridge component element. */
int bridge_component_entry; /**< TOC entry for a bridge component element. */
int bridge_component_hash; /**< TOC hash for a bridge component element. */
size_t direct_component_len; /**< Direct component element data length. */
uint32_t direct_component_offset; /**< Offset of a direct component element. */
int direct_component_entry; /**< TOC entry for a direct component element. */
int direct_component_hash; /**< TOC hash for a direct component element. */
};
extern const uint8_t PCD_DATA[];
@ -32,10 +57,9 @@ extern const uint32_t PCD_PLATFORM_ID_OFFSET;
extern const char PCD_PLATFORM_ID[];
extern const size_t PCD_PLATFORM_ID_LEN;
/*
* Constant PCD sizes.
*/
#define PCD_HEADER_SIZE 12
extern const uint8_t PCD_TOC_HASH[];
extern const struct pcd_testing_data PCD_TESTING;
#endif /* PCD_TESTING_H_ */

Просмотреть файл

@ -34,7 +34,7 @@ PFM_V2_FW_TYPE_ID = int ("0x11", 16)
PFM_V2_FW_VERSION_TYPE_ID = int ("0x12", 16)
PCD_V2_ROT_TYPE_ID = int ("0x40", 16)
PCD_V2_I2C_CPLD_TYPE_ID = int ("0x41", 16)
PCD_V2_I2C_POWER_CONTROLLER_TYPE_ID = int ("0x41", 16)
PCD_V2_DIRECT_COMPONENT_TYPE_ID = int ("0x42", 16)
PCD_V2_MCTP_BRIDGE_COMPONENT_TYPE_ID = int ("0x43", 16)
@ -519,14 +519,14 @@ def generate_toc (hash_engine, hash_type, toc_list, hash_list):
hash_len = hash_engine.digest_size
toc_len = ctypes.sizeof (manifest_toc_header) + \
(ctypes.sizeof (manifest_toc_entry) * num_entries) + ((num_entries + 1) * hash_len)
(ctypes.sizeof (manifest_toc_entry) + hash_len) * num_entries
toc = (ctypes.c_ubyte * toc_len) ()
toc_header_len = ctypes.sizeof (manifest_toc_header)
toc_header = manifest_toc_header (num_entries, num_entries, hash_type, 0)
ctypes.memmove (ctypes.addressof (toc), ctypes.addressof (toc_header), toc_header_len)
offset = ctypes.sizeof (manifest_header) + toc_len
offset = ctypes.sizeof (manifest_header) + toc_len + hash_len
hash_id = 0
toc_entry_len = ctypes.sizeof (manifest_toc_entry)
toc_offset = toc_header_len
@ -548,6 +548,11 @@ def generate_toc (hash_engine, hash_type, toc_list, hash_list):
toc_offset += hash_len
table_hash = generate_hash (toc, hash_engine)
ctypes.memmove (ctypes.addressof (toc) + toc_offset, ctypes.addressof (table_hash), hash_len)
return toc
toc_w_hash = (ctypes.c_ubyte * (toc_len + hash_len)) ()
ctypes.memmove (ctypes.addressof (toc_w_hash), ctypes.addressof (toc), toc_len)
ctypes.memmove (ctypes.addressof (toc_w_hash) + toc_offset, ctypes.addressof (table_hash),
hash_len)
return toc_w_hash

Просмотреть файл

@ -44,7 +44,7 @@ XML_ROT_EID_TAG = "RoTEID"
XML_BRIDGE_EID_TAG = "BridgeEID"
XML_BRIDGE_ADDRESS_TAG = "BridgeAddress"
XML_EID_TAG = "EID"
XML_CPLD_TAG = "CPLD"
XML_POWER_CONTROLLER_TAG = "PowerController"
XML_CHANNEL_TAG = "Channel"
XML_COMPONENTS_TAG = "Components"
XML_COMPONENT_TAG = "Component"
@ -508,15 +508,15 @@ def process_pcd (root):
xml["rot"]["interface"].update (result)
cpld = xml_find_single_tag (root, XML_CPLD_TAG, False)
if cpld is not None:
xml["cpld"] = {}
power_controller = xml_find_single_tag (root, XML_POWER_CONTROLLER_TAG, False)
if power_controller is not None:
xml["power_controller"] = {}
interface = xml_find_single_tag (cpld, XML_INTERFACE_TAG)
interface = xml_find_single_tag (power_controller, XML_INTERFACE_TAG)
if interface is None:
return None, None
xml["cpld"]["interface"] = {}
xml["power_controller"]["interface"] = {}
interface_type = xml_extract_attrib (interface, XML_TYPE_ATTRIB, True)
if interface_type is None:
@ -524,9 +524,9 @@ def process_pcd (root):
if interface_type == PCD_INTERFACE_TYPE_I2C:
interface_type = 0
else:
print ("Unknown CPLD interface type: {0}".format (interface_type))
print ("Unknown PowerController interface type: {0}".format (interface_type))
xml["cpld"]["interface"].update ({"type":interface_type})
xml["power_controller"]["interface"].update ({"type":interface_type})
result = xml_extract_single_value (interface, {"bus": XML_BUS_TAG,
"eid": XML_EID_TAG, "address": XML_ADDRESS_TAG, "i2cmode": XML_I2CMODE_TAG})
@ -543,13 +543,13 @@ def process_pcd (root):
elif result["i2cmode"] == PCD_INTERFACE_I2C_MODE_MS:
result["i2cmode"] = 1
else:
print ("Unknown CPLD interface I2C mode: {0}".format (result["i2cmode"]))
print ("Unknown PowerController interface I2C mode: {0}".format (result["i2cmode"]))
xml["cpld"]["interface"].update (result)
xml["power_controller"]["interface"].update (result)
muxes = xml_find_single_tag (interface, XML_MUXES_TAG, False)
if muxes is not None:
xml["cpld"]["interface"]["muxes"] = {}
xml["power_controller"]["interface"]["muxes"] = {}
for mux in muxes.findall (XML_MUX_TAG):
level = xml_extract_attrib (mux, XML_LEVEL_ATTRIB, False)
@ -563,7 +563,7 @@ def process_pcd (root):
result["address"] = int (result["address"], 16)
xml["cpld"]["interface"]["muxes"].update ({level:result})
xml["power_controller"]["interface"]["muxes"].update ({level:result})
components = xml_find_single_tag (root, XML_COMPONENTS_TAG, False)
if components is not None:

Просмотреть файл

@ -1,4 +1,4 @@
<PCD sku="C2030" version="0x1A">
<PCD sku="SKU1" version="0x1A">
<RoT type="PA-RoT">
<Ports>
<Port id="0">
@ -21,7 +21,7 @@
<BridgeAddress>0x10</BridgeAddress>
</Interface>
</RoT>
<CPLD>
<PowerController>
<Interface type="I2C">
<Bus>2</Bus>
<EID>0x14</EID>
@ -38,9 +38,9 @@
</Mux>
</Muxes>
</Interface>
</CPLD>
</PowerController>
<Components>
<Component type="Corsica" connection="Direct">
<Component type="Alpha" connection="Direct">
<Policy>Passive</Policy>
<Interface type="I2C">
<Bus>3</Bus>
@ -59,7 +59,7 @@
<Mask>0xe0</Mask>
</PwrCtrl>
</Component>
<Component type="Overlake" connection="MCTPBridge" count="2">
<Component type="Beta" connection="MCTPBridge" count="2">
<Policy>Passive</Policy>
<DeviceID>0x0a</DeviceID>
<VendorID>0x0b</VendorID>

Просмотреть файл

@ -144,38 +144,42 @@ def generate_muxes_buf (xml_muxes):
return muxes_buf, muxes_len, num_muxes
def generate_cpld (xml_cpld, hash_engine):
def generate_power_controller (xml_power_controller, hash_engine):
"""
Create a CPLD object from parsed XML list
Create a power_controller object from parsed XML list
:param xml_cpld: List of parsed XML of CPLD to be included in CPLD object
: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 CPLD object, CPLD's TOC entry, hash of CPLD object
:return Instance of a power_controller object, power_controller's TOC entry,
hash of power_controller object
"""
if xml_cpld["interface"]["type"] is not 0:
raise ValueError ("Unsupported CPLD interface type: {0}".format (
xml_cpld["interface"]["type"]))
if xml_power_controller["interface"]["type"] is not 0:
raise ValueError ("Unsupported power_controller interface type: {0}".format (
xml_power_controller["interface"]["type"]))
if "muxes" in xml_cpld["interface"]:
muxes, muxes_len, num_muxes = generate_muxes_buf (xml_cpld["interface"]["muxes"])
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_cpld["interface"], "bus", "CPLD interface"))
address = int (manifest_common.get_key_from_dict (xml_cpld["interface"], "address",
"CPLD interface"))
eid = int (manifest_common.get_key_from_dict (xml_cpld["interface"], "eid",
"CPLD interface"))
i2cmode = int (manifest_common.get_key_from_dict (xml_cpld["interface"], "i2cmode",
"CPLD interface"))
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"))
i2cmode = int (manifest_common.get_key_from_dict (xml_power_controller["interface"], "i2cmode",
"Power controller interface"))
i2c_flags = i2cmode
class pcd_cpld_element (ctypes.LittleEndianStructure):
class pcd_power_controller_element (ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [('mux_count', ctypes.c_ubyte, 4),
('i2c_flags', ctypes.c_ubyte, 4),
@ -184,14 +188,15 @@ def generate_cpld (xml_cpld, hash_engine):
('eid', ctypes.c_ubyte),
('muxes', ctypes.c_ubyte * muxes_len)]
cpld = pcd_cpld_element (num_muxes, i2c_flags, bus, address, eid, muxes)
cpld_len = ctypes.sizeof (cpld)
cpld_toc_entry = manifest_common.manifest_toc_entry (manifest_common.PCD_V2_I2C_CPLD_TYPE_ID,
manifest_common.V2_BASE_TYPE_ID, 1, 0, 0, cpld_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)
cpld_hash = manifest_common.generate_hash (cpld, hash_engine)
power_controller_hash = manifest_common.generate_hash (power_controller, hash_engine)
return cpld, cpld_toc_entry, cpld_hash
return power_controller, power_controller_toc_entry, power_controller_hash
def generate_direct_component_buf (xml_component):
"""
@ -414,13 +419,14 @@ elements_list.append (platform_id)
toc_list.append (platform_id_toc_entry)
hash_list.append (platform_id_hash)
if "cpld" in processed_xml:
cpld, cpld_toc_entry, cpld_hash = generate_cpld (processed_xml["cpld"], hash_engine)
if "power_controller" in processed_xml:
power_controller, power_controller_toc_entry, power_controller_hash = \
generate_power_controller (processed_xml["power_controller"], hash_engine)
pcd_len += ctypes.sizeof (cpld)
elements_list.append (cpld)
toc_list.append (cpld_toc_entry)
hash_list.append (cpld_hash)
pcd_len += ctypes.sizeof (power_controller)
elements_list.append (power_controller)
toc_list.append (power_controller_toc_entry)
hash_list.append (power_controller_hash)
if "components" in processed_xml:
components, num_components, components_toc_list, components_hash_list = generate_components (

Просмотреть файл

@ -487,25 +487,26 @@ int32_t visualize_pcd_rot_element (uint8_t *start, const char* prefix)
return (pointer - start);
}
int32_t visualize_pcd_cpld_element (uint8_t *start, const char* prefix)
int32_t visualize_pcd_power_controller_element (uint8_t *start, const char* prefix)
{
uint8_t *pointer = start;
struct pcd_cpld_element *cpld = (struct pcd_cpld_element*) pointer;
struct pcd_power_controller_element *power_controller =
(struct pcd_power_controller_element*) pointer;
pointer += sizeof (struct pcd_cpld_element);
pointer += sizeof (struct pcd_power_controller_element);
printf ("%spcd_cpld_element\n", prefix);
printf ("%spcd_power_controller_element\n", prefix);
printf ("%s{\n", prefix);
printf ("%s\tmux_count: %i\n", prefix, cpld->interface.mux_count);
printf ("%s\ti2c_flags: 0x%x\n", prefix, cpld->interface.i2c_flags);
printf ("%s\tbus: %i\n", prefix, cpld->interface.bus);
printf ("%s\taddress: 0x%x\n", prefix, cpld->interface.address);
printf ("%s\teid: 0x%x\n", prefix, cpld->interface.eid);
printf ("%s\tmux_count: %i\n", prefix, power_controller->i2c.mux_count);
printf ("%s\ti2c_flags: 0x%x\n", prefix, power_controller->i2c.i2c_flags);
printf ("%s\tbus: %i\n", prefix, power_controller->i2c.bus);
printf ("%s\taddress: 0x%x\n", prefix, power_controller->i2c.address);
printf ("%s\teid: 0x%x\n", prefix, power_controller->i2c.eid);
printf ("%s\tMuxes\n", prefix);
printf ("%s\t[\n", prefix);
for (int i = 0; i < cpld->interface.mux_count; ++i) {
for (int i = 0; i < power_controller->i2c.mux_count; ++i) {
struct pcd_mux *mux = (struct pcd_mux*) pointer;
pointer += sizeof (struct pcd_mux);
@ -698,8 +699,8 @@ int32_t visualize_pcd (uint8_t *start)
case PCD_ROT:
offset = visualize_pcd_rot_element (pointer, "");
break;
case PCD_CPLD:
offset = visualize_pcd_cpld_element (pointer, "");
case PCD_POWER_CONTROLLER:
offset = visualize_pcd_power_controller_element (pointer, "");
break;
case PCD_COMPONENT_DIRECT:
offset = visualize_pcd_direct_i2c_component_element (pointer, "");