]> git.proxmox.com Git - mirror_edk2.git/blame - StandaloneMmPkg/Core/FwVol.c
StandaloneMmPkg: Fix ECC error 9001 in StandaloneMmCpu
[mirror_edk2.git] / StandaloneMmPkg / Core / FwVol.c
CommitLineData
6b46d772
SV
1/**@file\r
2\r
3Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
92df3ca8 4Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>\r
86094561 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6b46d772
SV
6\r
7**/\r
8\r
9#include "StandaloneMmCore.h"\r
10#include <Library/FvLib.h>\r
d65e0e48 11#include <Library/ExtractGuidedSectionLib.h>\r
6b46d772
SV
12\r
13//\r
14// List of file types supported by dispatcher\r
15//\r
16EFI_FV_FILETYPE mMmFileTypes[] = {\r
17 EFI_FV_FILETYPE_MM,\r
18 0xE, //EFI_FV_FILETYPE_MM_STANDALONE,\r
19 //\r
20 // Note: DXE core will process the FV image file, so skip it in MM core\r
21 // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE\r
22 //\r
23};\r
24\r
25EFI_STATUS\r
26MmAddToDriverList (\r
7f72ec0b
LE
27 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,\r
28 IN VOID *Pe32Data,\r
29 IN UINTN Pe32DataSize,\r
30 IN VOID *Depex,\r
31 IN UINTN DepexSize,\r
32 IN EFI_GUID *DriverName\r
6b46d772
SV
33 );\r
34\r
35BOOLEAN\r
36FvHasBeenProcessed (\r
7f72ec0b 37 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader\r
6b46d772
SV
38 );\r
39\r
40VOID\r
81e9eca7 41FvIsBeingProcessed (\r
7f72ec0b 42 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader\r
6b46d772
SV
43 );\r
44\r
92df3ca8 45/**\r
6b46d772 46 Given the pointer to the Firmware Volume Header find the\r
2a0755a9 47 MM driver and return its PE32 image.\r
6b46d772 48\r
92df3ca8 49 @param [in] FwVolHeader Pointer to memory mapped FV\r
6b46d772 50\r
92df3ca8
SM
51 @retval EFI_SUCCESS Success.\r
52 @retval EFI_INVALID_PARAMETER Invalid parameter.\r
53 @retval EFI_NOT_FOUND Could not find section data.\r
54 @retval EFI_OUT_OF_RESOURCES Out of resources.\r
55 @retval EFI_VOLUME_CORRUPTED Firmware volume is corrupted.\r
56 @retval EFI_UNSUPPORTED Operation not supported.\r
6b46d772 57\r
92df3ca8
SM
58**/\r
59EFI_STATUS\r
60MmCoreFfsFindMmDriver (\r
61 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader\r
62 )\r
6b46d772 63{\r
d65e0e48
AB
64 EFI_STATUS Status;\r
65 EFI_STATUS DepexStatus;\r
66 EFI_FFS_FILE_HEADER *FileHeader;\r
67 EFI_FV_FILETYPE FileType;\r
68 VOID *Pe32Data;\r
69 UINTN Pe32DataSize;\r
70 VOID *Depex;\r
71 UINTN DepexSize;\r
72 UINTN Index;\r
73 EFI_COMMON_SECTION_HEADER *Section;\r
74 VOID *SectionData;\r
75 UINTN SectionDataSize;\r
76 UINT32 DstBufferSize;\r
77 VOID *ScratchBuffer;\r
78 UINT32 ScratchBufferSize;\r
79 VOID *DstBuffer;\r
80 UINT16 SectionAttribute;\r
81 UINT32 AuthenticationStatus;\r
82 EFI_FIRMWARE_VOLUME_HEADER *InnerFvHeader;\r
6b46d772
SV
83\r
84 DEBUG ((DEBUG_INFO, "MmCoreFfsFindMmDriver - 0x%x\n", FwVolHeader));\r
85\r
86 if (FvHasBeenProcessed (FwVolHeader)) {\r
87 return EFI_SUCCESS;\r
88 }\r
89\r
81e9eca7 90 FvIsBeingProcessed (FwVolHeader);\r
6b46d772 91\r
d65e0e48
AB
92 //\r
93 // First check for encapsulated compressed firmware volumes\r
94 //\r
95 FileHeader = NULL;\r
96 do {\r
97 Status = FfsFindNextFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
98 FwVolHeader, &FileHeader);\r
99 if (EFI_ERROR (Status)) {\r
100 break;\r
101 }\r
102 Status = FfsFindSectionData (EFI_SECTION_GUID_DEFINED, FileHeader,\r
103 &SectionData, &SectionDataSize);\r
104 if (EFI_ERROR (Status)) {\r
105 break;\r
106 }\r
107 Section = (EFI_COMMON_SECTION_HEADER *)(FileHeader + 1);\r
108 Status = ExtractGuidedSectionGetInfo (Section, &DstBufferSize,\r
109 &ScratchBufferSize, &SectionAttribute);\r
110 if (EFI_ERROR (Status)) {\r
111 break;\r
112 }\r
113\r
114 //\r
115 // Allocate scratch buffer\r
116 //\r
117 ScratchBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
118 if (ScratchBuffer == NULL) {\r
119 return EFI_OUT_OF_RESOURCES;\r
120 }\r
121\r
122 //\r
123 // Allocate destination buffer, extra one page for adjustment\r
124 //\r
125 DstBuffer = (VOID *)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
126 if (DstBuffer == NULL) {\r
127 return EFI_OUT_OF_RESOURCES;\r
128 }\r
129\r
130 //\r
131 // Call decompress function\r
132 //\r
133 Status = ExtractGuidedSectionDecode (Section, &DstBuffer, ScratchBuffer,\r
134 &AuthenticationStatus);\r
135 FreePages (ScratchBuffer, EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
136 if (EFI_ERROR (Status)) {\r
137 goto FreeDstBuffer;\r
138 }\r
139\r
140 DEBUG ((DEBUG_INFO,\r
141 "Processing compressed firmware volume (AuthenticationStatus == %x)\n",\r
142 AuthenticationStatus));\r
143\r
144 Status = FindFfsSectionInSections (DstBuffer, DstBufferSize,\r
145 EFI_SECTION_FIRMWARE_VOLUME_IMAGE, &Section);\r
146 if (EFI_ERROR (Status)) {\r
147 goto FreeDstBuffer;\r
148 }\r
149\r
150 InnerFvHeader = (VOID *)(Section + 1);\r
151 Status = MmCoreFfsFindMmDriver (InnerFvHeader);\r
152 if (EFI_ERROR (Status)) {\r
153 goto FreeDstBuffer;\r
154 }\r
155 } while (TRUE);\r
156\r
6b46d772
SV
157 for (Index = 0; Index < sizeof (mMmFileTypes) / sizeof (mMmFileTypes[0]); Index++) {\r
158 DEBUG ((DEBUG_INFO, "Check MmFileTypes - 0x%x\n", mMmFileTypes[Index]));\r
159 FileType = mMmFileTypes[Index];\r
160 FileHeader = NULL;\r
161 do {\r
162 Status = FfsFindNextFile (FileType, FwVolHeader, &FileHeader);\r
163 if (!EFI_ERROR (Status)) {\r
164 Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, &Pe32Data, &Pe32DataSize);\r
165 DEBUG ((DEBUG_INFO, "Find PE data - 0x%x\n", Pe32Data));\r
166 DepexStatus = FfsFindSectionData (EFI_SECTION_MM_DEPEX, FileHeader, &Depex, &DepexSize);\r
167 if (!EFI_ERROR (DepexStatus)) {\r
168 MmAddToDriverList (FwVolHeader, Pe32Data, Pe32DataSize, Depex, DepexSize, &FileHeader->Name);\r
169 }\r
170 }\r
171 } while (!EFI_ERROR (Status));\r
172 }\r
173\r
d65e0e48
AB
174 return EFI_SUCCESS;\r
175\r
176FreeDstBuffer:\r
177 FreePages (DstBuffer, EFI_SIZE_TO_PAGES (DstBufferSize));\r
178\r
6b46d772
SV
179 return Status;\r
180}\r