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