/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (c) 2025, Kory Maincent */ #ifndef _FWUMDATA_H_ #define _FWUMDATA_H_ #include /* Type definitions for U-Boot compatibility */ typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; /* FWU Constants */ #define FWU_IMAGE_ACCEPTED 0x1 #define FWU_BANK_INVALID (uint8_t)0xFF #define FWU_BANK_VALID (uint8_t)0xFE #define FWU_BANK_ACCEPTED (uint8_t)0xFC #define MAX_BANKS_V2 4 /* EFI GUID structure */ struct efi_guid { u32 time_high; u16 time_low; u16 reserved; u8 family; u8 node[7]; } __packed; /* FWU Metadata structures */ struct fwu_image_bank_info { struct efi_guid image_guid; u32 accepted; u32 reserved; } __packed; struct fwu_image_entry { struct efi_guid image_type_guid; struct efi_guid location_guid; struct fwu_image_bank_info img_bank_info[0]; /* Variable length */ } __packed; struct fwu_fw_store_desc { u8 num_banks; u8 reserved; u16 num_images; u16 img_entry_size; u16 bank_info_entry_size; struct fwu_image_entry img_entry[0]; /* Variable length */ } __packed; struct fwu_mdata { u32 crc32; u32 version; u32 active_index; u32 previous_active_index; /* Followed by image entries or fwu_mdata_ext */ } __packed; struct fwu_mdata_ext { /* V2 only */ u32 metadata_size; u16 desc_offset; u16 reserved1; u8 bank_state[4]; u32 reserved2; } __packed; /* Metadata access helpers */ struct fwu_image_entry *fwu_get_image_entry(struct fwu_mdata *mdata, int version, int num_banks, int img_id) { size_t offset; if (version == 1) { offset = sizeof(struct fwu_mdata) + (sizeof(struct fwu_image_entry) + sizeof(struct fwu_image_bank_info) * num_banks) * img_id; } else { /* V2: skip fwu_fw_store_desc header */ offset = sizeof(struct fwu_mdata) + sizeof(struct fwu_mdata_ext) + sizeof(struct fwu_fw_store_desc) + (sizeof(struct fwu_image_entry) + sizeof(struct fwu_image_bank_info) * num_banks) * img_id; } return (struct fwu_image_entry *)((char *)mdata + offset); } struct fwu_image_bank_info *fwu_get_bank_info(struct fwu_mdata *mdata, int version, int num_banks, int img_id, int bank_id) { size_t offset; if (version == 1) { offset = sizeof(struct fwu_mdata) + (sizeof(struct fwu_image_entry) + sizeof(struct fwu_image_bank_info) * num_banks) * img_id + sizeof(struct fwu_image_entry) + sizeof(struct fwu_image_bank_info) * bank_id; } else { offset = sizeof(struct fwu_mdata) + sizeof(struct fwu_mdata_ext) + sizeof(struct fwu_fw_store_desc) + (sizeof(struct fwu_image_entry) + sizeof(struct fwu_image_bank_info) * num_banks) * img_id + sizeof(struct fwu_image_entry) + sizeof(struct fwu_image_bank_info) * bank_id; } return (struct fwu_image_bank_info *)((char *)mdata + offset); } struct fwu_fw_store_desc *fwu_get_fw_desc(struct fwu_mdata *mdata) { size_t offset; offset = sizeof(struct fwu_mdata) + sizeof(struct fwu_mdata_ext); return (struct fwu_fw_store_desc *)((char *)mdata + offset); } struct fwu_mdata_ext *fwu_get_fw_mdata_ext(struct fwu_mdata *mdata) { size_t offset; offset = sizeof(struct fwu_mdata); return (struct fwu_mdata_ext *)((char *)mdata + offset); } #endif /* _FWUMDATA_H_ */