]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/DxeCapsuleLib/DxeCapsuleLib.c
IntelFrameworkModulePkg: Add DxeCapsuleLib
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / DxeCapsuleLib / DxeCapsuleLib.c
CommitLineData
cf7958f7 1/** @file\r
2 Capsule Library instance to update capsule image to flash.\r
3\r
4 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15#include <PiDxe.h>\r
16#include <Guid/Capsule.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/DxeServicesTableLib.h>\r
20#include <Library/MemoryAllocationLib.h>\r
21#include <Library/CapsuleLib.h>\r
22\r
23/**\r
24 Those capsules supported by the firmwares.\r
25\r
26 @param CapsuleHeader Points to a capsule header.\r
27\r
28 @retval EFI_SUCESS Input capsule is supported by firmware.\r
29 @retval EFI_UNSUPPORTED Input capsule is not supported by the firmware.\r
30**/\r
31EFI_STATUS\r
32EFIAPI\r
33SupportCapsuleImage (\r
34 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
35 )\r
36{\r
37 if (CompareGuid (&gEfiCapsuleGuid, &CapsuleHeader->CapsuleGuid)) {\r
38 return EFI_SUCCESS;\r
39 }\r
40\r
41 return EFI_UNSUPPORTED;\r
42}\r
43\r
44/**\r
45 The firmware implements to process the capsule image.\r
46\r
47 @param CapsuleHeader Points to a capsule header.\r
48\r
49 @retval EFI_SUCESS Process Capsule Image successfully.\r
50 @retval EFI_UNSUPPORTED Capsule image is not supported by the firmware.\r
51 @retval EFI_VOLUME_CORRUPTED FV volume in the capsule is corrupted.\r
52 @retval EFI_OUT_OF_RESOURCES Not enough memory.\r
53**/\r
54EFI_STATUS\r
55EFIAPI\r
56ProcessCapsuleImage (\r
57 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
58 )\r
59{\r
60 UINT32 Length;\r
61 EFI_FIRMWARE_VOLUME_HEADER *FvImage;\r
62 EFI_FIRMWARE_VOLUME_HEADER *ProcessedFvImage;\r
63 EFI_STATUS Status;\r
64 EFI_HANDLE FvProtocolHandle;\r
65 UINT32 FvAlignment;\r
66\r
67 FvImage = NULL;\r
68 ProcessedFvImage = NULL;\r
69 Status = EFI_SUCCESS;\r
70\r
71 if (SupportCapsuleImage (CapsuleHeader) != EFI_SUCCESS) {\r
72 return EFI_UNSUPPORTED;\r
73 }\r
74\r
75 //\r
76 // Skip the capsule header, move to the Firware Volume\r
77 //\r
78 FvImage = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) CapsuleHeader + CapsuleHeader->HeaderSize);\r
79 Length = CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;\r
80\r
81 while (Length != 0) {\r
82 //\r
83 // Point to the next firmware volume header, and then\r
84 // call the DXE service to process it.\r
85 //\r
86 if (FvImage->FvLength > (UINTN) Length) {\r
87 //\r
88 // Notes: need to stuff this status somewhere so that the\r
89 // error can be detected at OS runtime\r
90 //\r
91 Status = EFI_VOLUME_CORRUPTED;\r
92 break;\r
93 }\r
94\r
95 FvAlignment = 1 << ((FvImage->Attributes & EFI_FVB2_ALIGNMENT) >> 16);\r
96 //\r
97 // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
98 //\r
99 if (FvAlignment < 8) {\r
100 FvAlignment = 8;\r
101 }\r
102 //\r
103 // Check FvImage Align is required.\r
104 //\r
105 if (((UINTN) FvImage % FvAlignment) == 0) {\r
106 ProcessedFvImage = FvImage;\r
107 } else {\r
108 //\r
109 // Allocate new aligned buffer to store FvImage.\r
110 //\r
111 ProcessedFvImage = (EFI_FIRMWARE_VOLUME_HEADER *) AllocateAlignedPages ((UINTN) EFI_SIZE_TO_PAGES (FvImage->FvLength), (UINTN) FvAlignment);\r
112 if (ProcessedFvImage == NULL) {\r
113 Status = EFI_OUT_OF_RESOURCES;\r
114 break;\r
115 }\r
116 CopyMem (ProcessedFvImage, FvImage, (UINTN) FvImage->FvLength);\r
117 }\r
118\r
119 Status = gDS->ProcessFirmwareVolume (\r
120 (VOID *) ProcessedFvImage,\r
121 (UINTN) ProcessedFvImage->FvLength,\r
122 &FvProtocolHandle\r
123 );\r
124 if (EFI_ERROR (Status)) {\r
125 break;\r
126 }\r
127 //\r
128 // Call the dispatcher to dispatch any drivers from the produced firmware volume\r
129 //\r
130 gDS->Dispatch ();\r
131 //\r
132 // On to the next FV in the capsule\r
133 //\r
134 Length -= (UINT32) FvImage->FvLength;\r
135 FvImage = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINT8 *) FvImage + FvImage->FvLength);\r
136 }\r
137\r
138 return Status;\r
139}\r
140\r
141\r