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
|
/** @file
SMM Firmware Volume Block Driver.
Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiSmm.h>
#include <Library/SmmServicesTableLib.h>
#include "FvbSmmCommon.h"
#include "FvbService.h"
/**
The function installs EFI_SMM_FIRMWARE_VOLUME_BLOCK protocol
for each FV in the system.
@param[in] FwhInstance The pointer to a FW volume instance structure,
which contains the information about one FV.
@param[in] InstanceNum The instance number which can be used as a ID
to locate this FwhInstance in other functions.
@retval EFI_SUCESS Installed successfully.
@retval Else Did not install successfully.
**/
EFI_STATUS
InstallFvbProtocol (
IN EFI_FW_VOL_INSTANCE *FwhInstance,
IN UINTN InstanceNum
)
{
EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
EFI_STATUS Status;
EFI_HANDLE FvbHandle;
FV_MEMMAP_DEVICE_PATH *FvDevicePath;
VOID *TempPtr;
FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *)AllocateRuntimeCopyPool (
sizeof (EFI_FW_VOL_BLOCK_DEVICE),
&mFvbDeviceTemplate
);
if (FvbDevice == NULL) {
return EFI_OUT_OF_RESOURCES;
}
FvbDevice->Instance = InstanceNum;
FwVolHeader = &FwhInstance->VolumeHeader;
//
// Set up the devicepath
//
if (FwVolHeader->ExtHeaderOffset == 0) {
//
// FV does not contains extension header, then produce MEMMAP_DEVICE_PATH
//
TempPtr = AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);
FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)TempPtr;
if (FvbDevice->DevicePath == NULL) {
ASSERT (FALSE);
return EFI_OUT_OF_RESOURCES;
}
FvDevicePath = (FV_MEMMAP_DEVICE_PATH *)FvbDevice->DevicePath;
FvDevicePath->MemMapDevPath.StartingAddress = FwhInstance->FvBase;
FvDevicePath->MemMapDevPath.EndingAddress = FwhInstance->FvBase + FwVolHeader->FvLength - 1;
} else {
TempPtr = AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);
FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)TempPtr;
if (FvbDevice->DevicePath == NULL) {
ASSERT (FALSE);
return EFI_OUT_OF_RESOURCES;
}
CopyGuid (
&((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,
(GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset)
);
}
//
// Install the SMM Firmware Volume Block Protocol and Device Path Protocol
//
FvbHandle = NULL;
Status = gSmst->SmmInstallProtocolInterface (
&FvbHandle,
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
EFI_NATIVE_INTERFACE,
&FvbDevice->FwVolBlockInstance
);
ASSERT_EFI_ERROR (Status);
Status = gSmst->SmmInstallProtocolInterface (
&FvbHandle,
&gEfiDevicePathProtocolGuid,
EFI_NATIVE_INTERFACE,
FvbDevice->DevicePath
);
ASSERT_EFI_ERROR (Status);
//
// Notify the Fvb wrapper driver SMM fvb is ready
//
FvbHandle = NULL;
Status = gBS->InstallProtocolInterface (
&FvbHandle,
&gEfiSmmFirmwareVolumeBlockProtocolGuid,
EFI_NATIVE_INTERFACE,
&FvbDevice->FwVolBlockInstance
);
return Status;
}
/**
The driver entry point for SMM Firmware Volume Block Driver.
The function does the necessary initialization work
Firmware Volume Block Driver.
@param[in] ImageHandle The firmware allocated handle for the UEFI image.
@param[in] SystemTable A pointer to the EFI system table.
@retval EFI_SUCCESS This funtion always return EFI_SUCCESS.
It will ASSERT on errors.
**/
EFI_STATUS
EFIAPI
FvbSmmInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
FvbInitialize ();
return EFI_SUCCESS;
}
|