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 BootMonFsIsImageValid (
93 IN HW_IMAGE_DESCRIPTION
*Desc
,
98 HW_IMAGE_FOOTER
*Footer
;
101 Footer
= &Desc
->Footer
;
103 // Check that the verification bytes are present
104 if ((Footer
->FooterSignature1
!= HW_IMAGE_FOOTER_SIGNATURE_1
) ||
105 (Footer
->FooterSignature2
!= HW_IMAGE_FOOTER_SIGNATURE_2
)) {
109 if (Footer
->Version
== HW_IMAGE_FOOTER_VERSION
) {
110 if (Footer
->Offset
!= HW_IMAGE_FOOTER_OFFSET
) {
113 } else if (Footer
->Version
== HW_IMAGE_FOOTER_VERSION2
) {
114 if (Footer
->Offset
!= HW_IMAGE_FOOTER_OFFSET2
) {
121 Checksum
= Desc
->FooterChecksum
;
122 Status
= BootMonFsComputeFooterChecksum (Desc
);
123 if (EFI_ERROR (Status
)) {
124 DEBUG ((DEBUG_ERROR
, "Warning: failed to compute checksum for image '%a'\n", Desc
->Footer
.Filename
));
127 if (Desc
->FooterChecksum
!= Checksum
) {
128 DEBUG ((DEBUG_ERROR
, "Warning: image '%a' checksum mismatch.\n", Desc
->Footer
.Filename
));
131 if ((Desc
->BlockEnd
!= Lba
) || (Desc
->BlockStart
> Desc
->BlockEnd
)) {
140 BootMonFsDiscoverNextImage (
141 IN BOOTMON_FS_INSTANCE
*Instance
,
142 IN OUT EFI_LBA
*LbaStart
,
143 IN OUT BOOTMON_FS_FILE
*File
146 EFI_DISK_IO_PROTOCOL
*DiskIo
;
151 DiskIo
= Instance
->DiskIo
;
153 CurrentLba
= *LbaStart
;
155 // Look for images in the rest of this block
156 while (CurrentLba
<= Instance
->Media
->LastBlock
) {
157 // Work out the byte offset into media of the image description in this block
158 // If present, the image description is at the very end of the block.
159 DescOffset
= ((CurrentLba
+ 1) * Instance
->Media
->BlockSize
) - sizeof (HW_IMAGE_DESCRIPTION
);
161 // Read the image description from media
162 Status
= DiskIo
->ReadDisk (DiskIo
,
163 Instance
->Media
->MediaId
,
165 sizeof (HW_IMAGE_DESCRIPTION
),
168 if (EFI_ERROR (Status
)) {
172 // If we found a valid image description...
173 if (BootMonFsIsImageValid (&File
->HwDescription
, (CurrentLba
- Instance
->Media
->LowestAlignedLba
))) {
174 DEBUG ((EFI_D_ERROR
, "Found image: %a in block %d.\n",
175 &(File
->HwDescription
.Footer
.Filename
),
176 (UINTN
)(CurrentLba
- Instance
->Media
->LowestAlignedLba
)
178 File
->HwDescAddress
= DescOffset
;
180 *LbaStart
= CurrentLba
+ 1;
187 *LbaStart
= CurrentLba
;
188 return EFI_NOT_FOUND
;
192 BootMonFsInitialize (
193 IN BOOTMON_FS_INSTANCE
*Instance
199 BOOTMON_FS_FILE
*NewFile
;
205 Status
= BootMonFsCreateFile (Instance
, &NewFile
);
206 if (EFI_ERROR (Status
)) {
210 Status
= BootMonFsDiscoverNextImage (Instance
, &Lba
, NewFile
);
211 if (EFI_ERROR (Status
)) {
212 // Free NewFile allocated by BootMonFsCreateFile ()
216 InsertTailList (&Instance
->RootFile
->Link
, &NewFile
->Link
);
220 Instance
->Initialized
= TRUE
;