]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveState.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / S3SaveStateDxe / S3SaveState.c
1 /** @file
2 Implementation for S3 Boot Script Saver state driver.
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9 #include "InternalS3SaveState.h"
10
11 EFI_HANDLE mHandle = NULL;
12 EFI_S3_SAVE_STATE_PROTOCOL mS3SaveState = {
13 BootScriptWrite,
14 BootScriptInsert,
15 BootScriptLabel,
16 BootScriptCompare
17 };
18 /**
19 Internal function to add IO write opcode to the table.
20
21 @param Marker The variable argument list to get the opcode
22 and associated attributes.
23
24 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
25 @retval EFI_SUCCESS Opcode is added.
26
27 **/
28 EFI_STATUS
29 BootScriptWriteIoWrite (
30 IN VA_LIST Marker
31 )
32 {
33 S3_BOOT_SCRIPT_LIB_WIDTH Width;
34 UINT64 Address;
35 UINTN Count;
36 UINT8 *Buffer;
37
38 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
39 Address = VA_ARG (Marker, UINT64);
40 Count = VA_ARG (Marker, UINTN);
41 Buffer = VA_ARG (Marker, UINT8 *);
42
43 return S3BootScriptSaveIoWrite (Width, Address, Count, Buffer);
44 }
45 /**
46 Internal function to add IO read/write opcode to the table.
47
48 @param Marker The variable argument list to get the opcode
49 and associated attributes.
50
51 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
52 @retval EFI_SUCCESS Opcode is added.
53
54 **/
55 EFI_STATUS
56 BootScriptWriteIoReadWrite (
57 IN VA_LIST Marker
58 )
59 {
60 S3_BOOT_SCRIPT_LIB_WIDTH Width;
61 UINT64 Address;
62 UINT8 *Data;
63 UINT8 *DataMask;
64
65 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
66 Address = VA_ARG (Marker, UINT64);
67 Data = VA_ARG (Marker, UINT8 *);
68 DataMask = VA_ARG (Marker, UINT8 *);
69
70 return S3BootScriptSaveIoReadWrite (Width, Address, Data, DataMask);
71 }
72
73 /**
74 Internal function to add memory write opcode to the table.
75
76 @param Marker The variable argument list to get the opcode
77 and associated attributes.
78
79 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
80 @retval EFI_SUCCESS Opcode is added.
81
82 **/
83 EFI_STATUS
84 BootScriptWriteMemWrite (
85 IN VA_LIST Marker
86 )
87 {
88 S3_BOOT_SCRIPT_LIB_WIDTH Width;
89 UINT64 Address;
90 UINTN Count;
91 UINT8 *Buffer;
92
93 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
94 Address = VA_ARG (Marker, UINT64);
95 Count = VA_ARG (Marker, UINTN);
96 Buffer = VA_ARG (Marker, UINT8 *);
97
98 return S3BootScriptSaveMemWrite (Width, Address, Count, Buffer);
99 }
100
101 /**
102 Internal function to add memory read/write opcode to the table.
103
104 @param Marker The variable argument list to get the opcode
105 and associated attributes.
106
107 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
108 @retval EFI_SUCCESS Opcode is added.
109
110 **/
111 EFI_STATUS
112 BootScriptWriteMemReadWrite (
113 IN VA_LIST Marker
114 )
115 {
116 S3_BOOT_SCRIPT_LIB_WIDTH Width;
117 UINT64 Address;
118 UINT8 *Data;
119 UINT8 *DataMask;
120
121 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
122 Address = VA_ARG (Marker, UINT64);
123 Data = VA_ARG (Marker, UINT8 *);
124 DataMask = VA_ARG (Marker, UINT8 *);
125
126 return S3BootScriptSaveMemReadWrite (Width, Address, Data, DataMask);
127 }
128
129 /**
130 Internal function to add PciCfg write opcode to the table.
131
132 @param Marker The variable argument list to get the opcode
133 and associated attributes.
134
135 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
136 @retval EFI_SUCCESS Opcode is added.
137
138 **/
139 EFI_STATUS
140 BootScriptWritePciCfgWrite (
141 IN VA_LIST Marker
142 )
143 {
144 S3_BOOT_SCRIPT_LIB_WIDTH Width;
145 UINT64 Address;
146 UINTN Count;
147 UINT8 *Buffer;
148
149 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
150 Address = VA_ARG (Marker, UINT64);
151 Count = VA_ARG (Marker, UINTN);
152 Buffer = VA_ARG (Marker, UINT8 *);
153
154 return S3BootScriptSavePciCfgWrite (Width, Address, Count, Buffer);
155 }
156
157 /**
158 Internal function to PciCfg read/write opcode to the table.
159
160 @param Marker The variable argument list to get the opcode
161 and associated attributes.
162
163 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
164 @retval EFI_SUCCESS Opcode is added.
165
166 **/
167 EFI_STATUS
168 BootScriptWritePciCfgReadWrite (
169 IN VA_LIST Marker
170 )
171 {
172 S3_BOOT_SCRIPT_LIB_WIDTH Width;
173 UINT64 Address;
174 UINT8 *Data;
175 UINT8 *DataMask;
176
177 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
178 Address = VA_ARG (Marker, UINT64);
179 Data = VA_ARG (Marker, UINT8 *);
180 DataMask = VA_ARG (Marker, UINT8 *);
181
182 return S3BootScriptSavePciCfgReadWrite (Width, Address, Data, DataMask);
183 }
184 /**
185 Internal function to add PciCfg2 write opcode to the table.
186
187 @param Marker The variable argument list to get the opcode
188 and associated attributes.
189
190 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
191 @retval EFI_SUCCESS Opcode is added.
192
193 **/
194 EFI_STATUS
195 BootScriptWritePciCfg2Write (
196 IN VA_LIST Marker
197 )
198 {
199 S3_BOOT_SCRIPT_LIB_WIDTH Width;
200 UINT64 Address;
201 UINTN Count;
202 UINT8 *Buffer;
203 UINT16 Segment;
204
205 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
206 Segment = VA_ARG (Marker, UINT16);
207 Address = VA_ARG (Marker, UINT64);
208 Count = VA_ARG (Marker, UINTN);
209 Buffer = VA_ARG (Marker, UINT8 *);
210
211 return S3BootScriptSavePciCfg2Write (Width, Segment, Address, Count, Buffer);
212 }
213
214 /**
215 Internal function to PciCfg2 read/write opcode to the table.
216
217 @param Marker The variable argument list to get the opcode
218 and associated attributes.
219
220 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
221 @retval EFI_SUCCESS Opcode is added.
222
223 **/
224 EFI_STATUS
225 BootScriptWritePciCfg2ReadWrite (
226 IN VA_LIST Marker
227 )
228 {
229 S3_BOOT_SCRIPT_LIB_WIDTH Width;
230 UINT16 Segment;
231 UINT64 Address;
232 UINT8 *Data;
233 UINT8 *DataMask;
234
235 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
236 Segment = VA_ARG (Marker, UINT16);
237 Address = VA_ARG (Marker, UINT64);
238 Data = VA_ARG (Marker, UINT8 *);
239 DataMask = VA_ARG (Marker, UINT8 *);
240
241 return S3BootScriptSavePciCfg2ReadWrite (Width, Segment, Address, Data, DataMask);
242 }
243 /**
244 Internal function to add smbus execute opcode to the table.
245
246 @param Marker The variable argument list to get the opcode
247 and associated attributes.
248
249 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
250 @retval EFI_SUCCESS Opcode is added.
251
252 **/
253 EFI_STATUS
254 BootScriptWriteSmbusExecute (
255 IN VA_LIST Marker
256 )
257 {
258 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
259 EFI_SMBUS_DEVICE_COMMAND Command;
260 EFI_SMBUS_OPERATION Operation;
261 BOOLEAN PecCheck;
262 VOID *Buffer;
263 UINTN *DataSize;
264 UINTN SmBusAddress;
265
266 SlaveAddress.SmbusDeviceAddress = VA_ARG (Marker, UINTN);
267 Command = VA_ARG (Marker, EFI_SMBUS_DEVICE_COMMAND);
268 Operation = VA_ARG (Marker, EFI_SMBUS_OPERATION);
269 PecCheck = VA_ARG (Marker, BOOLEAN);
270 SmBusAddress = SMBUS_LIB_ADDRESS (SlaveAddress.SmbusDeviceAddress,Command,0,PecCheck);
271 DataSize = VA_ARG (Marker, UINTN *);
272 Buffer = VA_ARG (Marker, VOID *);
273
274 return S3BootScriptSaveSmbusExecute (SmBusAddress, Operation, DataSize, Buffer);
275 }
276 /**
277 Internal function to add stall opcode to the table.
278
279 @param Marker The variable argument list to get the opcode
280 and associated attributes.
281
282 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
283 @retval EFI_SUCCESS Opcode is added.
284
285 **/
286 EFI_STATUS
287 BootScriptWriteStall (
288 IN VA_LIST Marker
289 )
290 {
291 UINT32 Duration;
292
293 Duration = VA_ARG (Marker, UINT32);
294
295 return S3BootScriptSaveStall (Duration);
296 }
297
298 /**
299 Internal function to add Save jmp address according to DISPATCH_OPCODE.
300 We ignore "Context" parameter
301
302 @param Marker The variable argument list to get the opcode
303 and associated attributes.
304
305 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
306 @retval EFI_SUCCESS Opcode is added.
307
308 **/
309 EFI_STATUS
310 BootScriptWriteDispatch (
311 IN VA_LIST Marker
312 )
313 {
314 VOID *EntryPoint;
315
316 EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
317 return S3BootScriptSaveDispatch (EntryPoint);
318 }
319
320 /**
321 Internal function to add memory pool operation to the table.
322
323 @param Marker The variable argument list to get the opcode
324 and associated attributes.
325
326 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
327 @retval EFI_SUCCESS Opcode is added.
328
329 **/
330 EFI_STATUS
331 BootScriptWriteMemPoll (
332 IN VA_LIST Marker
333 )
334 {
335 S3_BOOT_SCRIPT_LIB_WIDTH Width;
336 UINT64 Address;
337 VOID *Data;
338 VOID *DataMask;
339 UINT64 Delay;
340 UINT64 LoopTimes;
341 UINT32 Remainder;
342
343 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
344 Address = VA_ARG (Marker, UINT64);
345 Data = VA_ARG (Marker, VOID *);
346 DataMask = VA_ARG (Marker, VOID *);
347 Delay = VA_ARG (Marker, UINT64);
348 //
349 // According to the spec, the interval between 2 polls is 100ns,
350 // but the unit of Duration for S3BootScriptSaveMemPoll() is microsecond(1000ns).
351 // Duration * 1000ns * LoopTimes = Delay * 100ns
352 // Duration will be minimum 1(microsecond) to be minimum deviation,
353 // so LoopTimes = Delay / 10.
354 //
355 LoopTimes = DivU64x32Remainder (
356 Delay,
357 10,
358 &Remainder
359 );
360 if (Remainder != 0) {
361 //
362 // If Remainder is not zero, LoopTimes will be rounded up by 1.
363 //
364 LoopTimes +=1;
365 }
366 return S3BootScriptSaveMemPoll (Width, Address, DataMask, Data, 1, LoopTimes);
367
368 }
369
370 /**
371 Internal function to add Save jmp address according to DISPATCH_OPCODE2.
372 The "Context" parameter is not ignored.
373
374 @param Marker The variable argument list to get the opcode
375 and associated attributes.
376
377 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
378 @retval EFI_SUCCESS Opcode is added.
379
380 **/
381 EFI_STATUS
382 BootScriptWriteDispatch2 (
383 IN VA_LIST Marker
384 )
385 {
386 VOID *EntryPoint;
387 VOID *Context;
388
389 EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
390 Context = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
391
392 return S3BootScriptSaveDispatch2 (EntryPoint, Context);
393 }
394 /**
395 Internal function to add INFORAMTION opcode node to the table
396 list.
397 @param Marker The variable argument list to get the opcode
398 and associated attributes.
399
400 @retval EFI_OUT_OF_RESOURCES Not enought resource to complete the operations.
401 @retval EFI_SUCCESS The opcode entry is added to the table
402 successfully.
403 **/
404 EFI_STATUS
405 BootScriptWriteInformation (
406 IN VA_LIST Marker
407 )
408 {
409 UINT32 InformationLength;
410 EFI_PHYSICAL_ADDRESS Information;
411
412 InformationLength = VA_ARG (Marker, UINT32);
413 Information = VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
414 return S3BootScriptSaveInformation (InformationLength, (VOID*)(UINTN)Information);
415 }
416 /**
417 Internal function to add IO poll opcode node to the table
418 @param Marker The variable argument list to get the opcode
419 and associated attributes.
420
421 @retval EFI_OUT_OF_RESOURCES Not enought resource to complete the operations.
422 @retval EFI_SUCCESS The opcode entry is added to the table
423 successfully.
424 **/
425 EFI_STATUS
426 BootScriptWriteIoPoll (
427 IN VA_LIST Marker
428 )
429 {
430 S3_BOOT_SCRIPT_LIB_WIDTH Width;
431 UINT64 Address;
432 VOID *Data;
433 VOID *DataMask;
434 UINT64 Delay;
435
436 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
437 Address = VA_ARG (Marker, UINT64);
438 Data = VA_ARG (Marker, VOID *);
439 DataMask = VA_ARG (Marker, VOID *);
440 Delay = (UINT64)VA_ARG (Marker, UINT64);
441
442 return S3BootScriptSaveIoPoll (Width, Address, Data, DataMask, Delay);
443 }
444 /**
445 Internal function to add PCI config poll opcode node to the table
446
447 @param Marker The variable argument list to get the opcode
448 and associated attributes.
449
450 @retval EFI_OUT_OF_RESOURCES Not enought resource to complete the operations.
451 @retval EFI_SUCCESS The opcode entry is added to the table
452 successfully.
453 **/
454 EFI_STATUS
455 BootScriptWritePciConfigPoll (
456 IN VA_LIST Marker
457 )
458 {
459 S3_BOOT_SCRIPT_LIB_WIDTH Width;
460 UINT64 Address;
461 VOID *Data;
462 VOID *DataMask;
463 UINT64 Delay;
464
465
466 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
467 Address = VA_ARG (Marker, UINT64);
468 Data = VA_ARG (Marker, VOID *);
469 DataMask = VA_ARG (Marker, VOID *);
470 Delay = (UINT64)VA_ARG (Marker, UINT64);
471
472 return S3BootScriptSavePciPoll (Width, Address, Data, DataMask, Delay);
473 }
474 /**
475 Internal function to add PCI config 2 poll opcode node to the table
476
477 @param Marker The variable argument list to get the opcode
478 and associated attributes.
479
480 @retval EFI_OUT_OF_RESOURCES Not enought resource to complete the operations.
481 @retval EFI_SUCCESS The opcode entry is added to the table
482 successfully.
483 **/
484 EFI_STATUS
485 BootScriptWritePciConfig2Poll (
486 IN VA_LIST Marker
487 )
488 {
489 S3_BOOT_SCRIPT_LIB_WIDTH Width;
490 UINT16 Segment;
491 UINT64 Address;
492 VOID *Data;
493 VOID *DataMask;
494 UINT64 Delay;
495
496 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
497 Segment = VA_ARG (Marker, UINT16);
498 Address = VA_ARG (Marker, UINT64);
499 Data = VA_ARG (Marker, VOID *);
500 DataMask = VA_ARG (Marker, VOID *);
501 Delay = (UINT64)VA_ARG (Marker, UINT64);
502
503 return S3BootScriptSavePci2Poll (Width, Segment, Address, Data, DataMask, Delay);
504 }
505
506
507 /**
508 Adds a record into S3 boot script table.
509
510 This function is used to store a boot script record into a given boot
511 script table. If the table specified by TableName is nonexistent in the
512 system, a new table will automatically be created and then the script record
513 will be added into the new table. This function is responsible for allocating
514 necessary memory for the script.
515
516 This function has a variable parameter list. The exact parameter list depends on
517 the OpCode that is passed into the function. If an unsupported OpCode or illegal
518 parameter list is passed in, this function returns EFI_INVALID_PARAMETER.
519 If there are not enough resources available for storing more scripts, this function returns
520 EFI_OUT_OF_RESOURCES.
521
522 @param This A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.
523 @param OpCode The operation code (opcode) number.
524 @param ... Argument list that is specific to each opcode.
525
526 @retval EFI_SUCCESS The operation succeeded. A record was added into the
527 specified script table.
528 @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.
529 If the opcode is unknow or not supported because of the PCD
530 Feature Flags.
531 @retval EFI_OUT_OF_RESOURCES There is insufficient memory to store the boot script.
532
533 **/
534 EFI_STATUS
535 EFIAPI
536 BootScriptWrite (
537 IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
538 IN UINTN OpCode,
539 ...
540 )
541 {
542 EFI_STATUS Status;
543 VA_LIST Marker;
544 //
545 // Build script according to opcode
546 //
547 switch (OpCode) {
548
549 case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
550 VA_START (Marker, OpCode);
551 Status = BootScriptWriteIoWrite (Marker);
552 VA_END (Marker);
553 break;
554
555 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
556 VA_START (Marker, OpCode);
557 Status = BootScriptWriteIoReadWrite (Marker);
558 VA_END (Marker);
559 break;
560
561 case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
562 VA_START (Marker, OpCode);
563 Status = BootScriptWriteMemWrite (Marker);
564 VA_END (Marker);
565 break;
566
567 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
568 VA_START (Marker, OpCode);
569 Status = BootScriptWriteMemReadWrite (Marker);
570 VA_END (Marker);
571 break;
572
573 case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
574 VA_START (Marker, OpCode);
575 Status = BootScriptWritePciCfgWrite (Marker);
576 VA_END (Marker);
577 break;
578
579 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
580 VA_START (Marker, OpCode);
581 Status = BootScriptWritePciCfgReadWrite (Marker);
582 VA_END (Marker);
583 break;
584
585 case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:
586 VA_START (Marker, OpCode);
587 Status = BootScriptWriteSmbusExecute (Marker);
588 VA_END (Marker);
589 break;
590
591 case EFI_BOOT_SCRIPT_STALL_OPCODE:
592 VA_START (Marker, OpCode);
593 Status = BootScriptWriteStall (Marker);
594 VA_END (Marker);
595
596 break;
597
598 case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
599 VA_START (Marker, OpCode);
600 Status = BootScriptWriteDispatch (Marker);
601 VA_END (Marker);
602 break;
603
604 case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
605 VA_START (Marker, OpCode);
606 Status = BootScriptWriteDispatch2 (Marker);
607 VA_END (Marker);
608 break;
609
610 case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
611 VA_START (Marker, OpCode);
612 Status = BootScriptWriteInformation (Marker);
613 VA_END (Marker);
614 break;
615
616 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
617 VA_START (Marker, OpCode);
618 Status = BootScriptWriteMemPoll (Marker);
619 VA_END (Marker);
620 break;
621
622 case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:
623 VA_START (Marker, OpCode);
624 Status = BootScriptWritePciCfg2Write (Marker);
625 VA_END (Marker);
626 break;
627
628 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
629 VA_START (Marker, OpCode);
630 Status = BootScriptWritePciCfg2ReadWrite (Marker);
631 VA_END (Marker);
632 break;
633
634 case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:
635 VA_START (Marker, OpCode);
636 Status = BootScriptWriteIoPoll (Marker);
637 VA_END (Marker);
638 break;
639
640 case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:
641 VA_START (Marker, OpCode);
642 Status = BootScriptWritePciConfigPoll (Marker);
643 VA_END (Marker);
644 break;
645
646 case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:
647 VA_START (Marker, OpCode);
648 Status = BootScriptWritePciConfig2Poll (Marker);
649 VA_END (Marker);
650 break;
651
652 default:
653 Status = EFI_INVALID_PARAMETER;
654 break;
655 }
656
657 return Status;
658 }
659 /**
660 Insert a record into a specified Framework boot script table.
661
662 This function is used to store an OpCode to be replayed as part of the S3 resume boot path. It is
663 assumed this protocol has platform specific mechanism to store the OpCode set and replay them
664 during the S3 resume.
665 The opcode is inserted before or after the specified position in the boot script table. If Position is
666 NULL then that position is after the last opcode in the table (BeforeOrAfter is FALSE) or before
667 the first opcode in the table (BeforeOrAfter is TRUE). The position which is pointed to by
668 Position upon return can be used for subsequent insertions.
669
670 @param This A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.
671 @param BeforeOrAfter Specifies whether the opcode is stored before (TRUE) or after (FALSE) the position
672 in the boot script table specified by Position. If Position is NULL or points to
673 NULL then the new opcode is inserted at the beginning of the table (if TRUE) or end
674 of the table (if FALSE).
675 @param Position On entry, specifies the position in the boot script table where the opcode will be
676 inserted, either before or after, depending on BeforeOrAfter. On exit, specifies
677 the position of the inserted opcode in the boot script table.
678 @param OpCode The operation code (opcode) number.
679 @param ... Argument list that is specific to each opcode.
680
681 @retval EFI_SUCCESS The operation succeeded. A record was added into the
682 specified script table.
683 @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..
684 @retval EFI_OUT_OF_RESOURCES There is insufficient memory to store the boot script.
685
686 **/
687 EFI_STATUS
688 EFIAPI
689 BootScriptInsert (
690 IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
691 IN BOOLEAN BeforeOrAfter,
692 IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL,
693 IN UINTN OpCode,
694 ...
695 )
696 {
697 EFI_STATUS Status;
698 VA_LIST Marker;
699 //
700 // Build script according to opcode
701 //
702 switch (OpCode) {
703
704 case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
705 VA_START (Marker, OpCode);
706 Status = BootScriptWriteIoWrite (Marker);
707 VA_END (Marker);
708 break;
709
710 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
711 VA_START (Marker, OpCode);
712 Status = BootScriptWriteIoReadWrite (Marker);
713 VA_END (Marker);
714 break;
715
716 case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
717 VA_START (Marker, OpCode);
718 Status = BootScriptWriteMemWrite (Marker);
719 VA_END (Marker);
720 break;
721
722 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
723 VA_START (Marker, OpCode);
724 Status = BootScriptWriteMemReadWrite (Marker);
725 VA_END (Marker);
726 break;
727
728 case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
729 VA_START (Marker, OpCode);
730 Status = BootScriptWritePciCfgWrite (Marker);
731 VA_END (Marker);
732 break;
733
734 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
735 VA_START (Marker, OpCode);
736 Status = BootScriptWritePciCfgReadWrite (Marker);
737 VA_END (Marker);
738 break;
739
740 case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:
741 VA_START (Marker, OpCode);
742 Status = BootScriptWriteSmbusExecute (Marker);
743 VA_END (Marker);
744 break;
745
746 case EFI_BOOT_SCRIPT_STALL_OPCODE:
747 VA_START (Marker, OpCode);
748 Status = BootScriptWriteStall (Marker);
749 VA_END (Marker);
750
751 break;
752
753 case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
754 VA_START (Marker, OpCode);
755 Status = BootScriptWriteDispatch (Marker);
756 VA_END (Marker);
757 break;
758
759 case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
760 VA_START (Marker, OpCode);
761 Status = BootScriptWriteDispatch2 (Marker);
762 VA_END (Marker);
763 break;
764
765 case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
766 VA_START (Marker, OpCode);
767 Status = BootScriptWriteInformation (Marker);
768 VA_END (Marker);
769 break;
770
771 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
772 VA_START (Marker, OpCode);
773 Status = BootScriptWriteMemPoll (Marker);
774 VA_END (Marker);
775 break;
776
777 case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:
778 VA_START (Marker, OpCode);
779 Status = BootScriptWritePciCfg2Write (Marker);
780 VA_END (Marker);
781 break;
782
783 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
784 VA_START (Marker, OpCode);
785 Status = BootScriptWritePciCfg2ReadWrite (Marker);
786 VA_END (Marker);
787 break;
788
789 case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:
790 VA_START (Marker, OpCode);
791 Status = BootScriptWriteIoPoll (Marker);
792 VA_END (Marker);
793 break;
794
795 case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:
796 VA_START (Marker, OpCode);
797 Status = BootScriptWritePciConfigPoll (Marker);
798 VA_END (Marker);
799 break;
800
801 case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:
802 VA_START (Marker, OpCode);
803 Status = BootScriptWritePciConfig2Poll (Marker);
804 VA_END (Marker);
805 break;
806
807 default:
808 Status = EFI_INVALID_PARAMETER;
809 break;
810 }
811
812 if (!EFI_ERROR (Status)) {
813 Status = S3BootScriptMoveLastOpcode (BeforeOrAfter, Position);
814 }
815 return Status;
816 }
817 /**
818 Find a label within the boot script table and, if not present, optionally create it.
819
820 If the label Label is already exists in the boot script table, then no new label is created, the
821 position of the Label is returned in *Position and EFI_SUCCESS is returned.
822 If the label Label does not already exist and CreateIfNotFound is TRUE, then it will be
823 created before or after the specified position and EFI_SUCCESS is returned.
824 If the label Label does not already exist and CreateIfNotFound is FALSE, then
825 EFI_NOT_FOUND is returned.
826
827 @param This A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.
828 @param BeforeOrAfter Specifies whether the label is stored before (TRUE) or after (FALSE) the position in
829 the boot script table specified by Position. If Position is NULL or points to
830 NULL then the new label is inserted at the beginning of the table (if TRUE) or end of
831 the table (if FALSE).
832 @param CreateIfNotFound Specifies whether the label will be created if the label does not exists (TRUE) or not
833 (FALSE).
834 @param Position On entry, specifies the position in the boot script table where the label will be inserted,
835 either before or after, depending on BeforeOrAfter. On exit, specifies the position
836 of the inserted label in the boot script table.
837 @param Label Points to the label which will be inserted in the boot script table.
838
839 @retval EFI_SUCCESS The label already exists or was inserted.
840 @retval EFI_INVALID_PARAMETER The Label is NULL or points to an empty string.
841 @retval EFI_INVALID_PARAMETER The Position is not a valid position in the boot script table.
842
843 **/
844 EFI_STATUS
845 EFIAPI
846 BootScriptLabel (
847 IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
848 IN BOOLEAN BeforeOrAfter,
849 IN BOOLEAN CreateIfNotFound,
850 IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL,
851 IN CONST CHAR8 *Label
852 )
853 {
854 return S3BootScriptLabel (BeforeOrAfter, CreateIfNotFound, Position, Label);
855 }
856 /**
857 Compare two positions in the boot script table and return their relative position.
858
859 This function compares two positions in the boot script table and returns their relative positions. If
860 Position1 is before Position2, then -1 is returned. If Position1 is equal to Position2,
861 then 0 is returned. If Position1 is after Position2, then 1 is returned.
862
863 @param This A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.
864 @param Position1 The positions in the boot script table to compare
865 @param Position2 The positions in the boot script table to compare
866 @param RelativePosition On return, points to the result of the comparison
867
868 @retval EFI_SUCCESS The operation succeeded.
869 @retval EFI_INVALID_PARAMETER The Position1 or Position2 is not a valid position in the boot script table.
870 @retval EFI_INVALID_PARAMETER The RelativePosition is NULL.
871
872 **/
873 EFI_STATUS
874 EFIAPI
875 BootScriptCompare (
876 IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
877 IN EFI_S3_BOOT_SCRIPT_POSITION Position1,
878 IN EFI_S3_BOOT_SCRIPT_POSITION Position2,
879 OUT UINTN *RelativePosition
880 )
881 {
882 return S3BootScriptCompare (Position1, Position2, RelativePosition);
883 }
884 /**
885 This routine is entry point of ScriptSave driver.
886
887 @param ImageHandle Handle for this drivers loaded image protocol.
888 @param SystemTable EFI system table.
889
890 @retval EFI_OUT_OF_RESOURCES No enough resource
891 @retval EFI_SUCCESS Succesfully installed the ScriptSave driver.
892 @retval other Errors occured.
893
894 **/
895 EFI_STATUS
896 EFIAPI
897 InitializeS3SaveState (
898 IN EFI_HANDLE ImageHandle,
899 IN EFI_SYSTEM_TABLE *SystemTable
900 )
901 {
902 EFI_STATUS Status;
903 EFI_EVENT EndOfDxeEvent;
904
905 if (!PcdGetBool (PcdAcpiS3Enable)) {
906 return EFI_UNSUPPORTED;
907 }
908
909 Status = gBS->CreateEventEx (
910 EVT_NOTIFY_SIGNAL,
911 TPL_CALLBACK,
912 AcpiS3ContextSaveOnEndOfDxe,
913 NULL,
914 &gEfiEndOfDxeEventGroupGuid,
915 &EndOfDxeEvent
916 );
917 ASSERT_EFI_ERROR (Status);
918
919 return gBS->InstallProtocolInterface (
920 &mHandle,
921 &gEfiS3SaveStateProtocolGuid,
922 EFI_NATIVE_INTERFACE,
923 &mS3SaveState
924 );
925
926 }
927
928