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