• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
FspNotificationHandler(IN UINT32 NotificationCode)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
FspInitDone(VOID)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
FspWaitForNotify(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 
198