Add dual FSP binaries support.
[mirror_edk2.git] / IntelFspWrapperPkg / FspNotifyDxe / FspNotifyDxe.c
1 /** @file\r
2   This driver will register two callbacks to call fsp's notifies.\r
3 \r
4   Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
5   This program and the accompanying materials\r
6   are licensed and made available under the terms and conditions of the BSD License\r
7   which accompanies this distribution.  The full text of the license may be found at\r
8   http://opensource.org/licenses/bsd-license.php.\r
9 \r
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 \r
13 **/\r
14 \r
15 #include <PiDxe.h>\r
16 \r
17 #include <Protocol/PciEnumerationComplete.h>\r
18 \r
19 #include <Library/UefiDriverEntryPoint.h>\r
20 #include <Library/UefiBootServicesTableLib.h>\r
21 #include <Library/DebugLib.h>\r
22 #include <Library/BaseMemoryLib.h>\r
23 #include <Library/UefiLib.h>\r
24 #include <Library/FspApiLib.h>\r
25 \r
26 FSP_INFO_HEADER *mFspHeader = NULL;\r
27 \r
28 /**\r
29   PciEnumerationComplete Protocol notification event handler.\r
30 \r
31   @param[in] Event    Event whose notification function is being invoked.\r
32   @param[in] Context  Pointer to the notification function's context.\r
33 **/\r
34 VOID\r
35 EFIAPI\r
36 OnPciEnumerationComplete (\r
37   IN EFI_EVENT  Event,\r
38   IN VOID       *Context\r
39   )\r
40 {\r
41   NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
42   EFI_STATUS          Status;\r
43   VOID                *Interface;\r
44 \r
45   //\r
46   // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration.\r
47   // Just return if it is not found.\r
48   //\r
49   Status = gBS->LocateProtocol (\r
50                   &gEfiPciEnumerationCompleteProtocolGuid,\r
51                   NULL,\r
52                   &Interface\r
53                   );\r
54   if (EFI_ERROR (Status)) {\r
55     return ;\r
56   }\r
57 \r
58   NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;\r
59   Status = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams);\r
60   if (Status != EFI_SUCCESS) {\r
61     DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status));\r
62   } else {\r
63     DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n"));\r
64   }\r
65 }\r
66 \r
67 /**\r
68   Notification function of EVT_GROUP_READY_TO_BOOT event group.\r
69 \r
70   This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.\r
71   When the Boot Manager is about to load and execute a boot option, it reclaims variable\r
72   storage if free size is below the threshold.\r
73 \r
74   @param[in] Event        Event whose notification function is being invoked.\r
75   @param[in] Context      Pointer to the notification function's context.\r
76 \r
77 **/\r
78 VOID\r
79 EFIAPI\r
80 OnReadyToBoot (\r
81   IN EFI_EVENT  Event,\r
82   IN VOID       *Context\r
83   )\r
84 {\r
85   NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
86   EFI_STATUS          Status;\r
87 \r
88   gBS->CloseEvent (Event);\r
89 \r
90   NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;\r
91   Status = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams);\r
92   if (Status != EFI_SUCCESS) {\r
93     DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status));\r
94   } else {\r
95     DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n"));\r
96   }\r
97 }\r
98 \r
99 /**\r
100   Main entry for the FSP DXE module.\r
101 \r
102   This routine registers two callbacks to call fsp's notifies.\r
103 \r
104   @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
105   @param[in] SystemTable    A pointer to the EFI System Table.\r
106 \r
107   @retval EFI_SUCCESS       The entry point is executed successfully.\r
108   @retval other             Some error occurs when executing this entry point.\r
109 \r
110 **/\r
111 EFI_STATUS\r
112 EFIAPI\r
113 FspDxeEntryPoint (\r
114   IN EFI_HANDLE         ImageHandle,\r
115   IN EFI_SYSTEM_TABLE   *SystemTable\r
116   )\r
117 {\r
118   EFI_STATUS Status;\r
119   EFI_EVENT  ReadyToBootEvent;\r
120   VOID       *Registration;\r
121   EFI_EVENT  ProtocolNotifyEvent;\r
122 \r
123   if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) {\r
124     mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase));\r
125   } else {\r
126     mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvSecondFspBase));\r
127   }\r
128   DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", mFspHeader));\r
129   if (mFspHeader == NULL) {\r
130     return EFI_DEVICE_ERROR;\r
131   }\r
132 \r
133   ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (\r
134                           &gEfiPciEnumerationCompleteProtocolGuid,\r
135                           TPL_CALLBACK,\r
136                           OnPciEnumerationComplete,\r
137                           NULL,\r
138                           &Registration\r
139                           );\r
140   ASSERT (ProtocolNotifyEvent != NULL);\r
141 \r
142   Status = EfiCreateEventReadyToBootEx (\r
143              TPL_CALLBACK,\r
144              OnReadyToBoot,\r
145              NULL,\r
146              &ReadyToBootEvent\r
147              );\r
148   ASSERT_EFI_ERROR (Status);\r
149 \r
150   return EFI_SUCCESS;\r
151 }\r
152 \r