Update IntelFspPkg to support FSP1.1
[mirror_edk2.git] / IntelFspPkg / Library / BaseFspPlatformLib / FspPlatformNotify.c
1 /** @file
2
3 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 **/
13
14 #include <PiPei.h>
15 #include <Library/PeiServicesLib.h>
16 #include <Library/PeiServicesTablePointerLib.h>
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/PcdLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/HobLib.h>
22 #include <Library/FspSwitchStackLib.h>
23 #include <Library/FspCommonLib.h>
24 #include <Guid/EventGroup.h>
25 #include <FspApi.h>
26 #include <Protocol/PciEnumerationComplete.h>
27
28 EFI_PEI_PPI_DESCRIPTOR mPeiPostPciEnumerationPpi = {
29 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
30 &gEfiPciEnumerationCompleteProtocolGuid,
31 NULL
32 };
33
34 EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi = {
35 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
36 &gEfiEventReadyToBootGuid,
37 NULL
38 };
39
40
41 UINT32 mFspNotifySequence[] = {
42 EnumInitPhaseAfterPciEnumeration,
43 EnumInitPhaseReadyToBoot
44 };
45
46 /**
47 Install FSP notification.
48
49 @param[in] NotificationCode FSP notification code
50
51 @retval EFI_SUCCESS Notify FSP successfully
52 @retval EFI_INVALID_PARAMETER NotificationCode is invalid
53
54 **/
55 EFI_STATUS
56 EFIAPI
57 FspNotificationHandler (
58 IN UINT32 NotificationCode
59 )
60 {
61 EFI_STATUS Status;
62
63 Status = EFI_SUCCESS;
64
65 switch (NotificationCode) {
66 case EnumInitPhaseAfterPciEnumeration:
67 //
68 // Do POST PCI initialization if needed
69 //
70 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));
71 PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);
72 break;
73
74 case EnumInitPhaseReadyToBoot:
75 //
76 // Ready To Boot
77 //
78 DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));
79 PeiServicesInstallPpi (&mPeiReadyToBootPpi);
80 break;
81
82 default:
83 Status = EFI_INVALID_PARAMETER;
84 break;
85 }
86
87 return Status;
88 }
89
90 /**
91 This function transfer control to the ContinuationFunc passed in by the
92 BootLoader.
93
94 **/
95 VOID
96 EFIAPI
97 FspInitDone (
98 VOID
99 )
100 {
101 FSP_INIT_PARAMS *FspInitParams;
102
103 if (GetFspApiCallingMode() == 0) {
104 //
105 // FspInit API is used, so jump into the ContinuationFunc
106 //
107 FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
108
109 //
110 // Modify the parameters for ContinuationFunc
111 //
112 SetFspContinuationFuncParameter(EFI_SUCCESS, 0);
113 SetFspContinuationFuncParameter((UINT32)GetHobList(), 1);
114
115 //
116 // Modify the return address to ContinuationFunc
117 //
118 SetFspApiReturnAddress((UINT32)FspInitParams->ContinuationFunc);
119
120 //
121 // Give control back to the boot loader framework caller after FspInit is done
122 // It is done throught the continuation function
123 //
124 SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_EXIT);
125 } else {
126 //
127 // FspMemoryInit API is used, so return directly
128 //
129
130 //
131 // This is the end of the FspSiliconInit API
132 // Give control back to the boot loader
133 //
134 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n"));
135 SetFspApiReturnStatus (EFI_SUCCESS);
136 }
137
138 Pei2LoaderSwitchStack();
139 }
140
141 /**
142 This function handle NotifyPhase API call from the BootLoader.
143 It gives control back to the BootLoader after it is handled. If the
144 Notification code is a ReadyToBoot event, this function will return
145 and FSP continues the remaining execution until it reaches the DxeIpl.
146
147 **/
148 VOID
149 FspWaitForNotify (
150 VOID
151 )
152 {
153 EFI_STATUS Status;
154 UINT32 NotificationValue;
155 UINT32 NotificationCount;
156 UINT8 Count;
157
158 NotificationCount = 0;
159 while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {
160
161 Count = (UINT8)((NotificationCount << 1) & 0x07);
162 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + Count);
163
164 NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
165 DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificationValue));
166
167 if (mFspNotifySequence[NotificationCount] != NotificationValue) {
168 //
169 // Notify code does not follow the predefined order
170 //
171 DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
172 SetFspApiReturnStatus(EFI_UNSUPPORTED);
173 } else {
174 //
175 // Process Notification and Give control back to the boot loader framework caller
176 //
177 Status = FspNotificationHandler (NotificationValue);
178 DEBUG ((DEBUG_INFO, "FSP Notification Handler Returns : 0x%08X\n", Status));
179 SetFspApiReturnStatus(Status);
180 if (!EFI_ERROR(Status)) {
181 NotificationCount++;
182 SetFspApiReturnStatus(EFI_SUCCESS);
183 if (NotificationValue == EnumInitPhaseReadyToBoot) {
184 break;
185 }
186 }
187 }
188 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT + Count);
189 Pei2LoaderSwitchStack();
190 }
191
192 //
193 // Control goes back to the PEI Core and it dispatches further PEIMs.
194 // DXEIPL is the final one to transfer control back to the boot loader.
195 //
196 }
197