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