summaryrefslogtreecommitdiff
path: root/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c
blob: 88f5540fefa901868e9324914b5cb34438fa01ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/** @file
  Source file for FSP notify phase PEI module

  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "FspNotifyPhasePeim.h"

/**

   This function waits for FSP notify.

   @param This          Entry point for DXE IPL PPI.
   @param PeiServices   General purpose services available to every PEIM.
   @param HobList       Address to the Pei HOB list.

   @return EFI_SUCCESS              This function never returns.

**/
EFI_STATUS
EFIAPI
WaitForNotify (
  IN CONST EFI_DXE_IPL_PPI  *This,
  IN EFI_PEI_SERVICES       **PeiServices,
  IN EFI_PEI_HOB_POINTERS   HobList
  );

CONST EFI_DXE_IPL_PPI  mDxeIplPpi = {
  WaitForNotify
};

CONST EFI_PEI_PPI_DESCRIPTOR  mInstallDxeIplPpi = {
  EFI_PEI_PPI_DESCRIPTOR_PPI,
  &gEfiDxeIplPpiGuid,
  (VOID *)&mDxeIplPpi
};

CONST EFI_PEI_PPI_DESCRIPTOR  gEndOfPeiSignalPpi = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEfiEndOfPeiSignalPpiGuid,
  NULL
};

CONST EFI_PEI_PPI_DESCRIPTOR  gFspReadyForNotifyPhasePpi = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gFspReadyForNotifyPhasePpiGuid,
  NULL
};

/**

   This function waits for FSP notify.

   @param This          Entry point for DXE IPL PPI.
   @param PeiServices   General purpose services available to every PEIM.
   @param HobList       Address to the Pei HOB list.

   @return EFI_SUCCESS              This function never returns.

**/
EFI_STATUS
EFIAPI
WaitForNotify (
  IN CONST EFI_DXE_IPL_PPI  *This,
  IN EFI_PEI_SERVICES       **PeiServices,
  IN EFI_PEI_HOB_POINTERS   HobList
  )
{
  EFI_STATUS  Status;

  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));

  //
  // End of PEI phase signal
  //
  Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
  ASSERT_EFI_ERROR (Status);

  //
  // Give control back to BootLoader after FspSiliconInit
  //
  DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));
  FspSiliconInitDone2 (EFI_SUCCESS);

  //
  // BootLoader called FSP again through NotifyPhase
  //
  FspWaitForNotify ();

  if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
    //
    // Should not come here
    //
    while (TRUE) {
      DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n"));
      SetFspApiReturnStatus (EFI_UNSUPPORTED);
      Pei2LoaderSwitchStack ();
    }
  }

  return EFI_SUCCESS;
}

/**
  FSP notify phase PEI module entry point

  @param[in]  FileHandle           Not used.
  @param[in]  PeiServices          General purpose services available to every PEIM.

  @retval     EFI_SUCCESS          The function completes successfully
  @retval     EFI_OUT_OF_RESOURCES Insufficient resources to create database
**/
EFI_STATUS
FspNotifyPhasePeimEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS              Status;
  VOID                    *OldDxeIplPpi;
  EFI_PEI_PPI_DESCRIPTOR  *OldDescriptor;

  DEBUG ((DEBUG_INFO | DEBUG_INIT, "The entry of FspNotificationPeim\n"));

  if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
    //
    // Locate old DXE IPL PPI
    //
    Status = PeiServicesLocatePpi (
               &gEfiDxeIplPpiGuid,
               0,
               &OldDescriptor,
               &OldDxeIplPpi
               );
    ASSERT_EFI_ERROR (Status);

    //
    // Re-install the DXE IPL PPI to wait for notify
    //
    Status = PeiServicesReInstallPpi (OldDescriptor, &mInstallDxeIplPpi);
    ASSERT_EFI_ERROR (Status);
  } else {
    Status = PeiServicesInstallPpi (&gFspReadyForNotifyPhasePpi);
    ASSERT_EFI_ERROR (Status);
  }

  return EFI_SUCCESS;
}