| 36 | } |
| 37 | |
| 38 | bool fv_init(struct mem_range_t fv) |
| 39 | { |
| 40 | if (fv.length % SMM_BLOCK_SIZE != 0) { |
| 41 | fprintf(stderr, |
| 42 | "Firmware Volume size is not a multiple of the block size (%dKiB)\n", |
| 43 | SMM_BLOCK_SIZE / 1024); |
| 44 | return false; |
| 45 | } |
| 46 | |
| 47 | uint32_t number_of_blocks = fv.length / SMM_BLOCK_SIZE; |
| 48 | memset(fv.start, 0xff, fv.length); |
| 49 | |
| 50 | const EFI_FIRMWARE_VOLUME_HEADER vol_hdr = { |
| 51 | .FileSystemGuid = EfiSystemNvDataFvGuid, |
| 52 | .FvLength = fv.length, |
| 53 | .Signature = EFI_FVH_SIGNATURE, |
| 54 | .Attributes = EFI_FVB2_READ_ENABLED_CAP |
| 55 | | EFI_FVB2_READ_STATUS |
| 56 | | EFI_FVB2_WRITE_ENABLED_CAP |
| 57 | | EFI_FVB2_WRITE_STATUS |
| 58 | | EFI_FVB2_STICKY_WRITE |
| 59 | | EFI_FVB2_MEMORY_MAPPED |
| 60 | | EFI_FVB2_ERASE_POLARITY, |
| 61 | .HeaderLength = sizeof(vol_hdr) |
| 62 | + sizeof(EFI_FV_BLOCK_MAP_ENTRY), |
| 63 | .Revision = EFI_FVH_REVISION, |
| 64 | .BlockMap[0] = { |
| 65 | .NumBlocks = number_of_blocks, |
| 66 | .Length = SMM_BLOCK_SIZE, |
| 67 | }, |
| 68 | }; |
| 69 | |
| 70 | EFI_FIRMWARE_VOLUME_HEADER *vol_hdr_dst = (void *)fv.start; |
| 71 | *vol_hdr_dst = vol_hdr; |
| 72 | vol_hdr_dst->BlockMap[1].NumBlocks = 0; |
| 73 | vol_hdr_dst->BlockMap[1].Length = 0; |
| 74 | |
| 75 | vol_hdr_dst->Checksum = |
| 76 | ~calc_checksum((const void *)vol_hdr_dst, vol_hdr.HeaderLength); |
| 77 | ++vol_hdr_dst->Checksum; |
| 78 | |
| 79 | const VARIABLE_STORE_HEADER var_store_hdr = { |
| 80 | .Signature = EfiAuthenticatedVariableGuid, |
| 81 | // Actual size of the storage is `n / 2 - 1` blocks, the rest is |
| 82 | // Fault Tolerant Write (FTW) space and the FTW spare space. |
| 83 | .Size = ((number_of_blocks / 2 - 1) * SMM_BLOCK_SIZE) - vol_hdr.HeaderLength, |
| 84 | .Format = VARIABLE_STORE_FORMATTED, |
| 85 | .State = VARIABLE_STORE_HEALTHY, |
| 86 | }; |
| 87 | |
| 88 | VARIABLE_STORE_HEADER *var_store_hdr_dst = |
| 89 | (void *)(fv.start + vol_hdr.HeaderLength); |
| 90 | *var_store_hdr_dst = var_store_hdr; |
| 91 | |
| 92 | return true; |
| 93 | } |
| 94 | |
| 95 | static bool guid_eq(const EFI_GUID *lhs, const EFI_GUID *rhs) |
no test coverage detected