TianoCore EDK2 master
Loading...
Searching...
No Matches
BootScriptSave.c
Go to the documentation of this file.
1
10
98
99//
100// Allocate SMM copy because we can not use mS3BootScriptTablePtr after SmmReadyToLock in InSmm.
101//
102SCRIPT_TABLE_PRIVATE_DATA *mS3BootScriptTableSmmPtr;
103
104EFI_GUID mBootScriptDataGuid = {
105 0xaea6b965, 0xdcf5, 0x4311, { 0xb4, 0xb8, 0xf, 0x12, 0x46, 0x44, 0x94, 0xd2 }
106};
107
108EFI_GUID mBootScriptDataBootTimeGuid = {
109 0xb5af1d7a, 0xb8cf, 0x4eb3, { 0x89, 0x25, 0xa8, 0x20, 0xe1, 0x6b, 0x68, 0x7d }
110};
111
112EFI_GUID mBootScriptTableBaseGuid = {
113 0x1810ab4a, 0x2314, 0x4df6, { 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91 }
114};
115
116EFI_GUID mBootScriptSmmPrivateDataGuid = {
117 0x627ee2da, 0x3bf9, 0x439b, { 0x92, 0x9f, 0x2e, 0xe, 0x6e, 0x9d, 0xba, 0x62 }
118};
119
120EFI_EVENT mEventDxeSmmReadyToLock = NULL;
121VOID *mRegistrationSmmExitBootServices = NULL;
122VOID *mRegistrationSmmLegacyBoot = NULL;
123VOID *mRegistrationSmmReadyToLock = NULL;
124BOOLEAN mS3BootScriptTableAllocated = FALSE;
125BOOLEAN mS3BootScriptTableSmmAllocated = FALSE;
126EFI_SMM_SYSTEM_TABLE2 *mBootScriptSmst = NULL;
127BOOLEAN mS3BootScriptAcpiS3Enable = TRUE;
128
135UINT8 *
137 VOID
138 )
139{
140 UINT8 *S3TableBase;
141 EFI_BOOT_SCRIPT_TERMINATE ScriptTerminate;
142 EFI_BOOT_SCRIPT_TABLE_HEADER *ScriptTableInfo;
143
144 S3TableBase = mS3BootScriptTablePtr->TableBase;
145
146 if (S3TableBase == NULL) {
147 //
148 // the table is not exist
149 //
150 return S3TableBase;
151 }
152
153 //
154 // Append the termination entry.
155 //
156 ScriptTerminate.OpCode = S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE;
157 ScriptTerminate.Length = (UINT8)sizeof (EFI_BOOT_SCRIPT_TERMINATE);
158 CopyMem (mS3BootScriptTablePtr->TableBase + mS3BootScriptTablePtr->TableLength, &ScriptTerminate, sizeof (EFI_BOOT_SCRIPT_TERMINATE));
159 //
160 // fill the table length
161 //
162 ScriptTableInfo = (EFI_BOOT_SCRIPT_TABLE_HEADER *)(mS3BootScriptTablePtr->TableBase);
163 ScriptTableInfo->TableLength = mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE);
164
165 return S3TableBase;
166 //
167 // NOTE: Here we did NOT adjust the mS3BootScriptTablePtr->TableLength to
168 // mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE).
169 // Because maybe after SmmReadyToLock, we still need add entries into the table,
170 // and the entry should be added start before this TERMINATE node.
171 //
172}
173
178VOID
180 VOID
181 )
182{
183 EFI_STATUS Status;
184
185 //
186 // Save whole memory copy into LockBox.
187 // It will be used to restore data at S3 resume.
188 //
189 Status = SaveLockBox (
190 &mBootScriptDataGuid,
191 (VOID *)mS3BootScriptTablePtr->TableBase,
192 EFI_PAGES_TO_SIZE (mS3BootScriptTablePtr->TableMemoryPageNumber)
193 );
194 ASSERT_EFI_ERROR (Status);
195
196 Status = SetLockBoxAttributes (&mBootScriptDataGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
197 ASSERT_EFI_ERROR (Status);
198
199 //
200 // Just need save TableBase.
201 // Do not update other field because they will NOT be used in S3.
202 //
203 Status = SaveLockBox (
204 &mBootScriptTableBaseGuid,
205 (VOID *)&mS3BootScriptTablePtr->TableBase,
206 sizeof (mS3BootScriptTablePtr->TableBase)
207 );
208 ASSERT_EFI_ERROR (Status);
209
210 Status = SetLockBoxAttributes (&mBootScriptTableBaseGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
211 ASSERT_EFI_ERROR (Status);
212}
213
221VOID
222EFIAPI
224 IN EFI_EVENT Event,
225 IN VOID *Context
226 )
227{
228 EFI_STATUS Status;
229 VOID *Interface;
230
231 //
232 // Try to locate it because EfiCreateProtocolNotifyEvent will trigger it once when registration.
233 // Just return if it is not found.
234 //
235 Status = gBS->LocateProtocol (
236 &gEfiDxeSmmReadyToLockProtocolGuid,
237 NULL,
238 &Interface
239 );
240 if (EFI_ERROR (Status)) {
241 return;
242 }
243
244 //
245 // Here we should tell the library that we are entering SmmLocked phase.
246 // and the memory page number occupied by the table should not grow anymore.
247 //
248 if (!mS3BootScriptTablePtr->SmmLocked) {
249 //
250 // Before SmmReadyToLock, we need not write the terminate node when adding a node to boot scipt table
251 // or else, that will impact the performance. However, after SmmReadyToLock, we should append terminate
252 // node on every add to boot script table.
253 //
255 mS3BootScriptTablePtr->SmmLocked = TRUE;
256
257 //
258 // Save BootScript data to lockbox
259 //
261 }
262}
263
275EFIAPI
277 IN CONST EFI_GUID *Protocol,
278 IN VOID *Interface,
279 IN EFI_HANDLE Handle
280 )
281{
282 //
283 // Check if it is already done
284 //
285 if (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr) {
286 return EFI_SUCCESS;
287 }
288
289 //
290 // Last chance to call-out, just make sure SmmLocked is set.
291 //
293
294 //
295 // Save a SMM copy. If TableBase is NOT null, it means SMM copy has been ready, skip copy mem.
296 //
297 if (mS3BootScriptTableSmmPtr->TableBase == NULL) {
298 CopyMem (mS3BootScriptTableSmmPtr, mS3BootScriptTablePtr, sizeof (*mS3BootScriptTablePtr));
299
300 //
301 // Set InSmm, we allow boot script update when InSmm, but not allow boot script outside SMM.
302 // InSmm will only be checked if SmmLocked is TRUE.
303 //
304 mS3BootScriptTableSmmPtr->InSmm = TRUE;
305 }
306
307 //
308 // We should not use ACPI Reserved copy, because it is not safe.
309 //
310 mS3BootScriptTablePtr = mS3BootScriptTableSmmPtr;
311
312 return EFI_SUCCESS;
313}
314
324VOID
326 VOID
327 )
328{
329 EFI_STATUS Status;
330
331 //
332 // ACPI Reserved copy is not safe, restore from BootScriptData LockBox first,
333 // and then save the data to BootScriptDataBootTime LockBox.
334 //
335 Status = RestoreLockBox (
336 &mBootScriptDataGuid,
337 NULL,
338 NULL
339 );
340 ASSERT_EFI_ERROR (Status);
341
342 //
343 // Save BootScriptDataBootTime
344 // It will be used to restore data after back from S3.
345 //
346 Status = SaveLockBox (
347 &mBootScriptDataBootTimeGuid,
348 (VOID *)mS3BootScriptTablePtr->TableBase,
349 mS3BootScriptTablePtr->BootTimeScriptLength
350 );
351 ASSERT_EFI_ERROR (Status);
352}
353
359VOID
361 VOID
362 )
363{
364 EFI_STATUS Status;
365
366 //
367 // Save boot script SMM private data with BackFromS3 = TRUE.
368 //
369 mS3BootScriptTablePtr->BackFromS3 = TRUE;
370 Status = SaveLockBox (
371 &mBootScriptSmmPrivateDataGuid,
372 (VOID *)mS3BootScriptTablePtr,
374 );
375 ASSERT_EFI_ERROR (Status);
376
377 Status = SetLockBoxAttributes (&mBootScriptSmmPrivateDataGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
378 ASSERT_EFI_ERROR (Status);
379
380 //
381 // Set BackFromS3 flag back to FALSE to indicate that now is not back from S3.
382 //
383 mS3BootScriptTablePtr->BackFromS3 = FALSE;
384}
385
397EFIAPI
399 IN CONST EFI_GUID *Protocol,
400 IN VOID *Interface,
401 IN EFI_HANDLE Handle
402 )
403{
404 if (!mS3BootScriptTablePtr->AtRuntime) {
405 mS3BootScriptTablePtr->BootTimeScriptLength = (UINT32)(mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE));
407
408 mS3BootScriptTablePtr->AtRuntime = TRUE;
410 }
411
412 return EFI_SUCCESS;
413}
414
426RETURN_STATUS
427EFIAPI
429 IN EFI_HANDLE ImageHandle,
430 IN EFI_SYSTEM_TABLE *SystemTable
431 )
432{
433 EFI_STATUS Status;
434 SCRIPT_TABLE_PRIVATE_DATA *S3TablePtr;
435 SCRIPT_TABLE_PRIVATE_DATA *S3TableSmmPtr;
436 VOID *Registration;
437 EFI_SMM_BASE2_PROTOCOL *SmmBase2;
438 BOOLEAN InSmm;
440
441 if (!PcdGetBool (PcdAcpiS3Enable)) {
442 mS3BootScriptAcpiS3Enable = FALSE;
443 DEBUG ((DEBUG_INFO, "%a: Skip S3BootScript because ACPI S3 disabled.\n", gEfiCallerBaseName));
444 return RETURN_SUCCESS;
445 }
446
447 S3TablePtr = (SCRIPT_TABLE_PRIVATE_DATA *)(UINTN)PcdGet64 (PcdS3BootScriptTablePrivateDataPtr);
448 //
449 // The Boot script private data is not be initialized. create it
450 //
451 if (S3TablePtr == 0) {
452 Buffer = SIZE_4GB - 1;
453 Status = gBS->AllocatePages (
457 &Buffer
458 );
459 ASSERT_EFI_ERROR (Status);
460 mS3BootScriptTableAllocated = TRUE;
461 S3TablePtr = (VOID *)(UINTN)Buffer;
462
463 Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, (UINT64)(UINTN)S3TablePtr);
464 ASSERT_EFI_ERROR (Status);
465 ZeroMem (S3TablePtr, sizeof (SCRIPT_TABLE_PRIVATE_DATA));
466 //
467 // Create event to notify the library system enter the SmmLocked phase.
468 //
469 mEventDxeSmmReadyToLock = EfiCreateProtocolNotifyEvent (
470 &gEfiDxeSmmReadyToLockProtocolGuid,
471 TPL_CALLBACK,
473 NULL,
474 &Registration
475 );
476 ASSERT (mEventDxeSmmReadyToLock != NULL);
477 }
478
479 mS3BootScriptTablePtr = S3TablePtr;
480
481 //
482 // Get InSmm, we need to register SmmReadyToLock if this library is linked to SMM driver.
483 //
484 Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **)&SmmBase2);
485 if (EFI_ERROR (Status)) {
486 return RETURN_SUCCESS;
487 }
488
489 Status = SmmBase2->InSmm (SmmBase2, &InSmm);
490 if (EFI_ERROR (Status)) {
491 return RETURN_SUCCESS;
492 }
493
494 if (!InSmm) {
495 return RETURN_SUCCESS;
496 }
497
498 //
499 // Good, we are in SMM
500 //
501 Status = SmmBase2->GetSmstLocation (SmmBase2, &mBootScriptSmst);
502 if (EFI_ERROR (Status)) {
503 return RETURN_SUCCESS;
504 }
505
506 S3TableSmmPtr = (SCRIPT_TABLE_PRIVATE_DATA *)(UINTN)PcdGet64 (PcdS3BootScriptTablePrivateSmmDataPtr);
507 //
508 // The Boot script private data in SMM is not be initialized. create it
509 //
510 if (S3TableSmmPtr == 0) {
511 Status = mBootScriptSmst->SmmAllocatePool (
514 (VOID **)&S3TableSmmPtr
515 );
516 ASSERT_EFI_ERROR (Status);
517 mS3BootScriptTableSmmAllocated = TRUE;
518
519 Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64)(UINTN)S3TableSmmPtr);
520 ASSERT_EFI_ERROR (Status);
521 ZeroMem (S3TableSmmPtr, sizeof (SCRIPT_TABLE_PRIVATE_DATA));
522
523 //
524 // Register SmmExitBootServices and SmmLegacyBoot notification.
525 //
526 Status = mBootScriptSmst->SmmRegisterProtocolNotify (
527 &gEdkiiSmmExitBootServicesProtocolGuid,
529 &mRegistrationSmmExitBootServices
530 );
531 ASSERT_EFI_ERROR (Status);
532
533 Status = mBootScriptSmst->SmmRegisterProtocolNotify (
534 &gEdkiiSmmLegacyBootProtocolGuid,
536 &mRegistrationSmmLegacyBoot
537 );
538 ASSERT_EFI_ERROR (Status);
539 }
540
541 mS3BootScriptTableSmmPtr = S3TableSmmPtr;
542
543 //
544 // Register SmmReadyToLock notification.
545 //
546 Status = mBootScriptSmst->SmmRegisterProtocolNotify (
547 &gEfiSmmReadyToLockProtocolGuid,
549 &mRegistrationSmmReadyToLock
550 );
551 ASSERT_EFI_ERROR (Status);
552
553 return RETURN_SUCCESS;
554}
555
569RETURN_STATUS
570EFIAPI
572 IN EFI_HANDLE ImageHandle,
573 IN EFI_SYSTEM_TABLE *SystemTable
574 )
575{
576 EFI_STATUS Status;
577
578 if (!mS3BootScriptAcpiS3Enable) {
579 return RETURN_SUCCESS;
580 }
581
582 DEBUG ((DEBUG_INFO, "%a() in %a module\n", __func__, gEfiCallerBaseName));
583
584 if (mEventDxeSmmReadyToLock != NULL) {
585 //
586 // Close the DxeSmmReadyToLock event.
587 //
588 Status = gBS->CloseEvent (mEventDxeSmmReadyToLock);
589 ASSERT_EFI_ERROR (Status);
590 }
591
592 if (mBootScriptSmst != NULL) {
593 if (mRegistrationSmmExitBootServices != NULL) {
594 //
595 // Unregister SmmExitBootServices notification.
596 //
597 Status = mBootScriptSmst->SmmRegisterProtocolNotify (
598 &gEdkiiSmmExitBootServicesProtocolGuid,
599 NULL,
600 &mRegistrationSmmExitBootServices
601 );
602 ASSERT_EFI_ERROR (Status);
603 }
604
605 if (mRegistrationSmmLegacyBoot != NULL) {
606 //
607 // Unregister SmmLegacyBoot notification.
608 //
609 Status = mBootScriptSmst->SmmRegisterProtocolNotify (
610 &gEdkiiSmmLegacyBootProtocolGuid,
611 NULL,
612 &mRegistrationSmmLegacyBoot
613 );
614 ASSERT_EFI_ERROR (Status);
615 }
616
617 if (mRegistrationSmmReadyToLock != NULL) {
618 //
619 // Unregister SmmReadyToLock notification.
620 //
621 Status = mBootScriptSmst->SmmRegisterProtocolNotify (
622 &gEfiSmmReadyToLockProtocolGuid,
623 NULL,
624 &mRegistrationSmmReadyToLock
625 );
626 ASSERT_EFI_ERROR (Status);
627 }
628 }
629
630 //
631 // Free the resources allocated and set PCDs to 0.
632 //
633 if (mS3BootScriptTableAllocated) {
635 ASSERT_EFI_ERROR (Status);
636 Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, 0);
637 ASSERT_EFI_ERROR (Status);
638 }
639
640 if ((mBootScriptSmst != NULL) && mS3BootScriptTableSmmAllocated) {
641 Status = mBootScriptSmst->SmmFreePool (mS3BootScriptTableSmmPtr);
642 ASSERT_EFI_ERROR (Status);
643 Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, 0);
644 ASSERT_EFI_ERROR (Status);
645 }
646
647 return RETURN_SUCCESS;
648}
649
660UINT8 *
662 UINT8 EntryLength
663 )
664{
665 EFI_PHYSICAL_ADDRESS S3TableBase;
666 EFI_PHYSICAL_ADDRESS NewS3TableBase;
667 UINT8 *NewEntryPtr;
668 UINT32 TableLength;
669 UINT16 PageNumber;
670 EFI_STATUS Status;
671 EFI_BOOT_SCRIPT_TABLE_HEADER *ScriptTableInfo;
672
673 S3TableBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(mS3BootScriptTablePtr->TableBase);
674 if (S3TableBase == 0) {
675 //
676 // The table is not exist. This is the first to add entry.
677 // Allocate ACPI script table space under 4G memory.
678 //
679 S3TableBase = 0xffffffff;
680 Status = gBS->AllocatePages (
683 2 + PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber),
684 (EFI_PHYSICAL_ADDRESS *)&S3TableBase
685 );
686
687 if (EFI_ERROR (Status)) {
688 ASSERT_EFI_ERROR (Status);
689 return 0;
690 }
691
692 //
693 // Fill Table Header
694 //
695 ScriptTableInfo = (EFI_BOOT_SCRIPT_TABLE_HEADER *)(UINTN)S3TableBase;
696 ScriptTableInfo->OpCode = S3_BOOT_SCRIPT_LIB_TABLE_OPCODE;
697 ScriptTableInfo->Length = (UINT8)sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
698 ScriptTableInfo->Version = BOOT_SCRIPT_TABLE_VERSION;
699 ScriptTableInfo->TableLength = 0; // will be calculate at CloseTable
701 mS3BootScriptTablePtr->TableBase = (UINT8 *)(UINTN)S3TableBase;
702 mS3BootScriptTablePtr->TableMemoryPageNumber = (UINT16)(2 + PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber));
703 }
704
705 // Here we do not count the reserved memory for runtime script table.
706 PageNumber = (UINT16)(mS3BootScriptTablePtr->TableMemoryPageNumber - PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber));
707 TableLength = mS3BootScriptTablePtr->TableLength;
708 if (EFI_PAGES_TO_SIZE ((UINTN)PageNumber) < (TableLength + EntryLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE))) {
709 //
710 // The buffer is too small to hold the table, Reallocate the buffer
711 //
712 NewS3TableBase = 0xffffffff;
713 Status = gBS->AllocatePages (
716 2 + PageNumber + PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber),
717 (EFI_PHYSICAL_ADDRESS *)&NewS3TableBase
718 );
719
720 if (EFI_ERROR (Status)) {
721 ASSERT_EFI_ERROR (Status);
722 return 0;
723 }
724
725 CopyMem ((VOID *)(UINTN)NewS3TableBase, (VOID *)(UINTN)S3TableBase, TableLength);
726 gBS->FreePages (S3TableBase, mS3BootScriptTablePtr->TableMemoryPageNumber);
727
728 mS3BootScriptTablePtr->TableBase = (UINT8 *)(UINTN)NewS3TableBase;
729 mS3BootScriptTablePtr->TableMemoryPageNumber = (UINT16)(2 + PageNumber + PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber));
730 }
731
732 //
733 // calculate the the start address for the new entry.
734 //
735 NewEntryPtr = mS3BootScriptTablePtr->TableBase + TableLength;
736
737 //
738 // update the table lenghth
739 //
740 mS3BootScriptTablePtr->TableLength = TableLength + EntryLength;
741
742 //
743 // In the boot time, we will not append the termination entry to the boot script
744 // table until the callers think there is no boot time data that should be added and
745 // it is caller's responsibility to explicit call the CloseTable.
746 //
747 //
748
749 return NewEntryPtr;
750}
751
760UINT8 *
762 UINT8 EntryLength
763 )
764{
765 UINT8 *NewEntryPtr;
766
767 NewEntryPtr = NULL;
768 //
769 // Check if the memory range reserved for S3 Boot Script table is large enough to hold the node.
770 //
771 if ((mS3BootScriptTablePtr->TableLength + EntryLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE)) <= EFI_PAGES_TO_SIZE ((UINTN)(mS3BootScriptTablePtr->TableMemoryPageNumber))) {
772 NewEntryPtr = mS3BootScriptTablePtr->TableBase + mS3BootScriptTablePtr->TableLength;
773 mS3BootScriptTablePtr->TableLength = mS3BootScriptTablePtr->TableLength + EntryLength;
774 //
775 // Append a terminate node on every insert
776 //
778 }
779
780 return (UINT8 *)NewEntryPtr;
781}
782
787VOID
789 VOID
790 )
791{
792 EFI_STATUS Status;
793 UINTN LockBoxLength;
794
795 //
796 // Restore boot time boot script data from LockBox.
797 //
798 LockBoxLength = mS3BootScriptTablePtr->BootTimeScriptLength;
799 Status = RestoreLockBox (
800 &mBootScriptDataBootTimeGuid,
801 (VOID *)mS3BootScriptTablePtr->TableBase,
802 &LockBoxLength
803 );
804 ASSERT_EFI_ERROR (Status);
805
806 //
807 // Update the data to BootScriptData LockBox.
808 //
809 Status = UpdateLockBox (
810 &mBootScriptDataGuid,
811 0,
812 (VOID *)mS3BootScriptTablePtr->TableBase,
813 LockBoxLength
814 );
815 ASSERT_EFI_ERROR (Status);
816
817 //
818 // Update TableLength.
819 //
820 mS3BootScriptTablePtr->TableLength = (UINT32)(mS3BootScriptTablePtr->BootTimeScriptLength - sizeof (EFI_BOOT_SCRIPT_TERMINATE));
821}
822
830UINT8 *
832 UINT8 EntryLength
833 )
834{
835 UINT8 *NewEntryPtr;
836
837 if (!mS3BootScriptAcpiS3Enable) {
838 return NULL;
839 }
840
841 if (mS3BootScriptTablePtr->SmmLocked) {
842 //
843 // We need check InSmm, because after SmmReadyToLock, only SMM driver is allowed to write boot script.
844 //
845 if (!mS3BootScriptTablePtr->InSmm) {
846 //
847 // Add DEBUG ERROR, so that we can find it after SmmReadyToLock.
848 // Do not use ASSERT, because we may have test to invoke this interface.
849 //
850 DEBUG ((DEBUG_ERROR, "FATAL ERROR: Set boot script outside SMM after SmmReadyToLock!!!\n"));
851 return NULL;
852 }
853
854 if (mS3BootScriptTablePtr->BackFromS3) {
855 //
856 // Back from S3, restore boot time boot script data from LockBox
857 // and set BackFromS3 flag back to FALSE.
858 //
860 mS3BootScriptTablePtr->BackFromS3 = FALSE;
861 }
862
863 NewEntryPtr = S3BootScriptGetRuntimeEntryAddAddress (EntryLength);
864 } else {
865 NewEntryPtr = S3BootScriptGetBootTimeEntryAddAddress (EntryLength);
866 }
867
868 return NewEntryPtr;
869}
870
877VOID
879 IN UINT8 *Script
880 )
881{
882 EFI_STATUS Status;
883 UINT32 ScriptOffset;
884 UINT32 TotalScriptLength;
885
886 if (!mS3BootScriptTablePtr->SmmLocked || !mS3BootScriptTablePtr->InSmm) {
887 //
888 // If it is not after SmmReadyToLock in SMM,
889 // just return.
890 //
891 return;
892 }
893
894 ScriptOffset = (UINT32)(Script - mS3BootScriptTablePtr->TableBase);
895
896 TotalScriptLength = (UINT32)(mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE));
897
898 //
899 // Update BootScriptData
900 // So in S3 resume, the data can be restored correctly.
901 //
902 Status = UpdateLockBox (
903 &mBootScriptDataGuid,
904 ScriptOffset,
905 (VOID *)((UINTN)mS3BootScriptTablePtr->TableBase + ScriptOffset),
906 TotalScriptLength - ScriptOffset
907 );
908 ASSERT_EFI_ERROR (Status);
909
910 //
911 // Now the length field is updated, need sync to lockbox.
912 // So at S3 resume, the data can be restored correctly.
913 //
914 Status = UpdateLockBox (
915 &mBootScriptDataGuid,
917 &TotalScriptLength,
918 sizeof (TotalScriptLength)
919 );
920 ASSERT_EFI_ERROR (Status);
921}
922
948UINT8 *
949EFIAPI
951 VOID
952 )
953{
954 UINT8 *S3TableBase;
955 UINT32 TableLength;
956 UINT8 *Buffer;
957 EFI_STATUS Status;
958 EFI_BOOT_SCRIPT_TABLE_HEADER *ScriptTableInfo;
959
960 S3TableBase = mS3BootScriptTablePtr->TableBase;
961 if (S3TableBase == 0) {
962 return 0;
963 }
964
965 //
966 // Append the termination record the S3 boot script table
967 //
969 TableLength = mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE);
970 //
971 // Allocate the buffer and copy the boot script to the buffer.
972 //
973 Status = gBS->AllocatePool (
975 (UINTN)TableLength,
976 (VOID **)&Buffer
977 );
978 if (EFI_ERROR (Status)) {
979 return 0;
980 }
981
982 CopyMem (Buffer, S3TableBase, TableLength);
983
984 //
985 // Destroy the table maintained by the library so that the next write operation
986 // will write the record to the first entry of the table.
987 //
988 // Fill the table header.
989 ScriptTableInfo = (EFI_BOOT_SCRIPT_TABLE_HEADER *)S3TableBase;
990 ScriptTableInfo->OpCode = S3_BOOT_SCRIPT_LIB_TABLE_OPCODE;
991 ScriptTableInfo->Length = (UINT8)sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
992 ScriptTableInfo->TableLength = 0; // will be calculate at close the table
993
995 return Buffer;
996}
997
1009RETURN_STATUS
1010EFIAPI
1013 IN UINT64 Address,
1014 IN UINTN Count,
1015 IN VOID *Buffer
1016 )
1017
1018{
1019 UINT8 Length;
1020 UINT8 *Script;
1021 UINT8 WidthInByte;
1023
1024 if (!mS3BootScriptAcpiS3Enable) {
1025 return RETURN_SUCCESS;
1026 }
1027
1028 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1029
1030 //
1031 // Truncation check
1032 //
1033 if ((Count > MAX_UINT8) ||
1034 (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_IO_WRITE)))
1035 {
1037 }
1038
1039 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_WRITE) + (WidthInByte * Count));
1040
1041 Script = S3BootScriptGetEntryAddAddress (Length);
1042 if (Script == NULL) {
1044 }
1045
1046 //
1047 // save script data
1048 //
1049 ScriptIoWrite.OpCode = EFI_BOOT_SCRIPT_IO_WRITE_OPCODE;
1050 ScriptIoWrite.Length = Length;
1051 ScriptIoWrite.Width = Width;
1052 ScriptIoWrite.Address = Address;
1053 ScriptIoWrite.Count = (UINT32)Count;
1054 CopyMem ((VOID *)Script, (VOID *)&ScriptIoWrite, sizeof (EFI_BOOT_SCRIPT_IO_WRITE));
1055 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_WRITE)), Buffer, WidthInByte * Count);
1056
1057 SyncBootScript (Script);
1058
1059 return RETURN_SUCCESS;
1060}
1061
1073RETURN_STATUS
1074EFIAPI
1077 IN UINT64 Address,
1078 IN VOID *Data,
1079 IN VOID *DataMask
1080 )
1081{
1082 UINT8 Length;
1083 UINT8 *Script;
1084 UINT8 WidthInByte;
1085 EFI_BOOT_SCRIPT_IO_READ_WRITE ScriptIoReadWrite;
1086
1087 if (!mS3BootScriptAcpiS3Enable) {
1088 return RETURN_SUCCESS;
1089 }
1090
1091 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1092 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE) + (WidthInByte * 2));
1093
1094 Script = S3BootScriptGetEntryAddAddress (Length);
1095 if (Script == NULL) {
1097 }
1098
1099 //
1100 // Build script data
1101 //
1102 ScriptIoReadWrite.OpCode = EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE;
1103 ScriptIoReadWrite.Length = Length;
1104 ScriptIoReadWrite.Width = Width;
1105 ScriptIoReadWrite.Address = Address;
1106
1107 CopyMem ((VOID *)Script, (VOID *)&ScriptIoReadWrite, sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE));
1108 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE)), Data, WidthInByte);
1109 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE) + WidthInByte), DataMask, WidthInByte);
1110
1111 SyncBootScript (Script);
1112
1113 return RETURN_SUCCESS;
1114}
1115
1127RETURN_STATUS
1128EFIAPI
1131 IN UINT64 Address,
1132 IN UINTN Count,
1133 IN VOID *Buffer
1134 )
1135{
1136 UINT8 Length;
1137 UINT8 *Script;
1138 UINT8 WidthInByte;
1139 EFI_BOOT_SCRIPT_MEM_WRITE ScriptMemWrite;
1140
1141 if (!mS3BootScriptAcpiS3Enable) {
1142 return RETURN_SUCCESS;
1143 }
1144
1145 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1146
1147 //
1148 // Truncation check
1149 //
1150 if ((Count > MAX_UINT8) ||
1151 (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_MEM_WRITE)))
1152 {
1154 }
1155
1156 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_MEM_WRITE) + (WidthInByte * Count));
1157
1158 Script = S3BootScriptGetEntryAddAddress (Length);
1159 if (Script == NULL) {
1161 }
1162
1163 //
1164 // Build script data
1165 //
1166 ScriptMemWrite.OpCode = EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE;
1167 ScriptMemWrite.Length = Length;
1168 ScriptMemWrite.Width = Width;
1169 ScriptMemWrite.Address = Address;
1170 ScriptMemWrite.Count = (UINT32)Count;
1171
1172 CopyMem ((VOID *)Script, (VOID *)&ScriptMemWrite, sizeof (EFI_BOOT_SCRIPT_MEM_WRITE));
1173 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_WRITE)), Buffer, WidthInByte * Count);
1174
1175 SyncBootScript (Script);
1176
1177 return RETURN_SUCCESS;
1178}
1179
1191RETURN_STATUS
1192EFIAPI
1195 IN UINT64 Address,
1196 IN VOID *Data,
1197 IN VOID *DataMask
1198 )
1199{
1200 UINT8 Length;
1201 UINT8 *Script;
1202 UINT8 WidthInByte;
1203 EFI_BOOT_SCRIPT_MEM_READ_WRITE ScriptMemReadWrite;
1204
1205 if (!mS3BootScriptAcpiS3Enable) {
1206 return RETURN_SUCCESS;
1207 }
1208
1209 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1210 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE) + (WidthInByte * 2));
1211
1212 Script = S3BootScriptGetEntryAddAddress (Length);
1213 if (Script == NULL) {
1215 }
1216
1217 //
1218 // Build script data
1219 //
1220 ScriptMemReadWrite.OpCode = EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE;
1221 ScriptMemReadWrite.Length = Length;
1222 ScriptMemReadWrite.Width = Width;
1223 ScriptMemReadWrite.Address = Address;
1224
1225 CopyMem ((VOID *)Script, (VOID *)&ScriptMemReadWrite, sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE));
1226 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE)), Data, WidthInByte);
1227 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE) + WidthInByte), DataMask, WidthInByte);
1228
1229 SyncBootScript (Script);
1230
1231 return RETURN_SUCCESS;
1232}
1233
1247RETURN_STATUS
1248EFIAPI
1251 IN UINT64 Address,
1252 IN UINTN Count,
1253 IN VOID *Buffer
1254 )
1255{
1256 UINT8 Length;
1257 UINT8 *Script;
1258 UINT8 WidthInByte;
1259 EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE ScriptPciWrite;
1260
1261 if (!mS3BootScriptAcpiS3Enable) {
1262 return RETURN_SUCCESS;
1263 }
1264
1265 if ((Width == S3BootScriptWidthUint64) ||
1266 (Width == S3BootScriptWidthFifoUint64) ||
1267 (Width == S3BootScriptWidthFillUint64))
1268 {
1269 return EFI_INVALID_PARAMETER;
1270 }
1271
1272 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1273
1274 //
1275 // Truncation check
1276 //
1277 if ((Count > MAX_UINT8) ||
1278 (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)))
1279 {
1281 }
1282
1283 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) + (WidthInByte * Count));
1284
1285 Script = S3BootScriptGetEntryAddAddress (Length);
1286 if (Script == NULL) {
1288 }
1289
1290 //
1291 // Build script data
1292 //
1293 ScriptPciWrite.OpCode = EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE;
1294 ScriptPciWrite.Length = Length;
1295 ScriptPciWrite.Width = Width;
1296 ScriptPciWrite.Address = Address;
1297 ScriptPciWrite.Count = (UINT32)Count;
1298
1299 CopyMem ((VOID *)Script, (VOID *)&ScriptPciWrite, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));
1300 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)), Buffer, WidthInByte * Count);
1301
1302 SyncBootScript (Script);
1303
1304 return RETURN_SUCCESS;
1305}
1306
1320RETURN_STATUS
1321EFIAPI
1324 IN UINT64 Address,
1325 IN VOID *Data,
1326 IN VOID *DataMask
1327 )
1328{
1329 UINT8 Length;
1330 UINT8 *Script;
1331 UINT8 WidthInByte;
1332 EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE ScriptPciReadWrite;
1333
1334 if (!mS3BootScriptAcpiS3Enable) {
1335 return RETURN_SUCCESS;
1336 }
1337
1338 if ((Width == S3BootScriptWidthUint64) ||
1339 (Width == S3BootScriptWidthFifoUint64) ||
1340 (Width == S3BootScriptWidthFillUint64))
1341 {
1342 return EFI_INVALID_PARAMETER;
1343 }
1344
1345 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1346 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE) + (WidthInByte * 2));
1347
1348 Script = S3BootScriptGetEntryAddAddress (Length);
1349 if (Script == NULL) {
1351 }
1352
1353 //
1354 // Build script data
1355 //
1356 ScriptPciReadWrite.OpCode = EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE;
1357 ScriptPciReadWrite.Length = Length;
1358 ScriptPciReadWrite.Width = Width;
1359 ScriptPciReadWrite.Address = Address;
1360
1361 CopyMem ((VOID *)Script, (VOID *)&ScriptPciReadWrite, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE));
1362 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE)), Data, WidthInByte);
1363 CopyMem (
1364 (VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE) + WidthInByte),
1365 DataMask,
1366 WidthInByte
1367 );
1368
1369 SyncBootScript (Script);
1370
1371 return RETURN_SUCCESS;
1372}
1373
1388RETURN_STATUS
1389EFIAPI
1392 IN UINT16 Segment,
1393 IN UINT64 Address,
1394 IN UINTN Count,
1395 IN VOID *Buffer
1396 )
1397{
1398 UINT8 Length;
1399 UINT8 *Script;
1400 UINT8 WidthInByte;
1401 EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE ScriptPciWrite2;
1402
1403 if (!mS3BootScriptAcpiS3Enable) {
1404 return RETURN_SUCCESS;
1405 }
1406
1407 if ((Width == S3BootScriptWidthUint64) ||
1408 (Width == S3BootScriptWidthFifoUint64) ||
1409 (Width == S3BootScriptWidthFillUint64))
1410 {
1411 return EFI_INVALID_PARAMETER;
1412 }
1413
1414 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1415
1416 //
1417 // Truncation check
1418 //
1419 if ((Count > MAX_UINT8) ||
1420 (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE)))
1421 {
1423 }
1424
1425 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE) + (WidthInByte * Count));
1426
1427 Script = S3BootScriptGetEntryAddAddress (Length);
1428 if (Script == NULL) {
1430 }
1431
1432 //
1433 // Build script data
1434 //
1435 ScriptPciWrite2.OpCode = EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE;
1436 ScriptPciWrite2.Length = Length;
1437 ScriptPciWrite2.Width = Width;
1438 ScriptPciWrite2.Address = Address;
1439 ScriptPciWrite2.Segment = Segment;
1440 ScriptPciWrite2.Count = (UINT32)Count;
1441
1442 CopyMem ((VOID *)Script, (VOID *)&ScriptPciWrite2, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));
1443 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE)), Buffer, WidthInByte * Count);
1444
1445 SyncBootScript (Script);
1446
1447 return RETURN_SUCCESS;
1448}
1449
1464RETURN_STATUS
1465EFIAPI
1468 IN UINT16 Segment,
1469 IN UINT64 Address,
1470 IN VOID *Data,
1471 IN VOID *DataMask
1472 )
1473{
1474 UINT8 Length;
1475 UINT8 *Script;
1476 UINT8 WidthInByte;
1477 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE ScriptPciReadWrite2;
1478
1479 if (!mS3BootScriptAcpiS3Enable) {
1480 return RETURN_SUCCESS;
1481 }
1482
1483 if ((Width == S3BootScriptWidthUint64) ||
1484 (Width == S3BootScriptWidthFifoUint64) ||
1485 (Width == S3BootScriptWidthFillUint64))
1486 {
1487 return EFI_INVALID_PARAMETER;
1488 }
1489
1490 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1491 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE) + (WidthInByte * 2));
1492
1493 Script = S3BootScriptGetEntryAddAddress (Length);
1494 if (Script == NULL) {
1496 }
1497
1498 //
1499 // Build script data
1500 //
1501 ScriptPciReadWrite2.OpCode = EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE;
1502 ScriptPciReadWrite2.Length = Length;
1503 ScriptPciReadWrite2.Width = Width;
1504 ScriptPciReadWrite2.Segment = Segment;
1505 ScriptPciReadWrite2.Address = Address;
1506
1507 CopyMem ((VOID *)Script, (VOID *)&ScriptPciReadWrite2, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE));
1508 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE)), Data, WidthInByte);
1509 CopyMem (
1510 (VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE) + WidthInByte),
1511 DataMask,
1512 WidthInByte
1513 );
1514
1515 SyncBootScript (Script);
1516
1517 return RETURN_SUCCESS;
1518}
1519
1554 IN UINTN SmBusAddress,
1555 IN EFI_SMBUS_OPERATION Operation,
1556 IN OUT UINTN *Length,
1557 IN VOID *Buffer
1558 )
1559{
1560 EFI_STATUS Status;
1561 UINTN RequiredLen;
1563 BOOLEAN PecCheck;
1564
1565 Command = SMBUS_LIB_COMMAND (SmBusAddress);
1566 PecCheck = SMBUS_LIB_PEC (SmBusAddress);
1567 //
1568 // Set default value to be 2:
1569 // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall.
1570 //
1571 RequiredLen = 2;
1572 Status = EFI_SUCCESS;
1573 switch (Operation) {
1574 case EfiSmbusQuickRead:
1575 case EfiSmbusQuickWrite:
1576 if (PecCheck || (Command != 0)) {
1577 return EFI_UNSUPPORTED;
1578 }
1579
1580 break;
1581 case EfiSmbusReceiveByte:
1582 case EfiSmbusSendByte:
1583 if (Command != 0) {
1584 return EFI_UNSUPPORTED;
1585 }
1586
1587 //
1588 // Cascade to check length parameter.
1589 //
1590 case EfiSmbusReadByte:
1591 case EfiSmbusWriteByte:
1592 RequiredLen = 1;
1593 //
1594 // Cascade to check length parameter.
1595 //
1596 case EfiSmbusReadWord:
1597 case EfiSmbusWriteWord:
1598 case EfiSmbusProcessCall:
1599 if ((Buffer == NULL) || (Length == NULL)) {
1600 return EFI_INVALID_PARAMETER;
1601 } else if (*Length < RequiredLen) {
1602 Status = EFI_BUFFER_TOO_SMALL;
1603 }
1604
1605 *Length = RequiredLen;
1606 break;
1607 case EfiSmbusReadBlock:
1608 case EfiSmbusWriteBlock:
1609 case EfiSmbusBWBRProcessCall:
1610 if ((Buffer == NULL) ||
1611 (Length == NULL) ||
1612 (*Length < MIN_SMBUS_BLOCK_LEN) ||
1613 (*Length > MAX_SMBUS_BLOCK_LEN))
1614 {
1615 return EFI_INVALID_PARAMETER;
1616 }
1617
1618 break;
1619 default:
1620 return EFI_INVALID_PARAMETER;
1621 }
1622
1623 return Status;
1624}
1625
1638RETURN_STATUS
1639EFIAPI
1641 IN UINTN SmBusAddress,
1642 IN EFI_SMBUS_OPERATION Operation,
1643 IN UINTN *Length,
1644 IN VOID *Buffer
1645 )
1646{
1647 EFI_STATUS Status;
1648 UINTN BufferLength;
1649 UINT8 DataSize;
1650 UINT8 *Script;
1651 EFI_BOOT_SCRIPT_SMBUS_EXECUTE ScriptSmbusExecute;
1652
1653 if (!mS3BootScriptAcpiS3Enable) {
1654 return RETURN_SUCCESS;
1655 }
1656
1657 if (Length == NULL) {
1658 BufferLength = 0;
1659 } else {
1660 BufferLength = *Length;
1661 }
1662
1663 Status = CheckParameters (SmBusAddress, Operation, &BufferLength, Buffer);
1664 if (EFI_ERROR (Status)) {
1665 return Status;
1666 }
1667
1668 //
1669 // Truncation check
1670 //
1671 if (BufferLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)) {
1673 }
1674
1675 DataSize = (UINT8)(sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE) + BufferLength);
1676
1677 Script = S3BootScriptGetEntryAddAddress (DataSize);
1678 if (Script == NULL) {
1680 }
1681
1682 //
1683 // Build script data
1684 //
1685 ScriptSmbusExecute.OpCode = EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE;
1686 ScriptSmbusExecute.Length = DataSize;
1687 ScriptSmbusExecute.SmBusAddress = (UINT64)SmBusAddress;
1688 ScriptSmbusExecute.Operation = Operation;
1689 ScriptSmbusExecute.DataSize = (UINT32)BufferLength;
1690
1691 CopyMem ((VOID *)Script, (VOID *)&ScriptSmbusExecute, sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE));
1692 CopyMem (
1693 (VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)),
1694 Buffer,
1695 BufferLength
1696 );
1697
1698 SyncBootScript (Script);
1699
1700 return RETURN_SUCCESS;
1701}
1702
1711RETURN_STATUS
1712EFIAPI
1714 IN UINTN Duration
1715 )
1716{
1717 UINT8 Length;
1718 UINT8 *Script;
1719 EFI_BOOT_SCRIPT_STALL ScriptStall;
1720
1721 if (!mS3BootScriptAcpiS3Enable) {
1722 return RETURN_SUCCESS;
1723 }
1724
1725 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_STALL));
1726
1727 Script = S3BootScriptGetEntryAddAddress (Length);
1728 if (Script == NULL) {
1730 }
1731
1732 //
1733 // Build script data
1734 //
1735 ScriptStall.OpCode = EFI_BOOT_SCRIPT_STALL_OPCODE;
1736 ScriptStall.Length = Length;
1737 ScriptStall.Duration = Duration;
1738
1739 CopyMem ((VOID *)Script, (VOID *)&ScriptStall, sizeof (EFI_BOOT_SCRIPT_STALL));
1740
1741 SyncBootScript (Script);
1742
1743 return RETURN_SUCCESS;
1744}
1745
1755RETURN_STATUS
1756EFIAPI
1758 IN VOID *EntryPoint,
1759 IN VOID *Context
1760 )
1761{
1762 UINT8 Length;
1763 UINT8 *Script;
1764 EFI_BOOT_SCRIPT_DISPATCH_2 ScriptDispatch2;
1765
1766 if (!mS3BootScriptAcpiS3Enable) {
1767 return RETURN_SUCCESS;
1768 }
1769
1770 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_DISPATCH_2));
1771
1772 Script = S3BootScriptGetEntryAddAddress (Length);
1773 if (Script == NULL) {
1775 }
1776
1777 //
1778 // Build script data
1779 //
1780 ScriptDispatch2.OpCode = EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE;
1781 ScriptDispatch2.Length = Length;
1782 ScriptDispatch2.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint;
1783 ScriptDispatch2.Context = (EFI_PHYSICAL_ADDRESS)(UINTN)Context;
1784
1785 CopyMem ((VOID *)Script, (VOID *)&ScriptDispatch2, sizeof (EFI_BOOT_SCRIPT_DISPATCH_2));
1786
1787 SyncBootScript (Script);
1788
1789 return RETURN_SUCCESS;
1790}
1791
1812RETURN_STATUS
1813EFIAPI
1816 IN UINT64 Address,
1817 IN VOID *BitMask,
1818 IN VOID *BitValue,
1819 IN UINTN Duration,
1820 IN UINT64 LoopTimes
1821 )
1822{
1823 UINT8 Length;
1824 UINT8 *Script;
1825 UINT8 WidthInByte;
1826 EFI_BOOT_SCRIPT_MEM_POLL ScriptMemPoll;
1827
1828 if (!mS3BootScriptAcpiS3Enable) {
1829 return RETURN_SUCCESS;
1830 }
1831
1832 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
1833
1834 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_MEM_POLL) + (WidthInByte * 2));
1835
1836 Script = S3BootScriptGetEntryAddAddress (Length);
1837 if (Script == NULL) {
1839 }
1840
1841 //
1842 // Build script data
1843 //
1844 ScriptMemPoll.OpCode = EFI_BOOT_SCRIPT_MEM_POLL_OPCODE;
1845 ScriptMemPoll.Length = Length;
1846 ScriptMemPoll.Width = Width;
1847 ScriptMemPoll.Address = Address;
1848 ScriptMemPoll.Duration = Duration;
1849 ScriptMemPoll.LoopTimes = LoopTimes;
1850
1851 CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_POLL)), BitValue, WidthInByte);
1852 CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_POLL) + WidthInByte), BitMask, WidthInByte);
1853 CopyMem ((VOID *)Script, (VOID *)&ScriptMemPoll, sizeof (EFI_BOOT_SCRIPT_MEM_POLL));
1854
1855 SyncBootScript (Script);
1856
1857 return RETURN_SUCCESS;
1858}
1859
1871RETURN_STATUS
1872EFIAPI
1874 IN UINT32 InformationLength,
1875 IN VOID *Information
1876 )
1877{
1878 UINT8 Length;
1879 UINT8 *Script;
1880 EFI_BOOT_SCRIPT_INFORMATION ScriptInformation;
1881
1882 if (!mS3BootScriptAcpiS3Enable) {
1883 return RETURN_SUCCESS;
1884 }
1885
1886 //
1887 // Truncation check
1888 //
1889 if (InformationLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_INFORMATION)) {
1891 }
1892
1893 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_INFORMATION) + InformationLength);
1894
1895 Script = S3BootScriptGetEntryAddAddress (Length);
1896 if (Script == NULL) {
1898 }
1899
1900 //
1901 // Build script data
1902 //
1903 ScriptInformation.OpCode = EFI_BOOT_SCRIPT_INFORMATION_OPCODE;
1904 ScriptInformation.Length = Length;
1905
1906 ScriptInformation.InformationLength = InformationLength;
1907
1908 CopyMem ((VOID *)Script, (VOID *)&ScriptInformation, sizeof (EFI_BOOT_SCRIPT_INFORMATION));
1909 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION)), (VOID *)Information, (UINTN)InformationLength);
1910
1911 SyncBootScript (Script);
1912
1913 return RETURN_SUCCESS;
1914}
1915
1926RETURN_STATUS
1927EFIAPI
1929 IN CONST CHAR8 *String
1930 )
1931{
1933 (UINT32)AsciiStrLen (String) + 1,
1934 (VOID *)String
1935 );
1936}
1937
1946RETURN_STATUS
1947EFIAPI
1949 IN VOID *EntryPoint
1950 )
1951{
1952 UINT8 Length;
1953 UINT8 *Script;
1954 EFI_BOOT_SCRIPT_DISPATCH ScriptDispatch;
1955
1956 if (!mS3BootScriptAcpiS3Enable) {
1957 return RETURN_SUCCESS;
1958 }
1959
1960 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_DISPATCH));
1961
1962 Script = S3BootScriptGetEntryAddAddress (Length);
1963 if (Script == NULL) {
1965 }
1966
1967 //
1968 // Build script data
1969 //
1970 ScriptDispatch.OpCode = EFI_BOOT_SCRIPT_DISPATCH_OPCODE;
1971 ScriptDispatch.Length = Length;
1972 ScriptDispatch.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint;
1973
1974 CopyMem ((VOID *)Script, (VOID *)&ScriptDispatch, sizeof (EFI_BOOT_SCRIPT_DISPATCH));
1975
1976 SyncBootScript (Script);
1977
1978 return RETURN_SUCCESS;
1979}
1980
1997RETURN_STATUS
1998EFIAPI
2001 IN UINT64 Address,
2002 IN VOID *Data,
2003 IN VOID *DataMask,
2004 IN UINT64 Delay
2005 )
2006{
2007 UINT8 WidthInByte;
2008 UINT8 *Script;
2009 UINT8 Length;
2010 EFI_BOOT_SCRIPT_IO_POLL ScriptIoPoll;
2011
2012 if (!mS3BootScriptAcpiS3Enable) {
2013 return RETURN_SUCCESS;
2014 }
2015
2016 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
2017 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_POLL) + (WidthInByte * 2));
2018
2019 Script = S3BootScriptGetEntryAddAddress (Length);
2020 if (Script == NULL) {
2022 }
2023
2024 //
2025 // Build script data
2026 //
2027 ScriptIoPoll.OpCode = EFI_BOOT_SCRIPT_IO_POLL_OPCODE;
2028 ScriptIoPoll.Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_POLL) + (WidthInByte * 2));
2029 ScriptIoPoll.Width = Width;
2030 ScriptIoPoll.Address = Address;
2031 ScriptIoPoll.Delay = Delay;
2032
2033 CopyMem ((VOID *)Script, (VOID *)&ScriptIoPoll, sizeof (EFI_BOOT_SCRIPT_IO_POLL));
2034 CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_POLL)), Data, WidthInByte);
2035 CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_POLL) + WidthInByte), DataMask, WidthInByte);
2036
2037 SyncBootScript (Script);
2038
2039 return RETURN_SUCCESS;
2040}
2041
2059RETURN_STATUS
2060EFIAPI
2063 IN UINT64 Address,
2064 IN VOID *Data,
2065 IN VOID *DataMask,
2066 IN UINT64 Delay
2067 )
2068{
2069 UINT8 *Script;
2070 UINT8 WidthInByte;
2071 UINT8 Length;
2072 EFI_BOOT_SCRIPT_PCI_CONFIG_POLL ScriptPciPoll;
2073
2074 if (!mS3BootScriptAcpiS3Enable) {
2075 return RETURN_SUCCESS;
2076 }
2077
2078 if ((Width == S3BootScriptWidthUint64) ||
2079 (Width == S3BootScriptWidthFifoUint64) ||
2080 (Width == S3BootScriptWidthFillUint64))
2081 {
2082 return EFI_INVALID_PARAMETER;
2083 }
2084
2085 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
2086 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + (WidthInByte * 2));
2087
2088 Script = S3BootScriptGetEntryAddAddress (Length);
2089 if (Script == NULL) {
2091 }
2092
2093 //
2094 // Build script data
2095 //
2096 ScriptPciPoll.OpCode = EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE;
2097 ScriptPciPoll.Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + (WidthInByte * 2));
2098 ScriptPciPoll.Width = Width;
2099 ScriptPciPoll.Address = Address;
2100 ScriptPciPoll.Delay = Delay;
2101
2102 CopyMem ((VOID *)Script, (VOID *)&ScriptPciPoll, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL));
2103 CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL)), Data, WidthInByte);
2104 CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + WidthInByte), DataMask, WidthInByte);
2105
2106 SyncBootScript (Script);
2107
2108 return RETURN_SUCCESS;
2109}
2110
2129RETURN_STATUS
2130EFIAPI
2133 IN UINT16 Segment,
2134 IN UINT64 Address,
2135 IN VOID *Data,
2136 IN VOID *DataMask,
2137 IN UINT64 Delay
2138 )
2139{
2140 UINT8 WidthInByte;
2141 UINT8 *Script;
2142 UINT8 Length;
2143 EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL ScriptPci2Poll;
2144
2145 if (!mS3BootScriptAcpiS3Enable) {
2146 return RETURN_SUCCESS;
2147 }
2148
2149 if ((Width == S3BootScriptWidthUint64) ||
2150 (Width == S3BootScriptWidthFifoUint64) ||
2151 (Width == S3BootScriptWidthFillUint64))
2152 {
2153 return EFI_INVALID_PARAMETER;
2154 }
2155
2156 WidthInByte = (UINT8)(0x01 << (Width & 0x03));
2157 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + (WidthInByte * 2));
2158
2159 Script = S3BootScriptGetEntryAddAddress (Length);
2160 if (Script == NULL) {
2162 }
2163
2164 //
2165 // Build script data
2166 //
2167 ScriptPci2Poll.OpCode = EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE;
2168 ScriptPci2Poll.Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + (WidthInByte * 2));
2169 ScriptPci2Poll.Width = Width;
2170 ScriptPci2Poll.Segment = Segment;
2171 ScriptPci2Poll.Address = Address;
2172 ScriptPci2Poll.Delay = Delay;
2173
2174 CopyMem ((VOID *)Script, (VOID *)&ScriptPci2Poll, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL));
2175 CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL)), Data, WidthInByte);
2176 CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + WidthInByte), DataMask, WidthInByte);
2177
2178 SyncBootScript (Script);
2179
2180 return RETURN_SUCCESS;
2181}
2182
2193VOID
2195 IN UINT8 EntryLength,
2196 IN VOID *Position OPTIONAL,
2197 IN BOOLEAN BeforeOrAfter OPTIONAL,
2198 OUT UINT8 **Script
2199 )
2200{
2201 UINTN TableLength;
2202 UINT8 *S3TableBase;
2203 UINTN PositionOffset;
2204 EFI_BOOT_SCRIPT_COMMON_HEADER ScriptHeader;
2205
2206 //
2207 // The entry inserting to table is already added to the end of the table
2208 //
2209 TableLength = mS3BootScriptTablePtr->TableLength - EntryLength;
2210 S3TableBase = mS3BootScriptTablePtr->TableBase;
2211 //
2212 // calculate the Position offset
2213 //
2214 if (Position != NULL) {
2215 PositionOffset = (UINTN)Position - (UINTN)S3TableBase;
2216
2217 //
2218 // If the BeforeOrAfter is FALSE, that means to insert the node right after the node.
2219 //
2220 if (!BeforeOrAfter) {
2221 CopyMem ((VOID *)&ScriptHeader, Position, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));
2222 PositionOffset += (ScriptHeader.Length);
2223 }
2224
2225 //
2226 // Insert the node before the adjusted Position
2227 //
2228 CopyMem (S3TableBase+PositionOffset+EntryLength, S3TableBase+PositionOffset, TableLength - PositionOffset);
2229 //
2230 // calculate the the start address for the new entry.
2231 //
2232 *Script = S3TableBase + PositionOffset;
2233 } else {
2234 if (!BeforeOrAfter) {
2235 //
2236 // Insert the node to the end of the table
2237 //
2238 *Script = S3TableBase + TableLength;
2239 } else {
2240 //
2241 // Insert the node to the beginning of the table
2242 //
2243 PositionOffset = (UINTN)sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
2244 CopyMem (S3TableBase+PositionOffset+EntryLength, S3TableBase+PositionOffset, TableLength - PositionOffset);
2245 *Script = S3TableBase + PositionOffset;
2246 }
2247 }
2248}
2249
2265RETURN_STATUS
2266EFIAPI
2268 IN BOOLEAN BeforeOrAfter,
2269 IN OUT VOID **Position OPTIONAL
2270 )
2271{
2272 UINT8 *Script;
2273 VOID *TempPosition;
2274 UINTN StartAddress;
2275 UINT32 TableLength;
2276 EFI_BOOT_SCRIPT_COMMON_HEADER ScriptHeader;
2277 BOOLEAN ValidatePosition;
2278 UINT8 *LastOpcode;
2279 UINT8 TempBootScriptEntry[BOOT_SCRIPT_NODE_MAX_LENGTH];
2280
2281 if (!mS3BootScriptAcpiS3Enable) {
2282 return RETURN_SUCCESS;
2283 }
2284
2285 ValidatePosition = FALSE;
2286 TempPosition = (Position == NULL) ? NULL : (*Position);
2287
2288 //
2289 // Check that the script is initialized and synced without adding an entry to the script.
2290 //
2291 Script = S3BootScriptGetEntryAddAddress (0);
2292 if (Script == NULL) {
2294 }
2295
2296 Script = mS3BootScriptTablePtr->TableBase;
2297
2298 StartAddress = (UINTN)Script;
2299 TableLength = mS3BootScriptTablePtr->TableLength;
2300 Script = Script + sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
2301 LastOpcode = Script;
2302 //
2303 // Find the last boot Script Entry which is not the terminate node
2304 //
2305 while ((UINTN)Script < (UINTN)(StartAddress + TableLength)) {
2306 CopyMem ((VOID *)&ScriptHeader, Script, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));
2307 if ((TempPosition != NULL) && (TempPosition == Script)) {
2308 //
2309 // If the position is specified, the position must be pointed to a boot script entry start address.
2310 //
2311 ValidatePosition = TRUE;
2312 }
2313
2314 if (ScriptHeader.OpCode != S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE) {
2315 LastOpcode = Script;
2316 }
2317
2318 Script = Script + ScriptHeader.Length;
2319 }
2320
2321 //
2322 // If the position is specified, but not the start of a boot script entry, it is a invalid input
2323 //
2324 if ((TempPosition != NULL) && !ValidatePosition) {
2326 }
2327
2328 CopyMem ((VOID *)&ScriptHeader, LastOpcode, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));
2329
2330 CopyMem ((VOID *)TempBootScriptEntry, LastOpcode, ScriptHeader.Length);
2331 //
2332 // Find the right position to write the node in
2333 //
2335 ScriptHeader.Length,
2336 TempPosition,
2337 BeforeOrAfter,
2338 &Script
2339 );
2340 //
2341 // Copy the node to Boot script table
2342 //
2343 CopyMem ((VOID *)Script, (VOID *)TempBootScriptEntry, ScriptHeader.Length);
2344
2345 SyncBootScript (Script);
2346
2347 //
2348 // return out the Position
2349 //
2350 if (Position != NULL) {
2351 *Position = Script;
2352 }
2353
2354 return RETURN_SUCCESS;
2355}
2356
2375RETURN_STATUS
2376EFIAPI
2378 IN BOOLEAN BeforeOrAfter,
2379 IN OUT VOID **Position OPTIONAL,
2380 IN UINT32 InformationLength,
2381 IN CONST CHAR8 *Information
2382 )
2383{
2384 UINT8 Length;
2385 UINT8 *Script;
2386 EFI_BOOT_SCRIPT_INFORMATION ScriptInformation;
2387
2388 if (!mS3BootScriptAcpiS3Enable) {
2389 return RETURN_SUCCESS;
2390 }
2391
2392 //
2393 // Truncation check
2394 //
2395 if (InformationLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_INFORMATION)) {
2397 }
2398
2399 Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_INFORMATION) + InformationLength);
2400
2401 Script = S3BootScriptGetEntryAddAddress (Length);
2402 if (Script == NULL) {
2404 }
2405
2406 //
2407 // Build script data
2408 //
2409 ScriptInformation.OpCode = S3_BOOT_SCRIPT_LIB_LABEL_OPCODE;
2410 ScriptInformation.Length = Length;
2411
2412 ScriptInformation.InformationLength = InformationLength;
2413
2414 CopyMem ((VOID *)Script, (VOID *)&ScriptInformation, sizeof (EFI_BOOT_SCRIPT_INFORMATION));
2415 CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION)), (VOID *)Information, (UINTN)InformationLength);
2416
2417 SyncBootScript (Script);
2418
2419 return S3BootScriptMoveLastOpcode (BeforeOrAfter, Position);
2420}
2421
2444RETURN_STATUS
2445EFIAPI
2447 IN BOOLEAN BeforeOrAfter,
2448 IN BOOLEAN CreateIfNotFound,
2449 IN OUT VOID **Position OPTIONAL,
2450 IN CONST CHAR8 *Label
2451 )
2452{
2453 UINT8 *Script;
2454 UINTN StartAddress;
2455 UINT32 TableLength;
2456 EFI_BOOT_SCRIPT_COMMON_HEADER ScriptHeader;
2457 EFI_BOOT_SCRIPT_TABLE_HEADER TableHeader;
2458 UINT32 LabelLength;
2459
2460 if (!mS3BootScriptAcpiS3Enable) {
2461 return RETURN_SUCCESS;
2462 }
2463
2464 //
2465 // Check NULL Label
2466 //
2467 if (Label == NULL) {
2468 return EFI_INVALID_PARAMETER;
2469 }
2470
2471 //
2472 // Check empty Label
2473 //
2474 if (Label[0] == '\0') {
2475 return EFI_INVALID_PARAMETER;
2476 }
2477
2478 //
2479 // Check that the script is initialized and synced without adding an entry to the script.
2480 // The code must search for the label first before it knows if a new entry needs
2481 // to be added.
2482 //
2483 Script = S3BootScriptGetEntryAddAddress (0);
2484 if (Script == NULL) {
2486 }
2487
2488 //
2489 // Check the header and search for existing label.
2490 //
2491 Script = mS3BootScriptTablePtr->TableBase;
2492 CopyMem ((VOID *)&TableHeader, Script, sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER));
2493 if (TableHeader.OpCode != S3_BOOT_SCRIPT_LIB_TABLE_OPCODE) {
2494 return EFI_INVALID_PARAMETER;
2495 }
2496
2497 StartAddress = (UINTN)Script;
2498 TableLength = mS3BootScriptTablePtr->TableLength;
2499 Script = Script + TableHeader.Length;
2500 while ((UINTN)Script < (UINTN)(StartAddress + TableLength)) {
2501 CopyMem ((VOID *)&ScriptHeader, Script, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));
2502 if (ScriptHeader.OpCode == S3_BOOT_SCRIPT_LIB_LABEL_OPCODE) {
2503 if (AsciiStrCmp ((CHAR8 *)(UINTN)(Script+sizeof (EFI_BOOT_SCRIPT_INFORMATION)), Label) == 0) {
2504 (*Position) = Script;
2505 return EFI_SUCCESS;
2506 }
2507 }
2508
2509 Script = Script + ScriptHeader.Length;
2510 }
2511
2512 if (CreateIfNotFound) {
2513 LabelLength = (UINT32)AsciiStrSize (Label);
2514 return S3BootScriptLabelInternal (BeforeOrAfter, Position, LabelLength, Label);
2515 } else {
2516 return EFI_NOT_FOUND;
2517 }
2518}
2519
2534RETURN_STATUS
2535EFIAPI
2537 IN UINT8 *Position1,
2538 IN UINT8 *Position2,
2539 OUT UINTN *RelativePosition
2540 )
2541{
2542 UINT8 *Script;
2543 UINT32 TableLength;
2544
2545 if (!mS3BootScriptAcpiS3Enable) {
2546 return RETURN_SUCCESS;
2547 }
2548
2549 if (RelativePosition == NULL) {
2550 return EFI_INVALID_PARAMETER;
2551 }
2552
2553 //
2554 // Check that the script is initialized and synced without adding an entry to the script.
2555 //
2556 Script = S3BootScriptGetEntryAddAddress (0);
2557 if (Script == NULL) {
2559 }
2560
2561 Script = mS3BootScriptTablePtr->TableBase;
2562
2563 //
2564 // mS3BootScriptTablePtr->TableLength does not include the termination node, so add it up
2565 //
2566 TableLength = mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE);
2567 if ((Position1 < Script) || (Position1 > Script+TableLength)) {
2568 return EFI_INVALID_PARAMETER;
2569 }
2570
2571 if ((Position2 < Script) || (Position2 > Script+TableLength)) {
2572 return EFI_INVALID_PARAMETER;
2573 }
2574
2575 *RelativePosition = (Position1 < Position2) ? -1 : ((Position1 == Position2) ? 0 : 1);
2576
2577 return EFI_SUCCESS;
2578}
UINT64 UINTN
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS ScriptIoWrite(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer)
VOID SaveSmmPriviateDataToLockBoxAtRuntime(VOID)
RETURN_STATUS EFIAPI S3BootScriptSaveInformation(IN UINT32 InformationLength, IN VOID *Information)
EFI_STATUS EFIAPI S3BootScriptSmmEventCallBack(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
EFI_STATUS CheckParameters(IN UINTN SmBusAddress, IN EFI_SMBUS_OPERATION Operation, IN OUT UINTN *Length, IN VOID *Buffer)
RETURN_STATUS EFIAPI S3BootScriptSaveIoPoll(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN VOID *Data, IN VOID *DataMask, IN UINT64 Delay)
RETURN_STATUS EFIAPI S3BootScriptSavePciCfg2ReadWrite(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT16 Segment, IN UINT64 Address, IN VOID *Data, IN VOID *DataMask)
RETURN_STATUS EFIAPI S3BootScriptSavePci2Poll(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT16 Segment, IN UINT64 Address, IN VOID *Data, IN VOID *DataMask, IN UINT64 Delay)
RETURN_STATUS EFIAPI S3BootScriptSaveDispatch2(IN VOID *EntryPoint, IN VOID *Context)
RETURN_STATUS EFIAPI S3BootScriptSaveIoReadWrite(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN VOID *Data, IN VOID *DataMask)
RETURN_STATUS EFIAPI S3BootScriptLibInitialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
RETURN_STATUS EFIAPI S3BootScriptSaveIoWrite(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer)
UINT8 * S3BootScriptGetRuntimeEntryAddAddress(UINT8 EntryLength)
RETURN_STATUS EFIAPI S3BootScriptSavePciCfgWrite(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer)
RETURN_STATUS EFIAPI S3BootScriptSaveInformationAsciiString(IN CONST CHAR8 *String)
RETURN_STATUS EFIAPI S3BootScriptCompare(IN UINT8 *Position1, IN UINT8 *Position2, OUT UINTN *RelativePosition)
VOID SyncBootScript(IN UINT8 *Script)
VOID SaveBootScriptDataToLockBox(VOID)
UINT8 * S3BootScriptGetBootTimeEntryAddAddress(UINT8 EntryLength)
VOID EFIAPI S3BootScriptEventCallBack(IN EFI_EVENT Event, IN VOID *Context)
RETURN_STATUS EFIAPI S3BootScriptSaveStall(IN UINTN Duration)
UINT8 * S3BootScriptGetEntryAddAddress(UINT8 EntryLength)
RETURN_STATUS EFIAPI S3BootScriptSaveSmbusExecute(IN UINTN SmBusAddress, IN EFI_SMBUS_OPERATION Operation, IN UINTN *Length, IN VOID *Buffer)
RETURN_STATUS EFIAPI S3BootScriptLabelInternal(IN BOOLEAN BeforeOrAfter, IN OUT VOID **Position OPTIONAL, IN UINT32 InformationLength, IN CONST CHAR8 *Information)
RETURN_STATUS EFIAPI S3BootScriptSaveMemPoll(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN VOID *BitMask, IN VOID *BitValue, IN UINTN Duration, IN UINT64 LoopTimes)
VOID RestoreBootTimeDataFromLockBox(VOID)
RETURN_STATUS EFIAPI S3BootScriptSavePciCfg2Write(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT16 Segment, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer)
EFI_STATUS EFIAPI S3BootScriptSmmAtRuntimeCallBack(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
UINT8 * S3BootScriptInternalCloseTable(VOID)
RETURN_STATUS EFIAPI S3BootScriptSaveDispatch(IN VOID *EntryPoint)
RETURN_STATUS EFIAPI S3BootScriptLibDeinitialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID S3BootScriptCalculateInsertAddress(IN UINT8 EntryLength, IN VOID *Position OPTIONAL, IN BOOLEAN BeforeOrAfter OPTIONAL, OUT UINT8 **Script)
RETURN_STATUS EFIAPI S3BootScriptMoveLastOpcode(IN BOOLEAN BeforeOrAfter, IN OUT VOID **Position OPTIONAL)
RETURN_STATUS EFIAPI S3BootScriptSavePciCfgReadWrite(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN VOID *Data, IN VOID *DataMask)
RETURN_STATUS EFIAPI S3BootScriptSaveMemWrite(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN VOID *Buffer)
UINT8 *EFIAPI S3BootScriptCloseTable(VOID)
SCRIPT_TABLE_PRIVATE_DATA * mS3BootScriptTablePtr
VOID SaveBootTimeDataToLockBox(VOID)
RETURN_STATUS EFIAPI S3BootScriptLabel(IN BOOLEAN BeforeOrAfter, IN BOOLEAN CreateIfNotFound, IN OUT VOID **Position OPTIONAL, IN CONST CHAR8 *Label)
RETURN_STATUS EFIAPI S3BootScriptSaveMemReadWrite(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN VOID *Data, IN VOID *DataMask)
RETURN_STATUS EFIAPI S3BootScriptSavePciPoll(IN S3_BOOT_SCRIPT_LIB_WIDTH Width, IN UINT64 Address, IN VOID *Data, IN VOID *DataMask, IN UINT64 Delay)
#define S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE
#define S3_BOOT_SCRIPT_LIB_TABLE_OPCODE
RETURN_STATUS EFIAPI SetLockBoxAttributes(IN GUID *Guid, IN UINT64 Attributes)
RETURN_STATUS EFIAPI RestoreLockBox(IN GUID *Guid, IN VOID *Buffer OPTIONAL, IN OUT UINTN *Length OPTIONAL)
RETURN_STATUS EFIAPI UpdateLockBox(IN GUID *Guid, IN UINTN Offset, IN VOID *Buffer, IN UINTN Length)
RETURN_STATUS EFIAPI SaveLockBox(IN GUID *Guid, IN VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define RETURN_OUT_OF_RESOURCES
Definition: Base.h:1114
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet16(TokenName)
Definition: PcdLib.h:349
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
BOOLEAN EFIAPI InSmm(VOID)
S3_BOOT_SCRIPT_LIB_WIDTH
@ S3BootScriptWidthFifoUint64
64-bit FIFO operation.
@ S3BootScriptWidthUint64
64-bit operation.
@ S3BootScriptWidthFillUint64
64-bit Fill operation.
UINTN EFI_SMBUS_DEVICE_COMMAND
Definition: SmBus.h:71
enum _EFI_SMBUS_OPERATION EFI_SMBUS_OPERATION
#define SMBUS_LIB_COMMAND(SmBusAddress)
Definition: SmbusLib.h:46
#define SMBUS_LIB_PEC(SmBusAddress)
Definition: SmbusLib.h:60
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134
@ EfiBootServicesData
@ EfiReservedMemoryType
@ EfiRuntimeServicesData
@ AllocateMaxAddress
Definition: UefiSpec.h:38
EFI_ALLOCATE_POOL SmmAllocatePool
Definition: PiSmmCis.h:132
Definition: Base.h:213