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