1 /** @file
2   In FSP API V1 mode, it will be invoked twice by pei core. In 1st entry, it will
3   call FspInit API. In 2nd entry, it will parse the hoblist from fsp and report
4   them into pei core.
5 
6   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 
12 #include "FspInitPei.h"
13 
14 /**
15   FSP Init continuation function.
16   Control will be returned to this callback function after FspInit API call.
17 
18   @param[in] Status      Status of the FSP INIT API
19   @param[in] HobListPtr  Pointer to the HOB data structure defined in the PI specification.
20 
21 **/
22 VOID
ContinuationFunc(IN EFI_STATUS Status,IN VOID * HobListPtr)23 ContinuationFunc (
24   IN EFI_STATUS Status,
25   IN VOID       *HobListPtr
26   )
27 {
28   EFI_BOOT_MODE             BootMode;
29   UINT64                    StackSize;
30   EFI_PHYSICAL_ADDRESS      StackBase;
31 
32   DEBUG ((DEBUG_INFO, "ContinuationFunc - %r\n", Status));
33   DEBUG ((DEBUG_INFO, "HobListPtr - 0x%x\n", HobListPtr));
34 
35   if (Status != EFI_SUCCESS) {
36     CpuDeadLoop ();
37   }
38 
39   //
40   // Can not call any PeiServices
41   //
42   BootMode = GetBootMode ();
43 
44   GetStackInfo (BootMode, TRUE, &StackSize, &StackBase);
45   DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase));
46   DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize));
47   CallPeiCoreEntryPoint (
48     HobListPtr,
49     (VOID *)(UINTN)StackBase,
50     (VOID *)(UINTN)(StackBase + StackSize)
51     );
52 }
53 
54 /**
55   Call FspInit API.
56 
57   @param[in] FspHeader FSP header pointer.
58 **/
59 VOID
PeiFspInit(IN FSP_INFO_HEADER * FspHeader)60 PeiFspInit (
61   IN FSP_INFO_HEADER *FspHeader
62   )
63 {
64   FSP_INIT_PARAMS           FspInitParams;
65   FSP_INIT_RT_COMMON_BUFFER FspRtBuffer;
66   UINT8                     FspUpdRgn[FixedPcdGet32 (PcdMaxUpdRegionSize)];
67   UINT32                    UpdRegionSize;
68   EFI_BOOT_MODE             BootMode;
69   UINT64                    StackSize;
70   EFI_PHYSICAL_ADDRESS      StackBase;
71   EFI_STATUS                Status;
72 
73   DEBUG ((DEBUG_INFO, "PeiFspInit enter\n"));
74 
75   PeiServicesGetBootMode (&BootMode);
76   DEBUG ((DEBUG_INFO, "BootMode - 0x%x\n", BootMode));
77 
78   GetStackInfo (BootMode, FALSE, &StackSize, &StackBase);
79   DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase));
80   DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize));
81 
82   ZeroMem (&FspRtBuffer, sizeof(FspRtBuffer));
83   FspRtBuffer.StackTop = (UINT32 *)(UINTN)(StackBase + StackSize);
84 
85   FspRtBuffer.BootMode = BootMode;
86 
87   /* Platform override any UPD configs */
88   UpdRegionSize = GetUpdRegionSize();
89   DEBUG ((DEBUG_INFO, "UpdRegionSize - 0x%x\n", UpdRegionSize));
90   DEBUG ((DEBUG_INFO, "sizeof(FspUpdRgn) - 0x%x\n", sizeof(FspUpdRgn)));
91   ASSERT(sizeof(FspUpdRgn) >= UpdRegionSize);
92   ZeroMem (FspUpdRgn, UpdRegionSize);
93   FspRtBuffer.UpdDataRgnPtr = UpdateFspUpdConfigs (FspUpdRgn);
94   FspRtBuffer.BootLoaderTolumSize = 0;
95 
96   ZeroMem (&FspInitParams, sizeof(FspInitParams));
97   FspInitParams.NvsBufferPtr = GetNvsBuffer ();
98   DEBUG ((DEBUG_INFO, "NvsBufferPtr - 0x%x\n", FspInitParams.NvsBufferPtr));
99   FspInitParams.RtBufferPtr  = (VOID *)&FspRtBuffer;
100   FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ContinuationFunc;
101 
102   SaveSecContext (GetPeiServicesTablePointer ());
103 
104   DEBUG ((DEBUG_INFO, "FspInitParams      - 0x%x\n", &FspInitParams));
105   DEBUG ((DEBUG_INFO, "  NvsBufferPtr     - 0x%x\n", FspInitParams.NvsBufferPtr));
106   DEBUG ((DEBUG_INFO, "  RtBufferPtr      - 0x%x\n", FspInitParams.RtBufferPtr));
107   DEBUG ((DEBUG_INFO, "    StackTop       - 0x%x\n", FspRtBuffer.StackTop));
108   DEBUG ((DEBUG_INFO, "    BootMode       - 0x%x\n", FspRtBuffer.BootMode));
109   DEBUG ((DEBUG_INFO, "    UpdDataRgnPtr  - 0x%x\n", FspRtBuffer.UpdDataRgnPtr));
110   DEBUG ((DEBUG_INFO, "  ContinuationFunc - 0x%x\n", FspInitParams.ContinuationFunc));
111 
112   Status = CallFspInit (FspHeader, &FspInitParams);
113   //
114   // Should never return
115   //
116   DEBUG((DEBUG_ERROR, "FSP Init failed, status: 0x%x\n", Status));
117   CpuDeadLoop ();
118 }
119 
120 /**
121   Do FSP initialization based on FspApi version 1.
122 
123   @param[in] FspHeader FSP header pointer.
124 
125   @return FSP initialization status.
126 **/
127 EFI_STATUS
PeiFspInitV1(IN FSP_INFO_HEADER * FspHeader)128 PeiFspInitV1 (
129   IN FSP_INFO_HEADER *FspHeader
130   )
131 {
132   EFI_STATUS           Status;
133   FSP_INIT_DONE_PPI    *FspInitDone;
134   VOID                 *FspHobList;
135   EFI_BOOT_MODE        BootMode;
136 
137   Status = PeiServicesLocatePpi (
138              &gFspInitDonePpiGuid,
139              0,
140              NULL,
141              (VOID **) &FspInitDone
142              );
143   if (EFI_ERROR (Status)) {
144     //
145     // 1st entry
146     //
147     DEBUG ((DEBUG_INFO, "1st entry\n"));
148 
149     PeiFspInit (FspHeader);
150     //
151     // Never return here, for FspApi version 1.
152     //
153     CpuDeadLoop ();
154   } else {
155     //
156     // 2nd entry for FspApi version 1 only.
157     //
158     DEBUG ((DEBUG_INFO, "2nd entry\n"));
159 
160     Status = FspInitDone->GetFspHobList (GetPeiServicesTablePointer (), FspInitDone, &FspHobList);
161     ASSERT_EFI_ERROR (Status);
162     DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
163     FspHobProcess (FspHobList);
164 
165     //
166     // Register EndOfPei Notify for S3 to run FspNotifyPhase
167     //
168     PeiServicesGetBootMode (&BootMode);
169     if (BootMode == BOOT_ON_S3_RESUME) {
170       Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
171       ASSERT_EFI_ERROR (Status);
172     }
173   }
174 
175   return EFI_SUCCESS;
176 }