]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/BootScriptSaveOnS3SaveStateThunk/ScriptSave.c
fix the typo error for the name of BootScriptSaveOnS3SaveStateThunk thunk driver
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / BootScriptSaveOnS3SaveStateThunk / ScriptSave.c
1 /** @file
2 Implementation for S3 Boot Script Save thunk driver.
3 This thunk driver consumes PI S3SaveState protocol to produce framework S3BootScriptSave Protocol
4
5 Copyright (c) 2010 Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15 #include "ScriptSave.h"
16
17 EFI_HANDLE mHandle;
18 EFI_BOOT_SCRIPT_SAVE_PROTOCOL mS3ScriptSave = {
19 BootScriptWrite,
20 BootScriptCloseTable
21 };
22 EFI_S3_SAVE_STATE_PROTOCOL *mS3SaveState;
23 /**
24 Internal function to add IO write opcode to the table.
25
26 @param Marker The variable argument list to get the opcode
27 and associated attributes.
28
29 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
30 @retval EFI_SUCCESS Opcode is added.
31
32 **/
33 EFI_STATUS
34 BootScriptIoWrite (
35 IN VA_LIST Marker
36 )
37 {
38 EFI_BOOT_SCRIPT_WIDTH Width;
39 UINT64 Address;
40 UINTN Count;
41 UINT8 *Buffer;
42
43 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
44 Address = VA_ARG (Marker, UINT64);
45 Count = VA_ARG (Marker, UINTN);
46 Buffer = VA_ARG (Marker, UINT8 *);
47
48 return mS3SaveState->Write (
49 mS3SaveState,
50 EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,
51 Width,
52 Address,
53 Count,
54 Buffer
55 );
56 }
57 /**
58 Internal function to add IO read/write opcode to the table.
59
60 @param Marker The variable argument list to get the opcode
61 and associated attributes.
62
63 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
64 @retval EFI_SUCCESS Opcode is added.
65
66 **/
67 EFI_STATUS
68 BootScriptIoReadWrite (
69 IN VA_LIST Marker
70 )
71 {
72 EFI_BOOT_SCRIPT_WIDTH Width;
73 UINT64 Address;
74 UINT8 *Data;
75 UINT8 *DataMask;
76
77 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
78 Address = VA_ARG (Marker, UINT64);
79 Data = VA_ARG (Marker, UINT8 *);
80 DataMask = VA_ARG (Marker, UINT8 *);
81
82 return mS3SaveState->Write (
83 mS3SaveState,
84 EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE,
85 Width,
86 Address,
87 Data,
88 DataMask
89 );
90 }
91
92 /**
93 Internal function to add memory write opcode to the table.
94
95 @param Marker The variable argument list to get the opcode
96 and associated attributes.
97
98 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
99 @retval EFI_SUCCESS Opcode is added.
100
101 **/
102 EFI_STATUS
103 BootScriptMemWrite (
104 IN VA_LIST Marker
105 )
106 {
107 EFI_BOOT_SCRIPT_WIDTH Width;
108 UINT64 Address;
109 UINTN Count;
110 UINT8 *Buffer;
111
112 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
113 Address = VA_ARG (Marker, UINT64);
114 Count = VA_ARG (Marker, UINTN);
115 Buffer = VA_ARG (Marker, UINT8 *);
116
117 return mS3SaveState->Write (
118 mS3SaveState,
119 EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,
120 Width,
121 Address,
122 Count,
123 Buffer
124 );
125 }
126
127 /**
128 Internal function to add memory read/write opcode to the table.
129
130 @param Marker The variable argument list to get the opcode
131 and associated attributes.
132
133 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
134 @retval EFI_SUCCESS Opcode is added.
135
136 **/
137 EFI_STATUS
138 BootScriptMemReadWrite (
139 IN VA_LIST Marker
140 )
141 {
142 EFI_BOOT_SCRIPT_WIDTH Width;
143 UINT64 Address;
144 UINT8 *Data;
145 UINT8 *DataMask;
146
147 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
148 Address = VA_ARG (Marker, UINT64);
149 Data = VA_ARG (Marker, UINT8 *);
150 DataMask = VA_ARG (Marker, UINT8 *);
151
152 return mS3SaveState->Write (
153 mS3SaveState,
154 EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE,
155 Width,
156 Address,
157 Data,
158 DataMask
159 );
160 }
161
162 /**
163 Internal function to add PciCfg write opcode to the table.
164
165 @param Marker The variable argument list to get the opcode
166 and associated attributes.
167
168 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
169 @retval EFI_SUCCESS Opcode is added.
170
171 **/
172 EFI_STATUS
173 BootScriptPciCfgWrite (
174 IN VA_LIST Marker
175 )
176 {
177 EFI_BOOT_SCRIPT_WIDTH Width;
178 UINT64 Address;
179 UINTN Count;
180 UINT8 *Buffer;
181
182 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
183 Address = VA_ARG (Marker, UINT64);
184 Count = VA_ARG (Marker, UINTN);
185 Buffer = VA_ARG (Marker, UINT8 *);
186
187 return mS3SaveState->Write (
188 mS3SaveState,
189 EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,
190 Width,
191 Address,
192 Count,
193 Buffer
194 );
195 }
196
197 /**
198 Internal function to PciCfg read/write opcode to the table.
199
200 @param Marker The variable argument list to get the opcode
201 and associated attributes.
202
203 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
204 @retval EFI_SUCCESS Opcode is added.
205
206 **/
207 EFI_STATUS
208 BootScriptPciCfgReadWrite (
209 IN VA_LIST Marker
210 )
211 {
212 EFI_BOOT_SCRIPT_WIDTH Width;
213 UINT64 Address;
214 UINT8 *Data;
215 UINT8 *DataMask;
216
217 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
218 Address = VA_ARG (Marker, UINT64);
219 Data = VA_ARG (Marker, UINT8 *);
220 DataMask = VA_ARG (Marker, UINT8 *);
221
222 return mS3SaveState->Write (
223 mS3SaveState,
224 EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE,
225 Width,
226 Address,
227 Data,
228 DataMask
229 );
230 }
231 /**
232 Internal function to add PciCfg2 write opcode to the table.
233
234 @param Marker The variable argument list to get the opcode
235 and associated attributes.
236
237 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
238 @retval EFI_SUCCESS Opcode is added.
239
240 **/
241 EFI_STATUS
242 BootScriptPciCfg2Write (
243 IN VA_LIST Marker
244 )
245 {
246 EFI_BOOT_SCRIPT_WIDTH Width;
247 UINT64 Address;
248 UINTN Count;
249 UINT8 *Buffer;
250 UINT16 Segment;
251
252 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
253 Address = VA_ARG (Marker, UINT64);
254 Count = VA_ARG (Marker, UINTN);
255 Buffer = VA_ARG (Marker, UINT8 *);
256 Segment = VA_ARG (Marker, UINT16);
257
258 return mS3SaveState->Write (
259 mS3SaveState,
260 EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE,
261 Width,
262 Segment,
263 Address,
264 Count,
265 Buffer
266 );
267 }
268
269 /**
270 Internal function to PciCfg2 read/write opcode to the table.
271
272 @param Marker The variable argument list to get the opcode
273 and associated attributes.
274
275 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
276 @retval EFI_SUCCESS Opcode is added.
277
278 **/
279 EFI_STATUS
280 BootScriptPciCfg2ReadWrite (
281 IN VA_LIST Marker
282 )
283 {
284 EFI_BOOT_SCRIPT_WIDTH Width;
285 UINT16 Segment;
286 UINT64 Address;
287 UINT8 *Data;
288 UINT8 *DataMask;
289
290 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
291 Address = VA_ARG (Marker, UINT64);
292 Segment = VA_ARG (Marker, UINT16);
293 Data = VA_ARG (Marker, UINT8 *);
294 DataMask = VA_ARG (Marker, UINT8 *);
295
296 return mS3SaveState->Write (
297 mS3SaveState,
298 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE,
299 Width,
300 Segment,
301 Address,
302 Data,
303 DataMask
304 );
305 }
306 /**
307 Internal function to add smbus excute opcode to the table.
308
309 @param Marker The variable argument list to get the opcode
310 and associated attributes.
311
312 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
313 @retval EFI_SUCCESS Opcode is added.
314
315 **/
316 EFI_STATUS
317 BootScriptSmbusExecute (
318 IN VA_LIST Marker
319 )
320 {
321 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
322 EFI_SMBUS_DEVICE_COMMAND Command;
323 EFI_SMBUS_OPERATION Operation;
324 BOOLEAN PecCheck;
325 VOID *Buffer;
326 UINTN *DataSize;
327
328 SlaveAddress.SmbusDeviceAddress = VA_ARG (Marker, UINTN);
329 Command = VA_ARG (Marker, EFI_SMBUS_DEVICE_COMMAND);
330 Operation = VA_ARG (Marker, EFI_SMBUS_OPERATION);
331 PecCheck = VA_ARG (Marker, BOOLEAN);
332 DataSize = VA_ARG (Marker, UINTN *);
333 Buffer = VA_ARG (Marker, VOID *);
334
335 return mS3SaveState->Write (
336 mS3SaveState,
337 EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE,
338 SlaveAddress,
339 Command,
340 Operation,
341 PecCheck,
342 DataSize,
343 Buffer
344 );
345 }
346 /**
347 Internal function to add stall opcode to the table.
348
349 @param Marker The variable argument list to get the opcode
350 and associated attributes.
351
352 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
353 @retval EFI_SUCCESS Opcode is added.
354
355 **/
356 EFI_STATUS
357 BootScriptStall (
358 IN VA_LIST Marker
359 )
360 {
361 UINT32 Duration;
362
363 Duration = VA_ARG (Marker, UINT32);
364
365 return mS3SaveState->Write (
366 mS3SaveState,
367 EFI_BOOT_SCRIPT_STALL_OPCODE,
368 Duration
369 );
370 }
371
372 /**
373 Internal function to add Save jmp address according to DISPATCH_OPCODE.
374 We ignore "Context" parameter
375
376 @param Marker The variable argument list to get the opcode
377 and associated attributes.
378
379 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
380 @retval EFI_SUCCESS Opcode is added.
381
382 **/
383 EFI_STATUS
384 BootScriptDispatch (
385 IN VA_LIST Marker
386 )
387 {
388 VOID *EntryPoint;
389
390 EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
391 return mS3SaveState->Write (
392 mS3SaveState,
393 EFI_BOOT_SCRIPT_DISPATCH_OPCODE,
394 EntryPoint
395 );
396 }
397
398 /**
399 Internal function to add memory pool operation to the table.
400
401 @param Marker The variable argument list to get the opcode
402 and associated attributes.
403
404 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
405 @retval EFI_SUCCESS Opcode is added.
406
407 **/
408 EFI_STATUS
409 BootScriptMemPoll (
410 IN VA_LIST Marker
411 )
412 {
413 EFI_BOOT_SCRIPT_WIDTH Width;
414 UINT64 Address;
415 UINT8 *BitMask;
416 UINT8 *BitValue;
417 UINT64 Duration;
418 UINT64 LoopTimes;
419 UINT64 Delay;
420
421 Width = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
422 Address = VA_ARG (Marker, UINT64);
423 BitMask = VA_ARG (Marker, UINT8 *);
424 BitValue = VA_ARG (Marker, UINT8 *);
425 Duration = (UINT64)VA_ARG (Marker, UINT64);
426 LoopTimes = (UINT64)VA_ARG (Marker, UINT64);
427 Delay = MultU64x64 (DivU64x32(Duration, 100), LoopTimes);
428
429 return mS3SaveState->Write (
430 mS3SaveState,
431 EFI_BOOT_SCRIPT_MEM_POLL_OPCODE,
432 Width,
433 Address,
434 BitMask,
435 BitValue,
436 Delay
437 );
438 }
439
440 /**
441 Internal function to add Save jmp address according to DISPATCH_OPCODE2.
442 The "Context" parameter is not ignored.
443
444 @param Marker The variable argument list to get the opcode
445 and associated attributes.
446
447 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
448 @retval EFI_SUCCESS Opcode is added.
449
450 **/
451 EFI_STATUS
452 BootScriptDispatch2 (
453 IN VA_LIST Marker
454 )
455 {
456 VOID *EntryPoint;
457 VOID *Context;
458
459 EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
460 Context = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
461
462 return mS3SaveState->Write (
463 mS3SaveState,
464 EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE,
465 EntryPoint,
466 Context
467 );
468 }
469 /**
470 Internal function to add the opcode link node to the link
471 list.
472 @param Marker The variable argument list to get the opcode
473 and associated attributes.
474
475 @retval EFI_OUT_OF_RESOURCES Not enought resource to complete the operations.
476 @retval EFI_SUCCESS The opcode entry is added to the link list
477 successfully.
478 **/
479 EFI_STATUS
480 BootScriptInformation (
481 IN VA_LIST Marker
482 )
483 {
484 UINT32 InformationLength;
485 EFI_PHYSICAL_ADDRESS Information;
486
487 InformationLength = VA_ARG (Marker, UINT32);
488 Information = VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
489
490 return mS3SaveState->Write (
491 mS3SaveState,
492 EFI_BOOT_SCRIPT_INFORMATION_OPCODE,
493 InformationLength,
494 (VOID*)(UINTN)Information
495 );
496 }
497
498 /**
499 Adds a record into a specified Framework boot script table.
500
501 This function is used to store a boot script record into a given boot
502 script table. If the table specified by TableName is nonexistent in the
503 system, a new table will automatically be created and then the script record
504 will be added into the new table. A boot script table can add new script records
505 until EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable() is called. Currently, the only
506 meaningful table name is EFI_ACPI_S3_RESUME_SCRIPT_TABLE. This function is
507 responsible for allocating necessary memory for the script.
508
509 This function has a variable parameter list. The exact parameter list depends on
510 the OpCode that is passed into the function. If an unsupported OpCode or illegal
511 parameter list is passed in, this function returns EFI_INVALID_PARAMETER.
512 If there are not enough resources available for storing more scripts, this function returns
513 EFI_OUT_OF_RESOURCES.
514
515 @param This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
516 @param TableName Name of the script table. Currently, the only meaningful value is
517 EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
518 @param OpCode The operation code (opcode) number.
519
520 @retval EFI_SUCCESS The operation succeeded. A record was added into the
521 specified script table.
522 @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.
523 If the opcode is unknow or not supported because of the PCD
524 Feature Flags.
525 @retval EFI_OUT_OF_RESOURCES There is insufficient memory to store the boot script.
526
527 **/
528 EFI_STATUS
529 EFIAPI
530 BootScriptWrite (
531 IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
532 IN UINT16 TableName,
533 IN UINT16 OpCode,
534 ...
535 )
536 {
537 EFI_STATUS Status;
538 VA_LIST Marker;
539
540 if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {
541 //
542 // Only S3 boot script is supported for now
543 //
544 return EFI_OUT_OF_RESOURCES;
545 }
546 //
547 // Build script according to opcode
548 //
549 switch (OpCode) {
550
551 case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
552 VA_START (Marker, OpCode);
553 Status = BootScriptIoWrite (Marker);
554 VA_END (Marker);
555 break;
556
557 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
558 VA_START (Marker, OpCode);
559 Status = BootScriptIoReadWrite (Marker);
560 VA_END (Marker);
561 break;
562
563 case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
564 VA_START (Marker, OpCode);
565 Status = BootScriptMemWrite (Marker);
566 VA_END (Marker);
567 break;
568
569 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
570 VA_START (Marker, OpCode);
571 Status = BootScriptMemReadWrite (Marker);
572 VA_END (Marker);
573 break;
574
575 case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
576 VA_START (Marker, OpCode);
577 Status = BootScriptPciCfgWrite (Marker);
578 VA_END (Marker);
579 break;
580
581 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
582 VA_START (Marker, OpCode);
583 Status = BootScriptPciCfgReadWrite (Marker);
584 VA_END (Marker);
585 break;
586
587 case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:
588 VA_START (Marker, OpCode);
589 Status = BootScriptSmbusExecute (Marker);
590 VA_END (Marker);
591 break;
592
593 case EFI_BOOT_SCRIPT_STALL_OPCODE:
594 VA_START (Marker, OpCode);
595 Status = BootScriptStall (Marker);
596 VA_END (Marker);
597
598 break;
599
600 case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
601 VA_START (Marker, OpCode);
602 Status = BootScriptDispatch (Marker);
603 VA_END (Marker);
604 break;
605
606 case FRAMEWORK_EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
607 VA_START (Marker, OpCode);
608 Status = BootScriptDispatch2 (Marker);
609 VA_END (Marker);
610 break;
611
612 case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
613 VA_START (Marker, OpCode);
614 Status = BootScriptInformation (Marker);
615 VA_END (Marker);
616 break;
617
618 case FRAMEWORK_EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
619 VA_START (Marker, OpCode);
620 Status = BootScriptMemPoll (Marker);
621 VA_END (Marker);
622 break;
623
624 case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:
625 VA_START (Marker, OpCode);
626 Status = BootScriptPciCfg2Write (Marker);
627 VA_END (Marker);
628 break;
629
630 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
631 VA_START (Marker, OpCode);
632 Status = BootScriptPciCfg2ReadWrite (Marker);
633 VA_END (Marker);
634 break;
635
636 default:
637 Status = EFI_INVALID_PARAMETER;
638 break;
639 }
640
641 return Status;
642 }
643
644 /**
645 Closes the specified script table.
646
647 This function closes the specified boot script table and returns the base address
648 of the table. It allocates a new pool to duplicate all the boot scripts in the specified
649 table. Once this function is called, the specified table will be destroyed after it is
650 copied into the allocated pool. As a result, any attempts to add a script record into a
651 closed table will cause a new table to be created. The base address of the allocated pool
652 will be returned in Address. After using the boot script table, the caller is responsible
653 for freeing the pool that is allocated by this function. If the boot script table,
654 such as EFI_ACPI_S3_RESUME_SCRIPT_TABLE, is required to be stored in a nonperturbed
655 memory region, the caller should copy the table into the nonperturbed memory region by itself.
656
657 @param This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
658 @param TableName Name of the script table. Currently, the only meaningful value is
659 EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
660 @param Address A pointer to the physical address where the table begins.
661
662 @retval EFI_SUCCESS The table was successfully returned.
663 @retval EFI_NOT_FOUND The specified table was not created previously.
664 @retval EFI_OUT_OF_RESOURCE Memory is insufficient to hold the reorganized boot script table.
665 @retval EFI_UNSUPPORTED the table type is not EFI_ACPI_S3_RESUME_SCRIPT_TABLE
666
667 **/
668 EFI_STATUS
669 EFIAPI
670 BootScriptCloseTable (
671 IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
672 IN UINT16 TableName,
673 OUT EFI_PHYSICAL_ADDRESS *Address
674 )
675 {
676 if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {
677 //
678 // Only S3 boot script is supported for now
679 //
680 return EFI_NOT_FOUND;
681 }
682 //
683 // Here the close table is not implemented.
684 //
685
686 return EFI_UNSUPPORTED;
687 }
688
689 /**
690 This routine is entry point of ScriptSave driver.
691
692 @param Imagehandle Handle for this drivers loaded image protocol.
693 @param SystemTable EFI system table.
694
695 @retval EFI_OUT_OF_RESOURCES No enough resource
696 @retval EFI_SUCCESS Succesfully installed the ScriptSave driver.
697 @retval other Errors occured.
698
699 **/
700 EFI_STATUS
701 EFIAPI
702 InitializeScriptSaveOnS3SaveState (
703 IN EFI_HANDLE ImageHandle,
704 IN EFI_SYSTEM_TABLE *SystemTable
705 )
706 {
707 EFI_STATUS Status;
708 //
709 // Locate and cache PI S3 Save State Protocol.
710 //
711 Status = gBS->LocateProtocol (
712 &gEfiS3SaveStateProtocolGuid,
713 NULL,
714 (VOID **) &mS3SaveState
715 );
716 ASSERT_EFI_ERROR (Status);
717
718 return gBS->InstallProtocolInterface (
719 &mHandle,
720 &gEfiBootScriptSaveProtocolGuid,
721 EFI_NATIVE_INTERFACE,
722 &mS3ScriptSave
723 );
724
725 }
726
727