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