]> git.proxmox.com Git - mirror_edk2.git/blob - UefiPayloadPkg/FvbRuntimeDxe/FvbServiceSmm.c
UefiPayloadPkg: Add a common FVB SMM module
[mirror_edk2.git] / UefiPayloadPkg / FvbRuntimeDxe / FvbServiceSmm.c
1 /** @file
2 SMM Firmware Volume Block Driver.
3
4 Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiSmm.h>
10 #include <Library/SmmServicesTableLib.h>
11 #include "FvbSmmCommon.h"
12 #include "FvbService.h"
13
14 /**
15 The function installs EFI_SMM_FIRMWARE_VOLUME_BLOCK protocol
16 for each FV in the system.
17
18 @param[in] FwhInstance The pointer to a FW volume instance structure,
19 which contains the information about one FV.
20 @param[in] InstanceNum The instance number which can be used as a ID
21 to locate this FwhInstance in other functions.
22
23 @retval EFI_SUCESS Installed successfully.
24 @retval Else Did not install successfully.
25
26 **/
27 EFI_STATUS
28 InstallFvbProtocol (
29 IN EFI_FW_VOL_INSTANCE *FwhInstance,
30 IN UINTN InstanceNum
31 )
32 {
33 EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
34 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
35 EFI_STATUS Status;
36 EFI_HANDLE FvbHandle;
37 FV_MEMMAP_DEVICE_PATH *FvDevicePath;
38 VOID *TempPtr;
39
40 FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool (
41 sizeof (EFI_FW_VOL_BLOCK_DEVICE),
42 &mFvbDeviceTemplate
43 );
44 if (FvbDevice == NULL) {
45 return EFI_OUT_OF_RESOURCES;
46 }
47
48 FvbDevice->Instance = InstanceNum;
49 FwVolHeader = &FwhInstance->VolumeHeader;
50
51 //
52 // Set up the devicepath
53 //
54 if (FwVolHeader->ExtHeaderOffset == 0) {
55 //
56 // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
57 //
58 TempPtr = AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
59 FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
60 if (FvbDevice->DevicePath == NULL) {
61 ASSERT (FALSE);
62 return EFI_OUT_OF_RESOURCES;
63 }
64 FvDevicePath = (FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath;
65 FvDevicePath->MemMapDevPath.StartingAddress = FwhInstance->FvBase;
66 FvDevicePath->MemMapDevPath.EndingAddress = FwhInstance->FvBase + FwVolHeader->FvLength - 1;
67 } else {
68 TempPtr = AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);
69 FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
70 if (FvbDevice->DevicePath == NULL) {
71 ASSERT (FALSE);
72 return EFI_OUT_OF_RESOURCES;
73 }
74
75 CopyGuid (
76 &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,
77 (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset)
78 );
79 }
80
81 //
82 // Install the SMM Firmware Volume Block Protocol and Device Path Protocol
83 //
84 FvbHandle = NULL;
85 Status = gSmst->SmmInstallProtocolInterface (
86 &FvbHandle,
87 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
88 EFI_NATIVE_INTERFACE,
89 &FvbDevice->FwVolBlockInstance
90 );
91 ASSERT_EFI_ERROR (Status);
92
93 Status = gSmst->SmmInstallProtocolInterface (
94 &FvbHandle,
95 &gEfiDevicePathProtocolGuid,
96 EFI_NATIVE_INTERFACE,
97 FvbDevice->DevicePath
98 );
99 ASSERT_EFI_ERROR (Status);
100
101 //
102 // Notify the Fvb wrapper driver SMM fvb is ready
103 //
104 FvbHandle = NULL;
105 Status = gBS->InstallProtocolInterface (
106 &FvbHandle,
107 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
108 EFI_NATIVE_INTERFACE,
109 &FvbDevice->FwVolBlockInstance
110 );
111
112 return Status;
113 }
114
115
116 /**
117 The driver entry point for SMM Firmware Volume Block Driver.
118
119 The function does the necessary initialization work
120 Firmware Volume Block Driver.
121
122 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
123 @param[in] SystemTable A pointer to the EFI system table.
124
125 @retval EFI_SUCCESS This funtion always return EFI_SUCCESS.
126 It will ASSERT on errors.
127
128 **/
129 EFI_STATUS
130 EFIAPI
131 FvbSmmInitialize (
132 IN EFI_HANDLE ImageHandle,
133 IN EFI_SYSTEM_TABLE *SystemTable
134 )
135 {
136 FvbInitialize ();
137
138 return EFI_SUCCESS;
139 }