Fix typo.
[mirror_edk2.git] / IntelFspPkg / Library / BaseFspPlatformLib / FspPlatformNotify.c
1 /** @file
2
3 Copyright (c) 2014, 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 FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter ();
104
105 //
106 // Modify the parameters for ContinuationFunc
107 //
108 SetFspContinuationFuncParameter(EFI_SUCCESS, 0);
109 SetFspContinuationFuncParameter((UINT32)GetHobList(), 1);
110
111 //
112 // Modify the return address to ContinuationFunc
113 //
114 SetFspApiReturnAddress((UINT32)FspInitParams->ContinuationFunc);
115
116 //
117 // Give control back to the boot loader framework caller after FspInit is done
118 // It is done throught the continuation function
119 //
120 SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_EXIT);
121 Pei2LoaderSwitchStack();
122 }
123
124 /**
125 This function handle NotifyPhase API call from the bootloader.
126 It gives control back to the bootloader after it is handled. If the
127 Notification code is a ReadyToBoot event, this function will return
128 and FSP continues the remaining execution until it reaches the DxeIpl.
129
130 **/
131 VOID
132 FspWaitForNotify (
133 VOID
134 )
135 {
136 EFI_STATUS Status;
137 UINT32 NotificationValue;
138 UINT32 NotificationCount;
139 UINT8 Count;
140
141 NotificationCount = 0;
142 while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {
143
144 Count = (UINT8)((NotificationCount << 1) & 0x07);
145 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_ENTRY + Count);
146
147 NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
148 DEBUG ((DEBUG_INFO, "FSP Got Notification. Notification Value : 0x%08X\n", NotificationValue));
149
150 if (mFspNotifySequence[NotificationCount] != NotificationValue) {
151 //
152 // Notify code does not follow the predefined order
153 //
154 SetFspApiReturnStatus(EFI_UNSUPPORTED);
155 } else {
156 //
157 // Process Notification and Give control back to the boot loader framework caller
158 //
159 Status = FspNotificationHandler (NotificationValue);
160 SetFspApiReturnStatus(Status);
161 if (!EFI_ERROR(Status)) {
162 NotificationCount++;
163 SetFspApiReturnStatus(EFI_SUCCESS);
164 if (NotificationValue == EnumInitPhaseReadyToBoot) {
165 break;
166 }
167 }
168 }
169 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POSTPCI_EXIT + Count);
170 Pei2LoaderSwitchStack();
171 }
172
173 //
174 // Control goes back to the PEI Core and it dispatches further PEIMs.
175 // DXEIPL is the final one to transfer control back to the boot loader.
176 //
177 }
178