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