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