32#define RESERVED_MEM_ALIGNMENT 8
35STATIC VOID *mScratchBuffer;
42STATIC FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *mCallback;
57 ASSERT (Event == mS3SaveStateInstalledEvent);
59 Status =
gBS->LocateProtocol (
60 &gEfiS3SaveStateProtocolGuid,
62 (VOID **)&mS3SaveState
64 if (EFI_ERROR (Status)) {
68 ASSERT (mCallback !=
NULL);
72 "%a: %a: DmaAccess@0x%Lx ScratchBuffer@[0x%Lx+0x%Lx]\n",
75 (UINT64)(
UINTN)mDmaAccess,
76 (UINT64)(
UINTN)mScratchBuffer,
77 (UINT64)mScratchBufferSize
79 mCallback (Context, mScratchBuffer);
81 gBS->CloseEvent (mS3SaveStateInstalledEvent);
82 mS3SaveStateInstalledEvent =
NULL;
145 IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback,
146 IN OUT VOID *Context OPTIONAL,
162 "%a: %a: fw_cfg DMA unavailable\n",
173 if (ScratchBufferSize >
174 MAX_UINT32 - (RESERVED_MEM_ALIGNMENT - 1) -
sizeof *mDmaAccess)
178 "%a: %a: ScratchBufferSize too big: %Lu\n",
181 (UINT64)ScratchBufferSize
187 (RESERVED_MEM_ALIGNMENT - 1) +
188 sizeof *mDmaAccess + ScratchBufferSize
190 if (mDmaAccess ==
NULL) {
193 "%a: %a: AllocateReservedPool(): out of resources\n",
200 mDmaAccess =
ALIGN_POINTER (mDmaAccess, RESERVED_MEM_ALIGNMENT);
206 Status =
gBS->CreateEvent (
211 &mS3SaveStateInstalledEvent
213 if (EFI_ERROR (Status)) {
216 "%a: %a: CreateEvent(): %r\n",
224 Status =
gBS->RegisterProtocolNotify (
225 &gEfiS3SaveStateProtocolGuid,
226 mS3SaveStateInstalledEvent,
229 if (EFI_ERROR (Status)) {
232 "%a: %a: RegisterProtocolNotify(): %r\n",
245 ASSERT (
sizeof *mDmaAccess % RESERVED_MEM_ALIGNMENT == 0);
246 mScratchBuffer = mDmaAccess + 1;
247 mScratchBufferSize = ScratchBufferSize;
248 mCallback = Callback;
253 Status =
gBS->SignalEvent (mS3SaveStateInstalledEvent);
254 if (EFI_ERROR (Status)) {
257 "%a: %a: SignalEvent(): %r\n",
268 mScratchBuffer =
NULL;
269 mScratchBufferSize = 0;
273 gBS->CloseEvent (mS3SaveStateInstalledEvent);
274 mS3SaveStateInstalledEvent =
NULL;
280 return (RETURN_STATUS)Status;
326 IN INT32 FirmwareConfigItem,
332 UINT64 AccessAddress;
333 UINT32 ControlPollData;
334 UINT32 ControlPollMask;
336 ASSERT (mDmaAccess !=
NULL);
337 ASSERT (mS3SaveState !=
NULL);
339 if ((FirmwareConfigItem < -1) || (FirmwareConfigItem > MAX_UINT16)) {
343 if (NumberOfBytes > mScratchBufferSize) {
350 mDmaAccess->Control = FW_CFG_DMA_CTL_WRITE;
351 if (FirmwareConfigItem != -1) {
352 mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT;
353 mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16;
356 mDmaAccess->Control =
SwapBytes32 (mDmaAccess->Control);
362 ASSERT (NumberOfBytes <= MAX_UINT32);
363 mDmaAccess->Length =
SwapBytes32 ((UINT32)NumberOfBytes);
372 Count = (
UINTN)mScratchBuffer + NumberOfBytes - (
UINTN)mDmaAccess;
373 Status = mS3SaveState->Write (
375 EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,
376 EfiBootScriptWidthUint8,
377 (UINT64)(
UINTN)mDmaAccess,
381 if (EFI_ERROR (Status)) {
384 "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n",
389 return (RETURN_STATUS)Status;
399 Status = mS3SaveState->Write (
401 EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,
402 EfiBootScriptWidthUint32,
403 (UINT64)FW_CFG_IO_DMA_ADDRESS,
405 (VOID *)&AccessAddress
407 if (EFI_ERROR (Status)) {
410 "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n",
415 return (RETURN_STATUS)Status;
424 ControlPollMask = MAX_UINT32;
425 Status = mS3SaveState->Write (
427 EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,
428 EfiBootScriptWidthUint32,
429 (UINT64)(
UINTN)&mDmaAccess->Control,
430 (VOID *)&ControlPollData,
431 (VOID *)&ControlPollMask,
434 if (EFI_ERROR (Status)) {
437 "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
442 return (RETURN_STATUS)Status;
490 IN INT32 FirmwareConfigItem,
495 UINT64 AccessAddress;
496 UINT32 ControlPollData;
497 UINT32 ControlPollMask;
499 ASSERT (mDmaAccess !=
NULL);
500 ASSERT (mS3SaveState !=
NULL);
502 if ((FirmwareConfigItem < -1) || (FirmwareConfigItem > MAX_UINT16)) {
506 if (NumberOfBytes > mScratchBufferSize) {
513 mDmaAccess->Control = FW_CFG_DMA_CTL_READ;
514 if (FirmwareConfigItem != -1) {
515 mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT;
516 mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16;
519 mDmaAccess->Control =
SwapBytes32 (mDmaAccess->Control);
525 ASSERT (NumberOfBytes <= MAX_UINT32);
526 mDmaAccess->Length =
SwapBytes32 ((UINT32)NumberOfBytes);
534 Status = mS3SaveState->Write (
536 EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,
537 EfiBootScriptWidthUint8,
538 (UINT64)(
UINTN)mDmaAccess,
542 if (EFI_ERROR (Status)) {
545 "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n",
550 return (RETURN_STATUS)Status;
560 Status = mS3SaveState->Write (
562 EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,
563 EfiBootScriptWidthUint32,
564 (UINT64)FW_CFG_IO_DMA_ADDRESS,
566 (VOID *)&AccessAddress
568 if (EFI_ERROR (Status)) {
571 "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n",
576 return (RETURN_STATUS)Status;
585 ControlPollMask = MAX_UINT32;
586 Status = mS3SaveState->Write (
588 EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,
589 EfiBootScriptWidthUint32,
590 (UINT64)(
UINTN)&mDmaAccess->Control,
591 (VOID *)&ControlPollData,
592 (VOID *)&ControlPollMask,
595 if (EFI_ERROR (Status)) {
598 "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
603 return (RETURN_STATUS)Status;
644 IN INT32 FirmwareConfigItem,
649 UINT64 AccessAddress;
650 UINT32 ControlPollData;
651 UINT32 ControlPollMask;
653 ASSERT (mDmaAccess !=
NULL);
654 ASSERT (mS3SaveState !=
NULL);
656 if ((FirmwareConfigItem < -1) || (FirmwareConfigItem > MAX_UINT16)) {
660 if (NumberOfBytes > MAX_UINT32) {
667 mDmaAccess->Control = FW_CFG_DMA_CTL_SKIP;
668 if (FirmwareConfigItem != -1) {
669 mDmaAccess->Control |= FW_CFG_DMA_CTL_SELECT;
670 mDmaAccess->Control |= (UINT32)FirmwareConfigItem << 16;
673 mDmaAccess->Control =
SwapBytes32 (mDmaAccess->Control);
675 mDmaAccess->Length =
SwapBytes32 ((UINT32)NumberOfBytes);
676 mDmaAccess->Address = 0;
682 Status = mS3SaveState->Write (
684 EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,
685 EfiBootScriptWidthUint8,
686 (UINT64)(
UINTN)mDmaAccess,
690 if (EFI_ERROR (Status)) {
693 "%a: %a: EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE: %r\n",
698 return (RETURN_STATUS)Status;
708 Status = mS3SaveState->Write (
710 EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,
711 EfiBootScriptWidthUint32,
712 (UINT64)FW_CFG_IO_DMA_ADDRESS,
714 (VOID *)&AccessAddress
716 if (EFI_ERROR (Status)) {
719 "%a: %a: EFI_BOOT_SCRIPT_IO_WRITE_OPCODE: %r\n",
724 return (RETURN_STATUS)Status;
733 ControlPollMask = MAX_UINT32;
734 Status = mS3SaveState->Write (
736 EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,
737 EfiBootScriptWidthUint32,
738 (UINT64)(
UINTN)&mDmaAccess->Control,
739 (VOID *)&ControlPollData,
740 (VOID *)&ControlPollMask,
743 if (EFI_ERROR (Status)) {
746 "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
751 return (RETURN_STATUS)Status;
810 IN VOID *ScratchData,
816 EFI_BOOT_SCRIPT_WIDTH Width;
819 ASSERT (mS3SaveState !=
NULL);
823 Width = EfiBootScriptWidthUint8;
827 Width = EfiBootScriptWidthUint16;
831 Width = EfiBootScriptWidthUint32;
835 Width = EfiBootScriptWidthUint64;
842 if ((ValueSize < 8) &&
843 ((
RShiftU64 (ValueMask, ValueSize * 8) > 0) ||
849 if ((
UINTN)ScratchData % ValueSize > 0) {
853 if (((
UINTN)ScratchData < (
UINTN)mScratchBuffer) ||
854 ((
UINTN)ScratchData > MAX_UINTN - ValueSize) ||
855 ((
UINTN)ScratchData + ValueSize >
856 (
UINTN)mScratchBuffer + mScratchBufferSize))
866 Status = mS3SaveState->Write (
868 EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,
870 (UINT64)(
UINTN)ScratchData,
875 if (EFI_ERROR (Status)) {
878 "%a: %a: EFI_BOOT_SCRIPT_MEM_POLL_OPCODE: %r\n",
883 return (RETURN_STATUS)Status;
UINT32 EFIAPI SwapBytes32(IN UINT32 Value)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI SwapBytes64(IN UINT64 Value)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateReservedPool(IN UINTN AllocationSize)
#define RETURN_OUT_OF_RESOURCES
#define ALIGN_POINTER(Pointer, Alignment)
#define RETURN_INVALID_PARAMETER
#define RETURN_BAD_BUFFER_SIZE
#define DEBUG(Expression)
UINT32 EFIAPI QemuFwCfgRead32(VOID)
VOID EFIAPI QemuFwCfgSelectItem(IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem)
BOOLEAN EFIAPI QemuFwCfgIsAvailable(VOID)
RETURN_STATUS EFIAPI QemuFwCfgS3ScriptReadBytes(IN INT32 FirmwareConfigItem, IN UINTN NumberOfBytes)
RETURN_STATUS EFIAPI QemuFwCfgS3ScriptWriteBytes(IN INT32 FirmwareConfigItem, IN UINTN NumberOfBytes)
RETURN_STATUS EFIAPI QemuFwCfgS3CallWhenBootScriptReady(IN FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION *Callback, IN OUT VOID *Context OPTIONAL, IN UINTN ScratchBufferSize)
STATIC VOID EFIAPI S3SaveStateInstalledNotify(IN EFI_EVENT Event, IN VOID *Context)
RETURN_STATUS EFIAPI QemuFwCfgS3ScriptCheckValue(IN VOID *ScratchData, IN UINT8 ValueSize, IN UINT64 ValueMask, IN UINT64 Value)
RETURN_STATUS EFIAPI QemuFwCfgS3ScriptSkipBytes(IN INT32 FirmwareConfigItem, IN UINTN NumberOfBytes)