1 /** @file
2 This driver will register two callbacks to call fsp's notifies.
3
4 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiDxe.h>
10
11 #include <Protocol/PciEnumerationComplete.h>
12
13 #include <Library/UefiDriverEntryPoint.h>
14 #include <Library/UefiBootServicesTableLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/UefiLib.h>
18 #include <Library/FspApiLib.h>
19
20 /**
21 Relocate this image under 4G memory.
22
23 @param ImageHandle Handle of driver image.
24 @param SystemTable Pointer to system table.
25
26 @retval EFI_SUCCESS Image successfully relocated.
27 @retval EFI_ABORTED Failed to relocate image.
28
29 **/
30 EFI_STATUS
31 RelocateImageUnder4GIfNeeded (
32 IN EFI_HANDLE ImageHandle,
33 IN EFI_SYSTEM_TABLE *SystemTable
34 );
35
36 FSP_INFO_HEADER *mFspHeader = NULL;
37
38 /**
39 PciEnumerationComplete Protocol notification event handler.
40
41 @param[in] Event Event whose notification function is being invoked.
42 @param[in] Context Pointer to the notification function's context.
43 **/
44 VOID
45 EFIAPI
OnPciEnumerationComplete(IN EFI_EVENT Event,IN VOID * Context)46 OnPciEnumerationComplete (
47 IN EFI_EVENT Event,
48 IN VOID *Context
49 )
50 {
51 NOTIFY_PHASE_PARAMS NotifyPhaseParams;
52 EFI_STATUS Status;
53 VOID *Interface;
54
55 //
56 // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration.
57 // Just return if it is not found.
58 //
59 Status = gBS->LocateProtocol (
60 &gEfiPciEnumerationCompleteProtocolGuid,
61 NULL,
62 &Interface
63 );
64 if (EFI_ERROR (Status)) {
65 return ;
66 }
67
68 NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;
69 Status = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams);
70 if (Status != EFI_SUCCESS) {
71 DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status));
72 } else {
73 DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n"));
74 }
75 }
76
77 /**
78 Notification function of EVT_GROUP_READY_TO_BOOT event group.
79
80 This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.
81 When the Boot Manager is about to load and execute a boot option, it reclaims variable
82 storage if free size is below the threshold.
83
84 @param[in] Event Event whose notification function is being invoked.
85 @param[in] Context Pointer to the notification function's context.
86
87 **/
88 VOID
89 EFIAPI
OnReadyToBoot(IN EFI_EVENT Event,IN VOID * Context)90 OnReadyToBoot (
91 IN EFI_EVENT Event,
92 IN VOID *Context
93 )
94 {
95 NOTIFY_PHASE_PARAMS NotifyPhaseParams;
96 EFI_STATUS Status;
97
98 gBS->CloseEvent (Event);
99
100 NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;
101 Status = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams);
102 if (Status != EFI_SUCCESS) {
103 DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status));
104 } else {
105 DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n"));
106 }
107 }
108
109 /**
110 Main entry for the FSP DXE module.
111
112 This routine registers two callbacks to call fsp's notifies.
113
114 @param[in] ImageHandle The firmware allocated handle for the EFI image.
115 @param[in] SystemTable A pointer to the EFI System Table.
116
117 @retval EFI_SUCCESS The entry point is executed successfully.
118 @retval other Some error occurs when executing this entry point.
119
120 **/
121 EFI_STATUS
122 EFIAPI
FspDxeEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)123 FspDxeEntryPoint (
124 IN EFI_HANDLE ImageHandle,
125 IN EFI_SYSTEM_TABLE *SystemTable
126 )
127 {
128 EFI_STATUS Status;
129 EFI_EVENT ReadyToBootEvent;
130 VOID *Registration;
131 EFI_EVENT ProtocolNotifyEvent;
132
133 //
134 // Load this driver's image to memory
135 //
136 Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);
137 if (EFI_ERROR (Status)) {
138 return EFI_SUCCESS;
139 }
140
141 if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) {
142 mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase));
143 } else {
144 mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvSecondFspBase));
145 }
146 DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", mFspHeader));
147 if (mFspHeader == NULL) {
148 return EFI_DEVICE_ERROR;
149 }
150
151 ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (
152 &gEfiPciEnumerationCompleteProtocolGuid,
153 TPL_CALLBACK,
154 OnPciEnumerationComplete,
155 NULL,
156 &Registration
157 );
158 ASSERT (ProtocolNotifyEvent != NULL);
159
160 Status = EfiCreateEventReadyToBootEx (
161 TPL_CALLBACK,
162 OnReadyToBoot,
163 NULL,
164 &ReadyToBootEvent
165 );
166 ASSERT_EFI_ERROR (Status);
167
168 return EFI_SUCCESS;
169 }
170
171