File: ArmFfaPeiLib.c

package info (click to toggle)
edk2 2025.11-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 338,436 kB
  • sloc: ansic: 2,166,377; asm: 270,725; perl: 235,301; python: 149,900; sh: 34,744; cpp: 23,311; makefile: 3,334; pascal: 1,602; xml: 806; lisp: 35; ruby: 16; sed: 6; tcl: 4
file content (200 lines) | stat: -rw-r--r-- 6,315 bytes parent folder | download
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/** @file
  Arm Ffa library code for PEI Driver

  Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

   @par Glossary:
     - FF-A - Firmware Framework for Arm A-profile

   @par Reference(s):
     - Arm Firmware Framework for Arm A-Profile [https://developer.arm.com/documentation/den0077/latest]

**/

#include <Uefi.h>
#include <PiPei.h>
#include <Pi/PiPeiCis.h>
#include <Pi/PiMultiPhase.h>

#include <Library/ArmLib.h>
#include <Library/ArmSmcLib.h>
#include <Library/ArmFfaLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>

#include <IndustryStandard/ArmFfaSvc.h>

#include <Guid/ArmFfaRxTxBufferInfo.h>

#include "ArmFfaCommon.h"
#include "ArmFfaRxTxMap.h"

/**
  Notification service to be called when gEfiPeiMemoryDiscoveredPpiGuid is installed.
  This function change reamp Rx/Tx buffer with permanent memory from
  temporary Rx/Tx buffer.

  Since, the Rx/Tx buffer is chanaged after gEfiPeiMemoryDiscoveredPpiGuid is installed,
  the Rx/Tx buffer should be gotten in each PEIM entrypoint
  via "ArmFfaGetRxTxBuffers()" for PEIM registered as shadow and
  call that function always then, it always gets proper Rx/Tx buffer.

  @param  PeiServices                 Indirect reference to the PEI Services Table.
  @param  NotifyDescriptor            Address of the notification descriptor data structure.
                                      Type EFI_PEI_NOTIFY_DESCRIPTOR is defined above.
  @param  Ppi                         Address of the PPI that was installed.

  @retval EFI_STATUS                  This function will install a PPI to PPI database.
                                      The status code will be the code for (*PeiServices)->InstallPpi.

**/
STATIC
EFI_STATUS
EFIAPI
PeiServicesMemoryDiscoveredNotifyCallback (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  EFI_HOB_GUID_TYPE          *RxTxBufferHob;
  ARM_FFA_RX_TX_BUFFER_INFO  *BufferInfo;

  RxTxBufferHob = GetFirstGuidHob (&gArmFfaRxTxBufferInfoGuid);
  ASSERT (RxTxBufferHob != NULL);
  BufferInfo = GET_GUID_HOB_DATA (RxTxBufferHob);

  return RemapFfaRxTxBuffer (BufferInfo);
}

STATIC EFI_PEI_NOTIFY_DESCRIPTOR  mNotifyOnPeiMemoryDiscovered = {
  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEfiPeiMemoryDiscoveredPpiGuid,
  PeiServicesMemoryDiscoveredNotifyCallback
};

/**
  ArmFfaLib Constructor.

  @param [in]   FileHandle        File Handle
  @param [in]   PeiServices       Pei Service Table

  @retval EFI_SUCCESS            Success
  @retval Others                 Error

**/
EFI_STATUS
EFIAPI
ArmFfaPeiLibConstructor (
  IN EFI_PEI_FILE_HANDLE     FileHandle,
  IN CONST EFI_PEI_SERVICES  **PeiServices
  )
{
  EFI_STATUS                 Status;
  EFI_HOB_GUID_TYPE          *RxTxBufferHob;
  ARM_FFA_RX_TX_BUFFER_INFO  *BufferInfo;
  VOID                       *Dummy;
  EFI_HOB_MEMORY_ALLOCATION  *RxTxBufferAllocationHob;

  Status = ArmFfaLibCommonInit ();
  if (EFI_ERROR (Status)) {
    if (Status == EFI_UNSUPPORTED) {
      /*
       * EFI_UNSUPPORTED return from ArmFfaLibCommonInit() means
       * FF-A interface doesn't support.
       * However, It doesn't make failure of loading driver/library instance
       * (i.e) ArmPkg's MmCommunication Dxe/PEI Driver uses as well as SpmMm.
       * So If FF-A is not supported the the MmCommunication Dxe/PEI falls
       * back to SpmMm.
       * For this case, return EFI_SUCCESS.

       */
      return EFI_SUCCESS;
    }

    return Status;
  }

  RxTxBufferHob = GetFirstGuidHob (&gArmFfaRxTxBufferInfoGuid);
  if (RxTxBufferHob == NULL) {
    Status = ArmFfaLibRxTxMap ();
    if (EFI_ERROR (Status)) {
      return Status;
    }

    BufferInfo = BuildGuidHob (
                   &gArmFfaRxTxBufferInfoGuid,
                   sizeof (ARM_FFA_RX_TX_BUFFER_INFO)
                   );
    if (BufferInfo == NULL) {
      ArmFfaLibRxTxUnmap ();
      return EFI_OUT_OF_RESOURCES;
    }

    UpdateRxTxBufferInfo (BufferInfo);

    /*
     * When permanent memory is used, gEfiPeiMemoryDiscoveredPpiGuid
     * is installed. If gEfiPeiMemoryDiscoveredPpiGuid is found,
     * It doesn't need to remap Rx/Tx buffer.
     */
    Status = (*PeiServices)->LocatePpi (
                               PeiServices,
                               &gEfiPeiMemoryDiscoveredPpiGuid,
                               0,
                               NULL,
                               &Dummy
                               );
    BufferInfo->RemapRequired = EFI_ERROR (Status);
  } else {
    BufferInfo = GET_GUID_HOB_DATA (RxTxBufferHob);
  }

  if (BufferInfo->RemapRequired) {
    /*
     * If RxTxBufferAllocationHob can be found with gArmFfaRxTxBufferInfoGuid,
     * This Rx/Tx buffer is mapped by ArmFfaSecLib.
     */
    RxTxBufferAllocationHob = FindRxTxBufferAllocationHob (TRUE);

    /*
     * Below case Rx/Tx buffer mapped by ArmPeiLib but in temporary memory.
     */
    if (RxTxBufferAllocationHob == NULL) {
      RxTxBufferAllocationHob = FindRxTxBufferAllocationHob (FALSE);
      ASSERT (RxTxBufferAllocationHob != NULL);
      BufferInfo->RemapOffset =
        (UINTN)(BufferInfo->TxBufferAddr -
                RxTxBufferAllocationHob->AllocDescriptor.MemoryBaseAddress);

      CopyGuid (
        &RxTxBufferAllocationHob->AllocDescriptor.Name,
        &gArmFfaRxTxBufferInfoGuid
        );
    }

    Status = (*PeiServices)->NotifyPpi (PeiServices, &mNotifyOnPeiMemoryDiscovered);

    /*
     * Failed to register NotifyPpi.
     * In this case, return ERROR to make failure of load for PPI
     * and postpone to remap to other PEIM.
     */
    if (EFI_ERROR (Status)) {
      return Status;
    }

    /*
     * Change RemapRequired to FALSE here to prevent other PEIM from
     * registering notification again.
     */
    BufferInfo->RemapRequired = FALSE;
  }

  return EFI_SUCCESS;
}