59VOID *mFvbRegistration =
NULL;
88 return gMmst->MmHandleProtocol (
90 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
107 OUT VOID **SarProtocol
115 Status = gMmst->MmLocateProtocol (
116 &gEfiSmmSwapAddressRangeProtocolGuid,
147 if ((NumberHandles ==
NULL) || (Buffer ==
NULL)) {
148 return EFI_INVALID_PARAMETER;
154 Status = gMmst->MmLocateHandle (
156 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
161 if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
162 return EFI_NOT_FOUND;
166 if (*Buffer ==
NULL) {
167 return EFI_OUT_OF_RESOURCES;
170 Status = gMmst->MmLocateHandle (
172 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
178 *NumberHandles = BufferSize /
sizeof (
EFI_HANDLE);
179 if (EFI_ERROR (Status)) {
220 if (EFI_ERROR (Status)) {
227 for (Index = 0; Index < HandleCount; Index++) {
229 if (EFI_ERROR (Status)) {
236 Status = Fvb->GetPhysicalAddress (Fvb, &FvbBaseAddress);
237 if (EFI_ERROR (Status)) {
241 if (Address != FvbBaseAddress) {
248 Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
249 if (EFI_ERROR (Status)) {
253 if (Attributes != FvbAttributes) {
260 *SmmFvbHandle = HandleBuffer[Index];
299 IN CONST VOID *RegisterContext,
300 IN OUT VOID *CommBuffer,
314 UINTN CommBufferPayloadSize;
315 UINTN PrivateDataSize;
317 UINTN TempCommBufferSize;
322 if ((CommBuffer ==
NULL) || (CommBufferSize ==
NULL)) {
326 TempCommBufferSize = *CommBufferSize;
329 DEBUG ((DEBUG_ERROR,
"SmmFtwHandler: SMM communication buffer size invalid!\n"));
336 DEBUG ((DEBUG_ERROR,
"SmmFtwHandler: SMM Primary(communication buffer) is not valid!\n"));
346 DEBUG ((DEBUG_ERROR,
"SmmFtwHandler: Not safe to do the operation: %x after End Of Dxe, so access denied!\n", SmmFtwFunctionHeader->Function));
347 SmmFtwFunctionHeader->ReturnStatus = EFI_ACCESS_DENIED;
351 switch (SmmFtwFunctionHeader->Function) {
352 case FTW_FUNCTION_GET_MAX_BLOCK_SIZE:
354 DEBUG ((DEBUG_ERROR,
"GetMaxBlockSize: SMM communication buffer size invalid!\n"));
361 &mFtwDevice->FtwInstance,
362 &SmmGetMaxBlockSizeHeader->BlockSize
366 case FTW_FUNCTION_ALLOCATE:
368 DEBUG ((DEBUG_ERROR,
"Allocate: SMM communication buffer size invalid!\n"));
374 &mFtwDevice->FtwInstance,
375 &SmmFtwAllocateHeader->CallerId,
376 SmmFtwAllocateHeader->PrivateDataSize,
377 SmmFtwAllocateHeader->NumberOfWrites
381 case FTW_FUNCTION_WRITE:
383 DEBUG ((DEBUG_ERROR,
"Write: SMM communication buffer size invalid!\n"));
388 Length = SmmFtwWriteHeader->Length;
389 PrivateDataSize = SmmFtwWriteHeader->PrivateDataSize;
396 Status = EFI_ACCESS_DENIED;
405 if (InfoSize > CommBufferPayloadSize) {
406 DEBUG ((DEBUG_ERROR,
"Write: Data size exceed communication buffer size limit!\n"));
407 Status = EFI_ACCESS_DENIED;
411 if (PrivateDataSize == 0) {
414 PrivateData = (VOID *)&SmmFtwWriteHeader->Data[Length];
418 SmmFtwWriteHeader->FvbBaseAddress,
419 SmmFtwWriteHeader->FvbAttributes,
422 if (!EFI_ERROR (Status)) {
430 &mFtwDevice->FtwInstance,
431 SmmFtwWriteHeader->Lba,
432 SmmFtwWriteHeader->Offset,
436 SmmFtwWriteHeader->Data
442 case FTW_FUNCTION_RESTART:
444 DEBUG ((DEBUG_ERROR,
"Restart: SMM communication buffer size invalid!\n"));
450 SmmFtwRestartHeader->FvbBaseAddress,
451 SmmFtwRestartHeader->FvbAttributes,
454 if (!EFI_ERROR (Status)) {
455 Status =
FtwRestart (&mFtwDevice->FtwInstance, SmmFvbHandle);
460 case FTW_FUNCTION_ABORT:
461 Status =
FtwAbort (&mFtwDevice->FtwInstance);
464 case FTW_FUNCTION_GET_LAST_WRITE:
466 DEBUG ((DEBUG_ERROR,
"GetLastWrite: SMM communication buffer size invalid!\n"));
471 PrivateDataSize = SmmFtwGetLastWriteHeader->PrivateDataSize;
476 Status = EFI_ACCESS_DENIED;
485 if (InfoSize > CommBufferPayloadSize) {
486 DEBUG ((DEBUG_ERROR,
"Data size exceed communication buffer size limit!\n"));
487 Status = EFI_ACCESS_DENIED;
492 &mFtwDevice->FtwInstance,
493 &SmmFtwGetLastWriteHeader->CallerId,
494 &SmmFtwGetLastWriteHeader->Lba,
495 &SmmFtwGetLastWriteHeader->Offset,
496 &SmmFtwGetLastWriteHeader->Length,
498 (VOID *)SmmFtwGetLastWriteHeader->Data,
499 &SmmFtwGetLastWriteHeader->Complete
501 SmmFtwGetLastWriteHeader->PrivateDataSize = PrivateDataSize;
505 Status = EFI_UNSUPPORTED;
508 SmmFtwFunctionHeader->ReturnStatus = Status;
539 Status = gMmst->MmLocateProtocol (
540 &gEfiSmmFaultTolerantWriteProtocolGuid,
542 (VOID **)&FtwProtocol
544 if (!EFI_ERROR (Status)) {
552 if (EFI_ERROR (Status)) {
561 &gEfiSmmFaultTolerantWriteProtocolGuid,
563 &mFtwDevice->FtwInstance
616 VOID *MmEndOfDxeRegistration;
622 if (EFI_ERROR (Status)) {
629 Status = gMmst->MmRegisterProtocolNotify (
630 &gEfiMmEndOfDxeProtocolGuid,
632 &MmEndOfDxeRegistration
639 Status = gMmst->MmRegisterProtocolNotify (
640 &gEfiSmmFirmwareVolumeBlockProtocolGuid,
VOID EFIAPI SpeculationBarrier(VOID)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI FtwGetMaxBlockSize(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, OUT UINTN *BlockSize)
EFI_STATUS EFIAPI FtwRestart(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, IN EFI_HANDLE FvBlockHandle)
EFI_STATUS EFIAPI FtwAllocate(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, IN EFI_GUID *CallerId, IN UINTN PrivateDataSize, IN UINTN NumberOfWrites)
EFI_STATUS EFIAPI FtwWrite(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, IN EFI_LBA Lba, IN UINTN Offset, IN UINTN Length, IN VOID *PrivateData, IN EFI_HANDLE FvBlockHandle, IN VOID *Buffer)
EFI_STATUS EFIAPI FtwGetLastWrite(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This, OUT EFI_GUID *CallerId, OUT EFI_LBA *Lba, OUT UINTN *Offset, OUT UINTN *Length, IN OUT UINTN *PrivateDataSize, OUT VOID *PrivateData, OUT BOOLEAN *Complete)
EFI_STATUS EFIAPI FtwAbort(IN EFI_FAULT_TOLERANT_WRITE_PROTOCOL *This)
EFI_STATUS FtwGetSarProtocol(OUT VOID **SarProtocol)
EFI_STATUS EFIAPI MmEndOfDxeCallback(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
EFI_STATUS EFIAPI FvbNotificationEvent(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
EFI_STATUS GetFvbCountAndBuffer(OUT UINTN *NumberHandles, OUT EFI_HANDLE **Buffer)
EFI_STATUS FtwGetFvbByHandle(IN EFI_HANDLE FvBlockHandle, OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock)
EFI_STATUS EFIAPI SmmFaultTolerantWriteHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *RegisterContext, IN OUT VOID *CommBuffer, IN OUT UINTN *CommBufferSize)
EFI_STATUS MmFaultTolerantWriteInitialize(VOID)
EFI_STATUS GetFvbByAddressAndAttribute(IN EFI_PHYSICAL_ADDRESS Address, IN EFI_FVB_ATTRIBUTES_2 Attributes, OUT EFI_HANDLE *SmmFvbHandle)
#define SMM_FTW_COMMUNICATE_HEADER_SIZE
VOID FtwNotifySmmReady(VOID)
BOOLEAN FtwSmmIsPrimaryBufferValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
#define OFFSET_OF(TYPE, Field)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
UINT32 EFI_FVB_ATTRIBUTES_2
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
UINT64 EFI_PHYSICAL_ADDRESS
EFI_STATUS InitFtwDevice(OUT EFI_FTW_DEVICE **FtwData)
EFI_STATUS InitFtwProtocol(IN OUT EFI_FTW_DEVICE *FtwDevice)
EFI_INSTALL_PROTOCOL_INTERFACE MmInstallProtocolInterface