]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbServiceDxe.c
Vlv2TbltDevicePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / Vlv2TbltDevicePkg / FvbRuntimeDxe / FvbServiceDxe.c
CommitLineData
3cbfba02
DW
1/** @file\r
2 Firmware Volume Block Driver for Lakeport Platform.\r
3\r
4 Firmware volume block driver for FWH or SPI device.\r
5 It depends on which Flash Device Library to be linked with this driver.\r
6\r
7Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
8 \r\r
9dc8036d
MK
9 SPDX-License-Identifier: BSD-2-Clause-Patent\r
10\r
3cbfba02
DW
11 \r\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16#include <Library/UefiRuntimeLib.h>\r
17#include "FvbService.h"\r
18\r
19extern FWB_GLOBAL mFvbModuleGlobal;\r
20\r
21/**\r
22 Call back function on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.\r
23\r
24 Fixup internal data so that the driver is callable in EFI runtime\r
25 in virtual mode. Convert the mFvbModuleGlobal date items to there\r
26 virtual address.\r
27\r
28 @param Event Event whose notification function is being invoked.\r
29 @param Context The context of the Notification context. Not used in\r
30 this call back function.\r
31\r
32**/\r
33VOID\r
34EFIAPI\r
35FvbVirtualddressChangeEvent (\r
36 IN EFI_EVENT Event,\r
37 IN VOID *Context\r
38 )\r
39{\r
40 EFI_FW_VOL_INSTANCE *FwhInstance;\r
41 UINTN Index;\r
42\r
43 //\r
44 // Convert the base address of all the instances.\r
45 //\r
46 for (Index = 0; Index < mFvbModuleGlobal.NumFv; Index++) {\r
47 FwhInstance = GetFvbInstance (Index);\r
48 EfiConvertPointer (0, (VOID **) &FwhInstance->FvBase);\r
49 }\r
50\r
51 EfiConvertPointer (0, (VOID **) &mFvbModuleGlobal.FvInstance);\r
52}\r
53\r
54\r
55/**\r
56 The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol\r
57 for each FV in the system.\r
58\r
59 @param[in] FwhInstance The pointer to a FW volume instance structure,\r
60 which contains the information about one FV.\r
61 @param[in] InstanceNum The instance number which can be used as a ID\r
62 to locate this FwhInstance in other functions.\r
63\r
64 @retval VOID\r
65\r
66**/\r
67VOID\r
68InstallFvbProtocol (\r
69 IN EFI_FW_VOL_INSTANCE *FwhInstance,\r
70 IN UINTN InstanceNum\r
71 )\r
72{\r
73 EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;\r
74 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
75 EFI_STATUS Status;\r
76 EFI_HANDLE FwbHandle;\r
77 EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;\r
78\r
79 FvbDevice = (EFI_FW_VOL_BLOCK_DEVICE *) AllocateRuntimeCopyPool (\r
80 sizeof (EFI_FW_VOL_BLOCK_DEVICE),\r
81 &mFvbDeviceTemplate\r
82 );\r
83 ASSERT (FvbDevice != NULL);\r
84\r
85 FvbDevice->Instance = InstanceNum;\r
86 FwVolHeader = &FwhInstance->VolumeHeader;\r
87\r
88 //\r
89 // Set up the devicepath.\r
90 //\r
91 DEBUG ((EFI_D_INFO, "FwBlockService.c: Setting up DevicePath for 0x%lx:\n", FwhInstance->FvBase));\r
92 if (FwVolHeader->ExtHeaderOffset == 0) {\r
93 //\r
94 // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH.\r
95 //\r
96 FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate);\r
97 ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.StartingAddress = FwhInstance->FvBase;\r
98 ((FV_MEMMAP_DEVICE_PATH *) FvbDevice->DevicePath)->MemMapDevPath.EndingAddress = FwhInstance->FvBase + FwVolHeader->FvLength - 1;\r
99 } else {\r
100 FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateRuntimeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate);\r
101 CopyGuid (\r
102 &((FV_PIWG_DEVICE_PATH *)FvbDevice->DevicePath)->FvDevPath.FvName,\r
103 (GUID *)(UINTN)(FwhInstance->FvBase + FwVolHeader->ExtHeaderOffset)\r
104 );\r
105 }\r
106\r
107 //\r
108 // Find a handle with a matching device path that has supports FW Block protocol.\r
109 //\r
110 Status = gBS->LocateDevicePath (\r
111 &gEfiFirmwareVolumeBlockProtocolGuid,\r
112 &FvbDevice->DevicePath,\r
113 &FwbHandle\r
114 );\r
115 if (EFI_ERROR (Status) ) {\r
116 //\r
117 // LocateDevicePath fails so install a new interface and device path.\r
118 //\r
119 DEBUG ((EFI_D_INFO, "FwBlockService.c: LocateDevicePath failed, install new interface 0x%lx:\n", FwhInstance->FvBase));\r
120 FwbHandle = NULL;\r
121 Status = gBS->InstallMultipleProtocolInterfaces (\r
122 &FwbHandle,\r
123 &gEfiFirmwareVolumeBlockProtocolGuid,\r
124 &FvbDevice->FwVolBlockInstance,\r
125 &gEfiDevicePathProtocolGuid,\r
126 FvbDevice->DevicePath,\r
127 NULL\r
128 );\r
129 ASSERT_EFI_ERROR (Status);\r
130 DEBUG ((EFI_D_INFO, "FwBlockService.c: IMPI FirmwareVolBlockProt, DevPath 0x%lx: %r\n", FwhInstance->FvBase, Status));\r
131\r
132 } else if (IsDevicePathEnd (FvbDevice->DevicePath)) {\r
133 //\r
134 // Device allready exists, so reinstall the FVB protocol.\r
135 //\r
136 DEBUG ((EFI_D_ERROR, "FwBlockService.c: LocateDevicePath succeeded, reinstall interface 0x%lx:\n", FwhInstance->FvBase));\r
137 Status = gBS->HandleProtocol (\r
138 FwbHandle,\r
139 &gEfiFirmwareVolumeBlockProtocolGuid,\r
140 (VOID **) &OldFwbInterface\r
141 );\r
142 ASSERT_EFI_ERROR (Status);\r
143\r
144 Status = gBS->ReinstallProtocolInterface (\r
145 FwbHandle,\r
146 &gEfiFirmwareVolumeBlockProtocolGuid,\r
147 OldFwbInterface,\r
148 &FvbDevice->FwVolBlockInstance\r
149 );\r
150 ASSERT_EFI_ERROR (Status);\r
151\r
152 } else {\r
153 //\r
154 // There was a FVB protocol on an End Device Path node.\r
155 //\r
156 ASSERT (FALSE);\r
157 }\r
158\r
159}\r
160\r
161\r
162/**\r
163 The driver entry point for Firmware Volume Block Driver.\r
164\r
165 The function does the necessary initialization work for\r
166 Firmware Volume Block Driver.\r
167\r
168 @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
169 @param[in] SystemTable A pointer to the EFI system table.\r
170\r
171 @retval EFI_SUCCESS This funtion always return EFI_SUCCESS.\r
172 It will ASSERT on errors.\r
173\r
174**/\r
175EFI_STATUS\r
176EFIAPI\r
177DxeFvbInitialize (\r
178 IN EFI_HANDLE ImageHandle,\r
179 IN EFI_SYSTEM_TABLE *SystemTable\r
180 )\r
181{\r
182 EFI_STATUS Status;\r
183 EFI_EVENT Event;\r
184\r
185 Status = gBS->CreateEventEx (\r
186 EVT_NOTIFY_SIGNAL,\r
187 TPL_NOTIFY,\r
188 FvbVirtualddressChangeEvent,\r
189 NULL,\r
190 &gEfiEventVirtualAddressChangeGuid,\r
191 &Event\r
192 );\r
193 ASSERT_EFI_ERROR (Status);\r
194\r
195 FvbInitialize ();\r
196\r
197 return EFI_SUCCESS;\r
198}\r
199\r