3 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
5 All rights reserved. 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.
18 // Hack to work in NT32
28 IN EFI_PHYSICAL_ADDRESS
*ImageAddress
,
32 IN EFI_PHYSICAL_ADDRESS
*EntryPoint
41 OUT EFI_PHYSICAL_ADDRESS
*ImageAddress
,
42 OUT UINT64
*ImageSize
,
43 OUT EFI_PHYSICAL_ADDRESS
*EntryPoint
47 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
50 ZeroMem (&ImageContext
, sizeof (ImageContext
));
52 ImageContext
.Handle
= PeCoffImage
;
53 ImageContext
.ImageRead
= PeCoffLoaderImageReadFromMemory
;
55 Status
= PeCoffLoaderGetImageInfo (&ImageContext
);
56 ASSERT_EFI_ERROR (Status
);
60 // Allocate Memory for the image
62 Buffer
= AllocatePages (EFI_SIZE_TO_PAGES((UINT32
)ImageContext
.ImageSize
));
66 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
69 // Load the image to our new buffer
71 Status
= PeCoffLoaderLoadImage (&ImageContext
);
72 ASSERT_EFI_ERROR (Status
);
75 // Relocate the image in our new buffer
77 Status
= PeCoffLoaderRelocateImage (&ImageContext
);
78 ASSERT_EFI_ERROR (Status
);
81 *ImageAddress
= ImageContext
.ImageAddress
;
82 *ImageSize
= ImageContext
.ImageSize
;
83 *EntryPoint
= ImageContext
.EntryPoint
;
86 // Flush not needed for all architectures. We could have a processor specific
87 // function in this library that does the no-op if needed.
89 InvalidateInstructionCacheRange ((VOID
*)(UINTN
)*ImageAddress
, (UINTN
)*ImageSize
);
98 (EFIAPI
*DXE_CORE_ENTRY_POINT
) (
104 LoadDxeCoreFromFfsFile (
105 IN EFI_PEI_FILE_HANDLE FileHandle
,
111 EFI_PHYSICAL_ADDRESS ImageAddress
;
113 EFI_PHYSICAL_ADDRESS EntryPoint
;
117 EFI_FV_FILE_INFO FvFileInfo
;
121 PERF_START (NULL
, "SEC", NULL
, 1);
123 Status
= FfsFindSectionData (EFI_SECTION_PE32
, FileHandle
, &PeCoffImage
);
124 if (EFI_ERROR (Status
)) {
129 Status
= LoadPeCoffImage (PeCoffImage
, &ImageAddress
, &ImageSize
, &EntryPoint
);
130 // For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
131 ASSERT_EFI_ERROR (Status
);
134 // Extract the DxeCore GUID file name.
136 Status
= FfsGetFileInfo (FileHandle
, &FvFileInfo
);
137 ASSERT_EFI_ERROR (Status
);
139 BuildModuleHob (&FvFileInfo
.FileName
, (EFI_PHYSICAL_ADDRESS
)(UINTN
)ImageAddress
, EFI_SIZE_TO_PAGES ((UINT32
) ImageSize
) * EFI_PAGE_SIZE
, EntryPoint
);
141 DEBUG ((EFI_D_INFO
| EFI_D_LOAD
, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID
*)(UINTN
)ImageAddress
, (VOID
*)(UINTN
)EntryPoint
));
144 if (StackSize
== 0) {
145 // User the current stack
148 if (PerformanceMeasurementEnabled ()) {
149 Tick
= GetPerformanceCounter ();
151 PERF_END (NULL
, "SEC", NULL
, Tick
);
153 ((DXE_CORE_ENTRY_POINT
)(UINTN
)EntryPoint
) (Hob
);
157 // Allocate 128KB for the Stack
159 BaseOfStack
= AllocatePages (EFI_SIZE_TO_PAGES (StackSize
));
160 ASSERT (BaseOfStack
!= NULL
);
163 // Compute the top of the stack we were allocated. Pre-allocate a UINTN
166 TopOfStack
= (VOID
*) ((UINTN
) BaseOfStack
+ EFI_SIZE_TO_PAGES (StackSize
) * EFI_PAGE_SIZE
- CPU_STACK_ALIGNMENT
);
167 TopOfStack
= ALIGN_POINTER (TopOfStack
, CPU_STACK_ALIGNMENT
);
170 // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
172 UpdateStackHob ((EFI_PHYSICAL_ADDRESS
)(UINTN
) BaseOfStack
, StackSize
);
175 if (PerformanceMeasurementEnabled ()) {
176 Tick
= GetPerformanceCounter ();
178 PERF_END (NULL
, "SEC", NULL
, Tick
);
181 (SWITCH_STACK_ENTRY_POINT
)(UINTN
)EntryPoint
,
189 // Should never get here as DXE Core does not return
190 DEBUG ((EFI_D_ERROR
, "DxeCore returned\n"));
193 return EFI_DEVICE_ERROR
;
201 IN UINTN
*FvInstance
, OPTIONAL
206 EFI_PEI_FV_HANDLE VolumeHandle
;
207 EFI_PEI_FILE_HANDLE FileHandle
= NULL
;
209 if (FvInstance
!= NULL
) {
211 // Caller passed in a specific FV to try, so only try that one
213 Status
= FfsFindNextVolume (*FvInstance
, &VolumeHandle
);
214 if (!EFI_ERROR (Status
)) {
215 Status
= FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE
, VolumeHandle
, &FileHandle
);
218 Status
= FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE
, &VolumeHandle
, &FileHandle
);
221 if (!EFI_ERROR (Status
)) {
222 return LoadDxeCoreFromFfsFile (FileHandle
, StackSize
);
236 EFI_PEI_FV_HANDLE VolumeHandle
;
237 EFI_PEI_FILE_HANDLE FileHandle
;
239 Status
= FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
, &VolumeHandle
, &FileHandle
);
240 if (!EFI_ERROR (Status
)) {
241 Status
= FfsProcessFvFile (FileHandle
);