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  This program and the accompanying materials
8  are licensed and made available under the terms and conditions of the BSD License
9  which accompanies this distribution.  The full text of the license may be found at
10  http://opensource.org/licenses/bsd-license.php.
11
12  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15**/
16
17
18#include "FspInitPei.h"
19
20/**
21  FSP Init continuation function.
22  Control will be returned to this callback function after FspInit API call.
23
24  @param[in] Status      Status of the FSP INIT API
25  @param[in] HobListPtr  Pointer to the HOB data structure defined in the PI specification.
26
27**/
28VOID
29ContinuationFunc (
30  IN EFI_STATUS Status,
31  IN VOID       *HobListPtr
32  )
33{
34  EFI_BOOT_MODE             BootMode;
35  UINT64                    StackSize;
36  EFI_PHYSICAL_ADDRESS      StackBase;
37
38  DEBUG ((DEBUG_INFO, "ContinuationFunc - %r\n", Status));
39  DEBUG ((DEBUG_INFO, "HobListPtr - 0x%x\n", HobListPtr));
40
41  if (Status != EFI_SUCCESS) {
42    CpuDeadLoop ();
43  }
44
45  //
46  // Can not call any PeiServices
47  //
48  BootMode = GetBootMode ();
49
50  GetStackInfo (BootMode, TRUE, &StackSize, &StackBase);
51  DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase));
52  DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize));
53  CallPeiCoreEntryPoint (
54    HobListPtr,
55    (VOID *)(UINTN)StackBase,
56    (VOID *)(UINTN)(StackBase + StackSize)
57    );
58}
59
60/**
61  Call FspInit API.
62
63  @param[in] FspHeader FSP header pointer.
64**/
65VOID
66PeiFspInit (
67  IN FSP_INFO_HEADER *FspHeader
68  )
69{
70  FSP_INIT_PARAMS           FspInitParams;
71  FSP_INIT_RT_COMMON_BUFFER FspRtBuffer;
72  UINT8                     FspUpdRgn[FixedPcdGet32 (PcdMaxUpdRegionSize)];
73  UINT32                    UpdRegionSize;
74  EFI_BOOT_MODE             BootMode;
75  UINT64                    StackSize;
76  EFI_PHYSICAL_ADDRESS      StackBase;
77  EFI_STATUS                Status;
78
79  DEBUG ((DEBUG_INFO, "PeiFspInit enter\n"));
80
81  PeiServicesGetBootMode (&BootMode);
82  DEBUG ((DEBUG_INFO, "BootMode - 0x%x\n", BootMode));
83
84  GetStackInfo (BootMode, FALSE, &StackSize, &StackBase);
85  DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase));
86  DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize));
87
88  ZeroMem (&FspRtBuffer, sizeof(FspRtBuffer));
89  FspRtBuffer.StackTop = (UINT32 *)(UINTN)(StackBase + StackSize);
90
91  FspRtBuffer.BootMode = BootMode;
92
93  /* Platform override any UPD configs */
94  UpdRegionSize = GetUpdRegionSize();
95  DEBUG ((DEBUG_INFO, "UpdRegionSize - 0x%x\n", UpdRegionSize));
96  DEBUG ((DEBUG_INFO, "sizeof(FspUpdRgn) - 0x%x\n", sizeof(FspUpdRgn)));
97  ASSERT(sizeof(FspUpdRgn) >= UpdRegionSize);
98  ZeroMem (FspUpdRgn, UpdRegionSize);
99  FspRtBuffer.UpdDataRgnPtr = UpdateFspUpdConfigs (FspUpdRgn);
100  FspRtBuffer.BootLoaderTolumSize = 0;
101
102  ZeroMem (&FspInitParams, sizeof(FspInitParams));
103  FspInitParams.NvsBufferPtr = GetNvsBuffer ();
104  DEBUG ((DEBUG_INFO, "NvsBufferPtr - 0x%x\n", FspInitParams.NvsBufferPtr));
105  FspInitParams.RtBufferPtr  = (VOID *)&FspRtBuffer;
106  FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ContinuationFunc;
107
108  SaveSecContext (GetPeiServicesTablePointer ());
109
110  DEBUG ((DEBUG_INFO, "FspInitParams      - 0x%x\n", &FspInitParams));
111  DEBUG ((DEBUG_INFO, "  NvsBufferPtr     - 0x%x\n", FspInitParams.NvsBufferPtr));
112  DEBUG ((DEBUG_INFO, "  RtBufferPtr      - 0x%x\n", FspInitParams.RtBufferPtr));
113  DEBUG ((DEBUG_INFO, "    StackTop       - 0x%x\n", FspRtBuffer.StackTop));
114  DEBUG ((DEBUG_INFO, "    BootMode       - 0x%x\n", FspRtBuffer.BootMode));
115  DEBUG ((DEBUG_INFO, "    UpdDataRgnPtr  - 0x%x\n", FspRtBuffer.UpdDataRgnPtr));
116  DEBUG ((DEBUG_INFO, "  ContinuationFunc - 0x%x\n", FspInitParams.ContinuationFunc));
117
118  Status = CallFspInit (FspHeader, &FspInitParams);
119  //
120  // Should never return
121  //
122  DEBUG((DEBUG_ERROR, "FSP Init failed, status: 0x%x\n", Status));
123  CpuDeadLoop ();
124}
125
126/**
127  Do FSP initialization based on FspApi version 1.
128
129  @param[in] FspHeader FSP header pointer.
130
131  @return FSP initialization status.
132**/
133EFI_STATUS
134PeiFspInitV1 (
135  IN FSP_INFO_HEADER *FspHeader
136  )
137{
138  EFI_STATUS           Status;
139  FSP_INIT_DONE_PPI    *FspInitDone;
140  VOID                 *FspHobList;
141  EFI_BOOT_MODE        BootMode;
142
143  Status = PeiServicesLocatePpi (
144             &gFspInitDonePpiGuid,
145             0,
146             NULL,
147             (VOID **) &FspInitDone
148             );
149  if (EFI_ERROR (Status)) {
150    //
151    // 1st entry
152    //
153    DEBUG ((DEBUG_INFO, "1st entry\n"));
154
155    PeiFspInit (FspHeader);
156    //
157    // Never return here, for FspApi version 1.
158    //
159    CpuDeadLoop ();
160  } else {
161    //
162    // 2nd entry for FspApi version 1 only.
163    //
164    DEBUG ((DEBUG_INFO, "2nd entry\n"));
165
166    Status = FspInitDone->GetFspHobList (GetPeiServicesTablePointer (), FspInitDone, &FspHobList);
167    ASSERT_EFI_ERROR (Status);
168    DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
169    FspHobProcess (FspHobList);
170
171    //
172    // Register EndOfPei Notify for S3 to run FspNotifyPhase
173    //
174    PeiServicesGetBootMode (&BootMode);
175    if (BootMode == BOOT_ON_S3_RESUME) {
176      Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
177      ASSERT_EFI_ERROR (Status);
178    }
179  }
180
181  return EFI_SUCCESS;
182}