2 Implementation for S3 Boot Script Saver driver.
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License that accompanies this distribution.
8 The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "InternalBootScriptSave.h"
19 EFI_HANDLE mHandle
= NULL
;
20 EFI_BOOT_SCRIPT_SAVE_PROTOCOL mS3ScriptSave
= {
26 Internal function to add IO write opcode to the table.
28 @param Marker The variable argument list to get the opcode
29 and associated attributes.
31 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
32 @retval EFI_SUCCESS Opcode is added.
40 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
45 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
46 Address
= VA_ARG (Marker
, UINT64
);
47 Count
= VA_ARG (Marker
, UINTN
);
48 Buffer
= VA_ARG (Marker
, UINT8
*);
50 return S3BootScriptSaveIoWrite (Width
, Address
, Count
, Buffer
);
54 Internal function to add IO read/write opcode to the table.
56 @param Marker The variable argument list to get the opcode
57 and associated attributes.
59 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
60 @retval EFI_SUCCESS Opcode is added.
64 BootScriptIoReadWrite (
68 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
73 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
74 Address
= VA_ARG (Marker
, UINT64
);
75 Data
= VA_ARG (Marker
, UINT8
*);
76 DataMask
= VA_ARG (Marker
, UINT8
*);
78 return S3BootScriptSaveIoReadWrite (Width
, Address
, Data
, DataMask
);
82 Internal function to add memory write opcode to the table.
84 @param Marker The variable argument list to get the opcode
85 and associated attributes.
87 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
88 @retval EFI_SUCCESS Opcode is added.
96 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
101 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
102 Address
= VA_ARG (Marker
, UINT64
);
103 Count
= VA_ARG (Marker
, UINTN
);
104 Buffer
= VA_ARG (Marker
, UINT8
*);
106 return S3BootScriptSaveMemWrite (Width
, Address
, Count
, Buffer
);
110 Internal function to add memory read/write opcode to the table.
112 @param Marker The variable argument list to get the opcode
113 and associated attributes.
115 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
116 @retval EFI_SUCCESS Opcode is added.
120 BootScriptMemReadWrite (
124 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
129 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
130 Address
= VA_ARG (Marker
, UINT64
);
131 Data
= VA_ARG (Marker
, UINT8
*);
132 DataMask
= VA_ARG (Marker
, UINT8
*);
134 return S3BootScriptSaveMemReadWrite (Width
, Address
, Data
, DataMask
);
138 Internal function to add PciCfg write opcode to the table.
140 @param Marker The variable argument list to get the opcode
141 and associated attributes.
143 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
144 @retval EFI_SUCCESS Opcode is added.
148 BootScriptPciCfgWrite (
152 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
157 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
158 Address
= VA_ARG (Marker
, UINT64
);
159 Count
= VA_ARG (Marker
, UINTN
);
160 Buffer
= VA_ARG (Marker
, UINT8
*);
162 return S3BootScriptSavePciCfgWrite (Width
, Address
, Count
, Buffer
);
166 Internal function to PciCfg read/write opcode to the table.
168 @param Marker The variable argument list to get the opcode
169 and associated attributes.
171 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
172 @retval EFI_SUCCESS Opcode is added.
176 BootScriptPciCfgReadWrite (
180 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
185 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
186 Address
= VA_ARG (Marker
, UINT64
);
187 Data
= VA_ARG (Marker
, UINT8
*);
188 DataMask
= VA_ARG (Marker
, UINT8
*);
190 return S3BootScriptSavePciCfgReadWrite (Width
, Address
, Data
, DataMask
);
194 Internal function to add PciCfg2 write opcode to the table.
196 @param Marker The variable argument list to get the opcode
197 and associated attributes.
199 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
200 @retval EFI_SUCCESS Opcode is added.
204 BootScriptPciCfg2Write (
208 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
214 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
215 Address
= VA_ARG (Marker
, UINT64
);
216 Count
= VA_ARG (Marker
, UINTN
);
217 Buffer
= VA_ARG (Marker
, UINT8
*);
218 Segment
= VA_ARG (Marker
, UINT16
);
220 return S3BootScriptSavePciCfg2Write (Width
, Segment
, Address
, Count
, Buffer
);
224 Internal function to PciCfg2 read/write opcode to the table.
226 @param Marker The variable argument list to get the opcode
227 and associated attributes.
229 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
230 @retval EFI_SUCCESS Opcode is added.
234 BootScriptPciCfg2ReadWrite (
238 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
244 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
245 Address
= VA_ARG (Marker
, UINT64
);
246 Segment
= VA_ARG (Marker
, UINT16
);
247 Data
= VA_ARG (Marker
, UINT8
*);
248 DataMask
= VA_ARG (Marker
, UINT8
*);
250 return S3BootScriptSavePciCfg2ReadWrite (Width
, Segment
, Address
, Data
, DataMask
);
254 Internal function to add smbus execute opcode to the table.
256 @param Marker The variable argument list to get the opcode
257 and associated attributes.
259 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
260 @retval EFI_SUCCESS Opcode is added.
264 BootScriptSmbusExecute (
268 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
;
269 EFI_SMBUS_DEVICE_COMMAND Command
;
270 EFI_SMBUS_OPERATION Operation
;
276 SlaveAddress
.SmbusDeviceAddress
= VA_ARG (Marker
, UINTN
);
277 Command
= VA_ARG (Marker
, EFI_SMBUS_DEVICE_COMMAND
);
278 Operation
= VA_ARG (Marker
, EFI_SMBUS_OPERATION
);
279 PecCheck
= VA_ARG (Marker
, BOOLEAN
);
280 SmBusAddress
= SMBUS_LIB_ADDRESS (SlaveAddress
.SmbusDeviceAddress
,Command
,0,PecCheck
);
281 DataSize
= VA_ARG (Marker
, UINTN
*);
282 Buffer
= VA_ARG (Marker
, VOID
*);
284 return S3BootScriptSaveSmbusExecute (SmBusAddress
, Operation
, DataSize
, Buffer
);
288 Internal function to add stall opcode to the table.
290 @param Marker The variable argument list to get the opcode
291 and associated attributes.
293 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
294 @retval EFI_SUCCESS Opcode is added.
304 Duration
= VA_ARG (Marker
, UINT32
);
306 return S3BootScriptSaveStall (Duration
);
310 Internal function to add Save jmp address according to DISPATCH_OPCODE.
311 We ignore "Context" parameter.
313 @param Marker The variable argument list to get the opcode
314 and associated attributes.
316 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
317 @retval EFI_SUCCESS Opcode is added.
327 EntryPoint
= (VOID
*)(UINTN
)VA_ARG (Marker
, EFI_PHYSICAL_ADDRESS
);
328 return S3BootScriptSaveDispatch (EntryPoint
);
332 Internal function to add memory pool operation to the table.
334 @param Marker The variable argument list to get the opcode
335 and associated attributes.
337 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
338 @retval EFI_SUCCESS Opcode is added.
346 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
353 Width
= VA_ARG (Marker
, S3_BOOT_SCRIPT_LIB_WIDTH
);
354 Address
= VA_ARG (Marker
, UINT64
);
355 BitMask
= VA_ARG (Marker
, UINT8
*);
356 BitValue
= VA_ARG (Marker
, UINT8
*);
357 Duration
= (UINTN
)VA_ARG (Marker
, UINT64
);
358 LoopTimes
= VA_ARG (Marker
, UINT64
);
360 return S3BootScriptSaveMemPoll (Width
, Address
, BitMask
, BitValue
, Duration
, LoopTimes
);
364 Internal function to add Save jmp address according to DISPATCH_OPCODE2.
365 The "Context" parameter is not ignored.
367 @param Marker The variable argument list to get the opcode
368 and associated attributes.
370 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
371 @retval EFI_SUCCESS Opcode is added.
375 BootScriptDispatch2 (
382 EntryPoint
= (VOID
*)(UINTN
)VA_ARG (Marker
, EFI_PHYSICAL_ADDRESS
);
383 Context
= (VOID
*)(UINTN
)VA_ARG (Marker
, EFI_PHYSICAL_ADDRESS
);
385 return S3BootScriptSaveDispatch2 (EntryPoint
, Context
);
389 Internal function to add the opcode link node to the link list.
391 @param Marker The variable argument list to get the opcode
392 and associated attributes.
394 @retval EFI_OUT_OF_RESOURCES Not enought resource to complete the operations.
395 @retval EFI_SUCCESS The opcode entry is added to the link list
399 BootScriptInformation (
403 UINT32 InformationLength
;
404 EFI_PHYSICAL_ADDRESS Information
;
406 InformationLength
= VA_ARG (Marker
, UINT32
);
407 Information
= VA_ARG (Marker
, EFI_PHYSICAL_ADDRESS
);
408 return S3BootScriptSaveInformation (InformationLength
, (VOID
*)(UINTN
)Information
);
412 Adds a record into a specified Framework boot script table.
414 This function is used to store a boot script record into a given boot
415 script table. If the table specified by TableName is nonexistent in the
416 system, a new table will automatically be created and then the script record
417 will be added into the new table. A boot script table can add new script records
418 until EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable() is called. Currently, the only
419 meaningful table name is EFI_ACPI_S3_RESUME_SCRIPT_TABLE. This function is
420 responsible for allocating necessary memory for the script.
422 This function has a variable parameter list. The exact parameter list depends on
423 the OpCode that is passed into the function. If an unsupported OpCode or illegal
424 parameter list is passed in, this function returns EFI_INVALID_PARAMETER.
425 If there are not enough resources available for storing more scripts, this function returns
426 EFI_OUT_OF_RESOURCES.
428 @param This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
429 @param TableName Name of the script table. Currently, the only meaningful value is
430 EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
431 @param OpCode The operation code (opcode) number.
432 @param ... Argument list that is specific to each opcode.
434 @retval EFI_SUCCESS The operation succeeded. A record was added into the
435 specified script table.
436 @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.
437 If the opcode is unknow or not supported because of the PCD
439 @retval EFI_OUT_OF_RESOURCES There is insufficient memory to store the boot script.
445 IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL
*This
,
454 if (TableName
!= FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE
) {
456 // Only S3 boot script is supported for now.
458 return EFI_OUT_OF_RESOURCES
;
462 // Build script according to opcode.
466 case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE
:
467 VA_START (Marker
, OpCode
);
468 Status
= BootScriptIoWrite (Marker
);
472 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE
:
473 VA_START (Marker
, OpCode
);
474 Status
= BootScriptIoReadWrite (Marker
);
478 case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE
:
479 VA_START (Marker
, OpCode
);
480 Status
= BootScriptMemWrite (Marker
);
484 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE
:
485 VA_START (Marker
, OpCode
);
486 Status
= BootScriptMemReadWrite (Marker
);
490 case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE
:
491 VA_START (Marker
, OpCode
);
492 Status
= BootScriptPciCfgWrite (Marker
);
496 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE
:
497 VA_START (Marker
, OpCode
);
498 Status
= BootScriptPciCfgReadWrite (Marker
);
502 case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE
:
503 VA_START (Marker
, OpCode
);
504 Status
= BootScriptSmbusExecute (Marker
);
508 case EFI_BOOT_SCRIPT_STALL_OPCODE
:
509 VA_START (Marker
, OpCode
);
510 Status
= BootScriptStall (Marker
);
515 case EFI_BOOT_SCRIPT_DISPATCH_OPCODE
:
516 VA_START (Marker
, OpCode
);
517 Status
= BootScriptDispatch (Marker
);
521 case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE
:
522 VA_START (Marker
, OpCode
);
523 Status
= BootScriptDispatch2 (Marker
);
527 case EFI_BOOT_SCRIPT_INFORMATION_OPCODE
:
528 VA_START (Marker
, OpCode
);
529 Status
= BootScriptInformation (Marker
);
533 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE
:
534 VA_START (Marker
, OpCode
);
535 Status
= BootScriptMemPoll (Marker
);
539 case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE
:
540 VA_START (Marker
, OpCode
);
541 Status
= BootScriptPciCfg2Write (Marker
);
545 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE
:
546 VA_START (Marker
, OpCode
);
547 Status
= BootScriptPciCfg2ReadWrite (Marker
);
552 Status
= EFI_INVALID_PARAMETER
;
560 Closes the specified script table.
562 This function closes the specified boot script table and returns the base address
563 of the table. It allocates a new pool to duplicate all the boot scripts in the specified
564 table. Once this function is called, the specified table will be destroyed after it is
565 copied into the allocated pool. As a result, any attempts to add a script record into a
566 closed table will cause a new table to be created. The base address of the allocated pool
567 will be returned in Address. After using the boot script table, the caller is responsible
568 for freeing the pool that is allocated by this function. If the boot script table,
569 such as EFI_ACPI_S3_RESUME_SCRIPT_TABLE, is required to be stored in a nonperturbed
570 memory region, the caller should copy the table into the nonperturbed memory region by itself.
572 @param This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
573 @param TableName Name of the script table. Currently, the only meaningful value is
574 EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
575 @param Address A pointer to the physical address where the table begins.
577 @retval EFI_SUCCESS The table was successfully returned.
578 @retval EFI_NOT_FOUND The specified table was not created previously.
579 @retval EFI_OUT_OF_RESOURCE Memory is insufficient to hold the reorganized boot script table.
580 @retval EFI_UNSUPPORTED The table type is not EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
585 BootScriptCloseTable (
586 IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL
*This
,
588 OUT EFI_PHYSICAL_ADDRESS
*Address
591 if (TableName
!= FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE
) {
593 // Only S3 boot script is supported for now.
595 return EFI_NOT_FOUND
;
597 *Address
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)S3BootScriptCloseTable ();
600 return EFI_NOT_FOUND
;
606 This routine is entry point of ScriptSave driver.
608 @param ImageHandle Handle for this drivers loaded image protocol.
609 @param SystemTable EFI system table.
611 @retval EFI_OUT_OF_RESOURCES No enough resource.
612 @retval EFI_SUCCESS Succesfully installed the ScriptSave driver.
613 @retval other Errors occured.
618 InitializeScriptSave (
619 IN EFI_HANDLE ImageHandle
,
620 IN EFI_SYSTEM_TABLE
*SystemTable
623 return gBS
->InstallProtocolInterface (
625 &gEfiBootScriptSaveProtocolGuid
,
626 EFI_NATIVE_INTERFACE
,