3 * Copyright (c) 2012-2014, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/IoLib.h>
16 #include <Library/NorFlashPlatformLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
20 #include <Protocol/SimpleFileSystem.h>
22 #include "BootMonFsInternal.h"
34 ASSERT (Size
% 4 == 0);
43 if (Word
> ~Checksum
) {
54 BootMonFsComputeFooterChecksum (
55 IN OUT HW_IMAGE_DESCRIPTION
*Footer
58 HW_IMAGE_DESCRIPTION
*Description
;
61 Footer
->Attributes
= 1;
63 Description
= AllocateZeroPool (sizeof (HW_IMAGE_DESCRIPTION
));
64 if (Description
== NULL
) {
65 DEBUG ((DEBUG_ERROR
, "BootMonFsComputeFooterChecksum: Unable to allocate memory.\n"));
66 return EFI_OUT_OF_RESOURCES
;
69 // Copy over to temporary shim
70 CopyMem (Description
, Footer
, sizeof (HW_IMAGE_DESCRIPTION
));
72 // BootMon doesn't checksum the previous checksum
73 Description
->FooterChecksum
= 0;
75 // Blank out regions which aren't being used.
76 for (Index
= Footer
->RegionCount
; Index
< HW_IMAGE_DESCRIPTION_REGION_MAX
; Index
++) {
77 Description
->Region
[Index
].Checksum
= 0;
78 Description
->Region
[Index
].LoadAddress
= 0;
79 Description
->Region
[Index
].Offset
= 0;
80 Description
->Region
[Index
].Size
= 0;
83 // Compute the checksum
84 Footer
->FooterChecksum
= BootMonFsChecksum (Description
, sizeof (HW_IMAGE_DESCRIPTION
));
86 FreePool (Description
);
92 BootMonFsImageInThisBlock (
96 OUT HW_IMAGE_DESCRIPTION
*Image
100 HW_IMAGE_FOOTER
*Ptr
;
101 HW_IMAGE_DESCRIPTION
*Footer
;
104 // The footer is stored as the last thing in the block
105 Ptr
= (HW_IMAGE_FOOTER
*)((UINT8
*)Buf
+ Size
- sizeof (HW_IMAGE_FOOTER
));
107 // Check that the verification bytes are present
108 if ((Ptr
->FooterSignature1
!= HW_IMAGE_FOOTER_SIGNATURE_1
) || (Ptr
->FooterSignature2
!= HW_IMAGE_FOOTER_SIGNATURE_2
)) {
112 if (Ptr
->Version
!= HW_IMAGE_FOOTER_VERSION
) {
116 if (Ptr
->Offset
!= HW_IMAGE_FOOTER_OFFSET
) {
120 Footer
= (HW_IMAGE_DESCRIPTION
*)(((UINT8
*)Buf
+ Size
- sizeof (HW_IMAGE_DESCRIPTION
)));
121 Checksum
= Footer
->FooterChecksum
;
122 Status
= BootMonFsComputeFooterChecksum (Footer
);
123 if (EFI_ERROR (Status
)) {
124 DEBUG ((DEBUG_ERROR
, "Warning: failed to compute checksum for image '%a'\n", Footer
->Footer
.Filename
));
127 if (Footer
->FooterChecksum
!= Checksum
) {
128 DEBUG ((DEBUG_ERROR
, "Warning: image '%a' checksum mismatch.\n", Footer
->Footer
.Filename
));
131 if ((Footer
->BlockEnd
!= Block
) || (Footer
->BlockStart
> Footer
->BlockEnd
)) {
135 // Copy the image out
136 CopyMem (Image
, Footer
, sizeof (HW_IMAGE_DESCRIPTION
));
142 BootMonFsDiscoverNextImage (
143 IN BOOTMON_FS_INSTANCE
*Instance
,
144 IN EFI_LBA
*LbaStart
,
145 OUT HW_IMAGE_DESCRIPTION
*Image
148 EFI_BLOCK_IO_PROTOCOL
*Blocks
;
152 Blocks
= Instance
->BlockIo
;
154 // Allocate an output buffer
155 Out
= AllocatePool (Instance
->Media
->BlockSize
);
157 return EFI_OUT_OF_RESOURCES
;
160 Blocks
->Reset (Blocks
, FALSE
);
161 CurrentLba
= *LbaStart
;
163 // Look for images in the rest of this block
164 while (CurrentLba
<= Instance
->Media
->LastBlock
) {
165 // Read in the next block
166 Blocks
->ReadBlocks (Blocks
, Instance
->Media
->MediaId
, CurrentLba
, Instance
->Media
->BlockSize
, Out
);
167 // Check for an image in the current block
168 if (BootMonFsImageInThisBlock (Out
, Instance
->Media
->BlockSize
, (CurrentLba
- Instance
->Media
->LowestAlignedLba
), Image
)) {
169 DEBUG ((EFI_D_ERROR
, "Found image: %a in block %d.\n", &(Image
->Footer
.Filename
), (UINTN
)(CurrentLba
- Instance
->Media
->LowestAlignedLba
)));
171 *LbaStart
= Image
->BlockEnd
+ 1;
178 *LbaStart
= CurrentLba
;
180 return EFI_NOT_FOUND
;
184 BootMonFsInitialize (
185 IN BOOTMON_FS_INSTANCE
*Instance
191 BOOTMON_FS_FILE
*NewFile
;
197 Status
= BootMonFsCreateFile (Instance
, &NewFile
);
198 if (EFI_ERROR (Status
)) {
202 Status
= BootMonFsDiscoverNextImage (Instance
, &Lba
, &(NewFile
->HwDescription
));
203 if (EFI_ERROR (Status
)) {
204 // Free NewFile allocated by BootMonFsCreateFile ()
208 InsertTailList (&Instance
->RootFile
->Link
, &NewFile
->Link
);
212 Instance
->Initialized
= TRUE
;