diff options
Diffstat (limited to 'src/soc/amd/common/pi/image.c')
-rw-r--r-- | src/soc/amd/common/pi/image.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/soc/amd/common/pi/image.c b/src/soc/amd/common/pi/image.c new file mode 100644 index 000000000000..03a2a473a0bd --- /dev/null +++ b/src/soc/amd/common/pi/image.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <agesa_headers.h> +#include <amdblocks/image.h> +#include <types.h> + +/* Check if the image has the desired module. */ +static bool validate_image(void *module_chain, const char module_signature[8]) +{ + AMD_MODULE_HEADER *mod_ptr = (AMD_MODULE_HEADER *)module_chain; + uint64_t signature = *(uint64_t *)module_signature; + char *checking_str; + + while ((mod_ptr != NULL) && + (MODULE_SIGNATURE == *(uint32_t *)&mod_ptr->ModuleHeaderSignature)) { + checking_str = (char *)&mod_ptr->ModuleIdentifier; + if (signature == *(uint64_t *)checking_str) + return true; + mod_ptr = (AMD_MODULE_HEADER *)mod_ptr->NextBlock; + } + return false; +} + +/* + * Find an image that has the desired module. The image is aligned within + * a given range. + */ +void *amd_find_image(const void *start_address, const void *end_address, + uint32_t alignment, const char name[8]) +{ + uint8_t *current_ptr = (uint8_t *)start_address; + uint8_t *start = (uint8_t *)start_address; + uint8_t *end = (uint8_t *)end_address; + AMD_IMAGE_HEADER *image_ptr; + + while ((current_ptr >= start) && (current_ptr < end)) { + if (IMAGE_SIGNATURE == *((uint32_t *)current_ptr)) { + image_ptr = (AMD_IMAGE_HEADER *) current_ptr; + + /* Check if the image has the desired module */ + if (validate_image((void *)image_ptr->ModuleInfoOffset, + name)) + return current_ptr; + } + current_ptr += alignment; + } + return NULL; +} |