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