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