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