2 Interpret and execute the S3 data in S3 boot script.
4 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions
8 of the BSD License which accompanies this distribution. The
9 full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "InternalBootScriptLib.h"
19 Checks the parameter of SmbusExecute().
21 This function checks the input parameters of SmbusExecute(). If the input parameters are valid
22 for certain SMBus bus protocol, it will return EFI_SUCCESS; otherwise, it will return certain
23 error code based on the input SMBus bus protocol.
25 @param SmBusAddress Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length,
27 @param Operation Signifies which particular SMBus hardware protocol instance that
28 it will use to execute the SMBus transactions. This SMBus
29 hardware protocol is defined by the SMBus Specification and is
31 @param Length Signifies the number of bytes that this operation will do. The
32 maximum number of bytes can be revision specific and operation
33 specific. This field will contain the actual number of bytes that
34 are executed for this operation. Not all operations require this
36 @param Buffer Contains the value of data to execute to the SMBus slave device.
37 Not all operations require this argument. The length of this
38 buffer is identified by Length.
40 @retval EFI_SUCCESS All the parameters are valid for the corresponding SMBus bus
42 @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
43 @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
44 and EfiSmbusQuickWrite. Length is outside the range of valid
46 @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
47 @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
52 IN UINTN SmBusAddress
,
53 IN EFI_SMBUS_OPERATION Operation
,
60 EFI_SMBUS_DEVICE_COMMAND Command
;
63 Command
= SMBUS_LIB_COMMAND (SmBusAddress
);
64 PecCheck
= SMBUS_LIB_PEC (SmBusAddress
);
66 // Set default value to be 2:
67 // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall.
72 case EfiSmbusQuickRead
:
73 case EfiSmbusQuickWrite
:
74 if (PecCheck
|| Command
!= 0) {
75 return EFI_UNSUPPORTED
;
78 case EfiSmbusReceiveByte
:
79 case EfiSmbusSendByte
:
81 return EFI_UNSUPPORTED
;
84 // Cascade to check length parameter.
86 case EfiSmbusReadByte
:
87 case EfiSmbusWriteByte
:
90 // Cascade to check length parameter.
92 case EfiSmbusReadWord
:
93 case EfiSmbusWriteWord
:
94 case EfiSmbusProcessCall
:
95 if (Buffer
== NULL
|| Length
== NULL
) {
96 return EFI_INVALID_PARAMETER
;
97 } else if (*Length
< RequiredLen
) {
98 Status
= EFI_BUFFER_TOO_SMALL
;
100 *Length
= RequiredLen
;
102 case EfiSmbusReadBlock
:
103 case EfiSmbusWriteBlock
:
104 if ((Buffer
== NULL
) ||
106 (*Length
< MIN_SMBUS_BLOCK_LEN
) ||
107 (*Length
> MAX_SMBUS_BLOCK_LEN
)) {
108 return EFI_INVALID_PARAMETER
;
111 case EfiSmbusBWBRProcessCall
:
112 return EFI_UNSUPPORTED
;
114 return EFI_INVALID_PARAMETER
;
120 Executes an SMBus operation to an SMBus controller. Returns when either the command has been
121 executed or an error is encountered in doing the operation.
123 The SmbusExecute() function provides a standard way to execute an operation as defined in the System
124 Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
125 slave devices accept this transaction or that this function returns with error.
127 @param SmbusAddress Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length,
129 @param Operation Signifies which particular SMBus hardware protocol instance that
130 it will use to execute the SMBus transactions. This SMBus
131 hardware protocol is defined by the SMBus Specification and is
133 @param Length Signifies the number of bytes that this operation will do. The
134 maximum number of bytes can be revision specific and operation
135 specific. This field will contain the actual number of bytes that
136 are executed for this operation. Not all operations require this
138 @param Buffer Contains the value of data to execute to the SMBus slave device.
139 Not all operations require this argument. The length of this
140 buffer is identified by Length.
142 @retval EFI_SUCCESS The last data that was returned from the access matched the poll
144 @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).
145 @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is
146 determined by the SMBus host controller device.
147 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
148 @retval EFI_DEVICE_ERROR The request was not completed because a failure that was
149 reflected in the Host Status Register bit. Device errors are a
150 result of a transaction collision, illegal command field,
151 unclaimed cycle (host initiated), or bus errors (collisions).
152 @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.
153 @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead
154 and EfiSmbusQuickWrite. Length is outside the range of valid
156 @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.
157 @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.
162 IN UINTN SmbusAddress
,
163 IN EFI_SMBUS_OPERATION Operation
,
164 IN OUT UINTN
*Length
,
170 UINT8 WorkBuffer
[MAX_SMBUS_BLOCK_LEN
];
172 Status
= CheckParameters (SmbusAddress
, Operation
, Length
, Buffer
);
173 if (EFI_ERROR (Status
)) {
178 case EfiSmbusQuickRead
:
179 DEBUG ((EFI_D_INFO
, "EfiSmbusQuickRead - 0x%08x\n", SmbusAddress
));
180 SmBusQuickRead (SmbusAddress
, &Status
);
182 case EfiSmbusQuickWrite
:
183 DEBUG ((EFI_D_INFO
, "EfiSmbusQuickWrite - 0x%08x\n", SmbusAddress
));
184 SmBusQuickWrite (SmbusAddress
, &Status
);
186 case EfiSmbusReceiveByte
:
187 DEBUG ((EFI_D_INFO
, "EfiSmbusReceiveByte - 0x%08x\n", SmbusAddress
));
188 *(UINT8
*) Buffer
= SmBusReceiveByte (SmbusAddress
, &Status
);
190 case EfiSmbusSendByte
:
191 DEBUG ((EFI_D_INFO
, "EfiSmbusReceiveByte - 0x%08x (0x%02x)\n", SmbusAddress
, (UINTN
)*(UINT8
*) Buffer
));
192 SmBusSendByte (SmbusAddress
, *(UINT8
*) Buffer
, &Status
);
194 case EfiSmbusReadByte
:
195 DEBUG ((EFI_D_INFO
, "EfiSmbusReadByte - 0x%08x\n", SmbusAddress
));
196 *(UINT8
*) Buffer
= SmBusReadDataByte (SmbusAddress
, &Status
);
198 case EfiSmbusWriteByte
:
199 DEBUG ((EFI_D_INFO
, "EfiSmbusWriteByte - 0x%08x (0x%02x)\n", SmbusAddress
, (UINTN
)*(UINT8
*) Buffer
));
200 SmBusWriteDataByte (SmbusAddress
, *(UINT8
*) Buffer
, &Status
);
202 case EfiSmbusReadWord
:
203 DEBUG ((EFI_D_INFO
, "EfiSmbusReadWord - 0x%08x\n", SmbusAddress
));
204 *(UINT16
*) Buffer
= SmBusReadDataWord (SmbusAddress
, &Status
);
206 case EfiSmbusWriteWord
:
207 DEBUG ((EFI_D_INFO
, "EfiSmbusWriteByte - 0x%08x (0x%04x)\n", SmbusAddress
, (UINTN
)*(UINT16
*) Buffer
));
208 SmBusWriteDataWord (SmbusAddress
, *(UINT16
*) Buffer
, &Status
);
210 case EfiSmbusProcessCall
:
211 DEBUG ((EFI_D_INFO
, "EfiSmbusProcessCall - 0x%08x (0x%04x)\n", SmbusAddress
, (UINTN
)*(UINT16
*) Buffer
));
212 *(UINT16
*) Buffer
= SmBusProcessCall (SmbusAddress
, *(UINT16
*) Buffer
, &Status
);
214 case EfiSmbusReadBlock
:
215 DEBUG ((EFI_D_INFO
, "EfiSmbusReadBlock - 0x%08x\n", SmbusAddress
));
216 WorkBufferLen
= SmBusReadBlock (SmbusAddress
, WorkBuffer
, &Status
);
217 if (!EFI_ERROR (Status
)) {
219 // Read block transaction is complete successfully, and then
220 // check whether the output buffer is large enough.
222 if (*Length
>= WorkBufferLen
) {
223 CopyMem (Buffer
, WorkBuffer
, WorkBufferLen
);
225 Status
= EFI_BUFFER_TOO_SMALL
;
227 *Length
= WorkBufferLen
;
230 case EfiSmbusWriteBlock
:
231 DEBUG ((EFI_D_INFO
, "EfiSmbusWriteBlock - 0x%08x (0x%04x)\n", SmbusAddress
, (UINTN
)*(UINT16
*) Buffer
));
232 SmBusWriteBlock ((SmbusAddress
+ SMBUS_LIB_ADDRESS (0, 0, (*Length
), FALSE
)) , Buffer
, &Status
);
234 case EfiSmbusBWBRProcessCall
:
236 // BUGBUG: Should this case be handled?
245 Translates boot script width and address stride to MDE library interface.
248 @param Width Width of the operation.
249 @param Address Address of the operation.
250 @param AddressStride Instride for stepping input buffer.
251 @param BufferStride Outstride for stepping output buffer.
253 @retval EFI_SUCCESS Successful translation.
254 @retval EFI_INVALID_PARAMETER Width or Address is invalid.
258 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
260 OUT UINTN
*AddressStride
,
261 OUT UINTN
*BufferStride
266 if (Width
>= S3BootScriptWidthMaximum
) {
267 return EFI_INVALID_PARAMETER
;
270 *AddressStride
= (UINT32
)(1 << (Width
& 0x03));
271 *BufferStride
= *AddressStride
;
273 AlignMask
= *AddressStride
- 1;
274 if ((Address
& AlignMask
) != 0) {
275 return EFI_INVALID_PARAMETER
;
278 if (Width
>= S3BootScriptWidthFifoUint8
&& Width
<= S3BootScriptWidthFifoUint64
) {
282 if (Width
>= S3BootScriptWidthFillUint8
&& Width
<= S3BootScriptWidthFillUint64
) {
290 Translates boot script to MDE library interface.
292 @param[in] Width Width of the operation.
293 @param[in] Address Address of the operation.
294 @param[in] Count Count of the number of accesses to perform.
295 @param[out] Buffer Pointer to the buffer to read from I/O space.
297 @retval EFI_SUCCESS The data was written to the EFI System.
298 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
300 The Buffer is not aligned for the given Width.
301 Address is outside the legal range of I/O ports.
306 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
317 Out
.Buf
= (UINT8
*) Buffer
;
319 if (Address
> MAX_IO_ADDRESS
) {
320 return EFI_INVALID_PARAMETER
;
323 Status
= BuildLoopData (Width
, Address
, &AddressStride
, &BufferStride
);
324 if (EFI_ERROR (Status
)) {
328 // Loop for each iteration and move the data
330 for (; Count
> 0; Count
--, Address
+= AddressStride
, Out
.Buf
+= BufferStride
) {
333 case S3BootScriptWidthUint8
:
334 case S3BootScriptWidthFifoUint8
:
335 case S3BootScriptWidthFillUint8
:
336 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint8Read - 0x%08x\n", Address
));
337 *Out
.Uint8
= IoRead8 ((UINTN
) Address
);
340 case S3BootScriptWidthUint16
:
341 case S3BootScriptWidthFifoUint16
:
342 case S3BootScriptWidthFillUint16
:
343 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint16Read - 0x%08x\n", Address
));
344 *Out
.Uint16
= IoRead16 ((UINTN
) Address
);
347 case S3BootScriptWidthUint32
:
348 case S3BootScriptWidthFifoUint32
:
349 case S3BootScriptWidthFillUint32
:
350 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint32Read - 0x%08x\n", Address
));
351 *Out
.Uint32
= IoRead32 ((UINTN
) Address
);
355 return EFI_INVALID_PARAMETER
;
363 Perform a write operation
365 @param[in] Width Width of the operation.
366 @param[in] Address Address of the operation.
367 @param[in] Count Count of the number of accesses to perform.
368 @param[in] Buffer Pointer to the buffer to write to I/O space.
370 @retval EFI_SUCCESS The data was written to the EFI System.
371 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
373 The Buffer is not aligned for the given Width.
374 Address is outside the legal range of I/O ports.
379 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
388 UINT64 OriginalAddress
;
392 In
.Buf
= (UINT8
*) Buffer
;
394 if (Address
> MAX_IO_ADDRESS
) {
395 return EFI_INVALID_PARAMETER
;
398 Status
= BuildLoopData (Width
, Address
, &AddressStride
, &BufferStride
);
399 if (EFI_ERROR (Status
)) {
403 // Loop for each iteration and move the data
405 OriginalAddress
= Address
;
406 OriginalIn
.Buf
= In
.Buf
;
407 for (; Count
> 0; Count
--, Address
+= AddressStride
, In
.Buf
+= BufferStride
) {
409 case S3BootScriptWidthUint8
:
410 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint8
));
411 IoWrite8 ((UINTN
) Address
, *In
.Uint8
);
413 case S3BootScriptWidthFifoUint8
:
414 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", (UINTN
)OriginalAddress
, (UINTN
)*In
.Uint8
));
415 IoWrite8 ((UINTN
) OriginalAddress
, *In
.Uint8
);
417 case S3BootScriptWidthFillUint8
:
418 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint8
));
419 IoWrite8 ((UINTN
) Address
, *OriginalIn
.Uint8
);
421 case S3BootScriptWidthUint16
:
422 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint16
));
423 IoWrite16 ((UINTN
) Address
, *In
.Uint16
);
425 case S3BootScriptWidthFifoUint16
:
426 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", (UINTN
)OriginalAddress
, (UINTN
)*In
.Uint16
));
427 IoWrite16 ((UINTN
) OriginalAddress
, *In
.Uint16
);
429 case S3BootScriptWidthFillUint16
:
430 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint16
));
431 IoWrite16 ((UINTN
) Address
, *OriginalIn
.Uint16
);
433 case S3BootScriptWidthUint32
:
434 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint32
));
435 IoWrite32 ((UINTN
) Address
, *In
.Uint32
);
437 case S3BootScriptWidthFifoUint32
:
438 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", (UINTN
)OriginalAddress
, (UINTN
)*In
.Uint32
));
439 IoWrite32 ((UINTN
) OriginalAddress
, *In
.Uint32
);
441 case S3BootScriptWidthFillUint32
:
442 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint32
));
443 IoWrite32 ((UINTN
) Address
, *OriginalIn
.Uint32
);
445 case S3BootScriptWidthUint64
:
446 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint64 - 0x%08x (0x%016lx)\n", (UINTN
)Address
, *In
.Uint64
));
447 IoWrite64 ((UINTN
) Address
, *In
.Uint64
);
449 case S3BootScriptWidthFifoUint64
:
450 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFifoUint64 - 0x%08x (0x%016lx)\n", (UINTN
)Address
, *In
.Uint64
));
451 IoWrite64 ((UINTN
) OriginalAddress
, *In
.Uint64
);
453 case S3BootScriptWidthFillUint64
:
454 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFillUint64 - 0x%08x (0x%016lx)\n", (UINTN
)Address
, *In
.Uint64
));
455 IoWrite64 ((UINTN
) Address
, *OriginalIn
.Uint64
);
458 return EFI_INVALID_PARAMETER
;
466 Interprete the IO write entry in S3 boot script and perform the write operation
468 @param Script Pointer to the node which is to be interpreted.
470 @retval EFI_SUCCESS The data was written to the EFI System.
471 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
473 The Buffer is not aligned for the given Width.
474 Address is outside the legal range of I/O ports.
478 BootScriptExecuteIoWrite (
482 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
486 EFI_BOOT_SCRIPT_IO_WRITE IoWrite
;
488 CopyMem ((VOID
*)&IoWrite
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_IO_WRITE
));
489 Width
= (S3_BOOT_SCRIPT_LIB_WIDTH
) IoWrite
.Width
;
490 Address
= IoWrite
.Address
;
491 Count
= IoWrite
.Count
;
492 Buffer
= Script
+ sizeof (EFI_BOOT_SCRIPT_IO_WRITE
);
494 return ScriptIoWrite(Width
, Address
, Count
, Buffer
);
497 Perform memory read operation
499 @param Width Width of the operation.
500 @param Address Address of the operation.
501 @param Count Count of the number of accesses to perform.
502 @param Buffer Pointer to the buffer read from memory.
504 @retval EFI_SUCCESS The data was written to the EFI System.
505 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
507 The Buffer is not aligned for the given Width.
508 @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count
509 is not valid for this EFI System.
514 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
527 Status
= BuildLoopData (Width
, Address
, &AddressStride
, &BufferStride
);
528 if (EFI_ERROR (Status
)) {
532 // Loop for each iteration and move the data
534 for (; Count
> 0; Count
--, Address
+= AddressStride
, Out
.Buf
+= BufferStride
) {
536 case S3BootScriptWidthUint8
:
537 case S3BootScriptWidthFifoUint8
:
538 case S3BootScriptWidthFillUint8
:
539 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN
)Address
));
540 *Out
.Uint8
= MmioRead8 ((UINTN
) Address
);
543 case S3BootScriptWidthUint16
:
544 case S3BootScriptWidthFifoUint16
:
545 case S3BootScriptWidthFillUint16
:
546 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN
)Address
));
547 *Out
.Uint16
= MmioRead16 ((UINTN
) Address
);
550 case S3BootScriptWidthUint32
:
551 case S3BootScriptWidthFifoUint32
:
552 case S3BootScriptWidthFillUint32
:
553 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN
)Address
));
554 *Out
.Uint32
= MmioRead32 ((UINTN
) Address
);
557 case S3BootScriptWidthUint64
:
558 case S3BootScriptWidthFifoUint64
:
559 case S3BootScriptWidthFillUint64
:
560 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN
)Address
));
561 *Out
.Uint64
= MmioRead64 ((UINTN
) Address
);
565 return EFI_UNSUPPORTED
;
572 Translates boot script to MDE library interface.
574 @param Width Width of the operation.
575 @param Address Address of the operation.
576 @param Count Count of the number of accesses to perform.
577 @param Buffer Pointer to the buffer write to memory.
579 @retval EFI_SUCCESS The data was written to the EFI System.
580 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
582 The Buffer is not aligned for the given Width.
583 @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count
584 is not valid for this EFI System.
589 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
597 UINT64 OriginalAddress
;
604 Status
= BuildLoopData (Width
, Address
, &AddressStride
, &BufferStride
);
605 if (EFI_ERROR (Status
)) {
609 // Loop for each iteration and move the data
611 OriginalAddress
= Address
;
612 OriginalIn
.Buf
= In
.Buf
;
613 for (; Count
> 0; Count
--, Address
+= AddressStride
, In
.Buf
+= BufferStride
) {
615 case S3BootScriptWidthUint8
:
616 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint8
));
617 MmioWrite8 ((UINTN
) Address
, *In
.Uint8
);
619 case S3BootScriptWidthFifoUint8
:
620 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", (UINTN
)OriginalAddress
, (UINTN
)*In
.Uint8
));
621 MmioWrite8 ((UINTN
) OriginalAddress
, *In
.Uint8
);
623 case S3BootScriptWidthFillUint8
:
624 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint8
));
625 MmioWrite8 ((UINTN
) Address
, *OriginalIn
.Uint8
);
627 case S3BootScriptWidthUint16
:
628 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint16
));
629 MmioWrite16 ((UINTN
) Address
, *In
.Uint16
);
631 case S3BootScriptWidthFifoUint16
:
632 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", (UINTN
)OriginalAddress
, (UINTN
)*In
.Uint16
));
633 MmioWrite16 ((UINTN
) OriginalAddress
, *In
.Uint16
);
635 case S3BootScriptWidthFillUint16
:
636 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint16
));
637 MmioWrite16 ((UINTN
) Address
, *OriginalIn
.Uint16
);
639 case S3BootScriptWidthUint32
:
640 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint32
));
641 MmioWrite32 ((UINTN
) Address
, *In
.Uint32
);
643 case S3BootScriptWidthFifoUint32
:
644 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", (UINTN
)OriginalAddress
, (UINTN
)*In
.Uint32
));
645 MmioWrite32 ((UINTN
) OriginalAddress
, *In
.Uint32
);
647 case S3BootScriptWidthFillUint32
:
648 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN
)Address
, (UINTN
)*In
.Uint32
));
649 MmioWrite32 ((UINTN
) Address
, *OriginalIn
.Uint32
);
651 case S3BootScriptWidthUint64
:
652 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint64 - 0x%08x (0x%016lx)\n", (UINTN
)Address
, *In
.Uint64
));
653 MmioWrite64 ((UINTN
) Address
, *In
.Uint64
);
655 case S3BootScriptWidthFifoUint64
:
656 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFifoUint64 - 0x%08x (0x%016lx)\n", (UINTN
)OriginalAddress
, *In
.Uint64
));
657 MmioWrite64 ((UINTN
) OriginalAddress
, *In
.Uint64
);
659 case S3BootScriptWidthFillUint64
:
660 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthFillUint64 - 0x%08x (0x%016lx)\n", (UINTN
)Address
, *In
.Uint64
));
661 MmioWrite64 ((UINTN
) Address
, *OriginalIn
.Uint64
);
664 return EFI_UNSUPPORTED
;
670 Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_WRITE OP code.
672 @param[in] Script Pointer to the node which is to be interpreted.
674 @retval EFI_SUCCESS The data was written to the EFI System.
675 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
677 The Buffer is not aligned for the given Width.
678 @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count
679 is not valid for this EFI System.
683 BootScriptExecuteMemoryWrite (
688 S3_BOOT_SCRIPT_LIB_WIDTH Width
;
691 EFI_BOOT_SCRIPT_MEM_WRITE MemWrite
;
693 CopyMem((VOID
*)&MemWrite
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_MEM_WRITE
));
694 Width
= (S3_BOOT_SCRIPT_LIB_WIDTH
)MemWrite
.Width
;
695 Address
= MemWrite
.Address
;
696 Count
= MemWrite
.Count
;
697 Buffer
= Script
+ sizeof(EFI_BOOT_SCRIPT_MEM_WRITE
);
699 DEBUG ((EFI_D_INFO
, "BootScriptExecuteMemoryWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN
)Address
, (UINTN
)Count
, (UINTN
)Width
));
700 return ScriptMemoryWrite (Width
,Address
, Count
, Buffer
);
704 Translates boot script to MDE library interface for PCI configuration read operation
706 @param Width Width of the operation.
707 @param Address Address of the operation.
708 @param Buffer Pointer to the buffer reaf from PCI config space
710 @retval EFI_SUCCESS The read succeed.
711 @retval EFI_INVALID_PARAMETER if Width is not defined
716 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
722 case S3BootScriptWidthUint8
:
723 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint8 - 0x%016lx\n", Address
));
724 * (UINT8
*) Buffer
= PciRead8 (PCI_ADDRESS_ENCODE(Address
));
727 case S3BootScriptWidthUint16
:
728 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint16 - 0x%016lx\n", Address
));
729 * (UINT16
*) Buffer
= PciRead16 (PCI_ADDRESS_ENCODE(Address
));
732 case S3BootScriptWidthUint32
:
733 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint32 - 0x%016lx\n", Address
));
734 * (UINT32
*) Buffer
= PciRead32 (PCI_ADDRESS_ENCODE(Address
));
738 return EFI_INVALID_PARAMETER
;
744 Translates boot script to MDE library interface for PCI configuration write operation
746 @param Width Width of the operation.
747 @param Address Address of the operation.
748 @param Buffer Pointer to the buffer reaf from PCI config space
750 @retval EFI_SUCCESS The write succeed.
751 @retval EFI_INVALID_PARAMETER if Width is not defined
756 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
762 case S3BootScriptWidthUint8
:
763 case S3BootScriptWidthFifoUint8
:
764 case S3BootScriptWidthFillUint8
:
765 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint8 - 0x%016lx (0x%02x)\n", Address
, (UINTN
)*(UINT8
*) Buffer
));
766 PciWrite8 (PCI_ADDRESS_ENCODE(Address
), *(UINT8
*) Buffer
);
768 case S3BootScriptWidthUint16
:
769 case S3BootScriptWidthFifoUint16
:
770 case S3BootScriptWidthFillUint16
:
771 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint16 - 0x%016lx (0x%04x)\n", Address
, (UINTN
)*(UINT16
*) Buffer
));
772 PciWrite16 (PCI_ADDRESS_ENCODE(Address
), *(UINT16
*) Buffer
);
774 case S3BootScriptWidthUint32
:
775 case S3BootScriptWidthFifoUint32
:
776 case S3BootScriptWidthFillUint32
:
777 DEBUG ((EFI_D_INFO
, "S3BootScriptWidthUint32 - 0x%016lx (0x%08x)\n", Address
, (UINTN
)*(UINT32
*) Buffer
));
778 PciWrite32 (PCI_ADDRESS_ENCODE(Address
), *(UINT32
*) Buffer
);
781 return EFI_INVALID_PARAMETER
;
786 Perform pci configure 2 read operation.
788 @param Width Width of the operation.
789 @param Segment Pci segment number
790 @param Address Address of the operation.
791 @param Buffer Pointer to the buffer to write to I/O space.
793 @retval EFI_SUCCESS The data was written to the EFI System.
794 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
796 The Buffer is not aligned for the given Width.
797 Address is outside the legal range of I/O ports.
798 @note A known Limitations in the implementation which is the 'Segment' parameter is assumed as
799 Zero, or else, assert.
803 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
811 return ScriptPciCfgRead (Width
, Address
, Buffer
);
814 Perform pci configure write operation.
816 @param Width Width of the operation.
817 @param Segment Pci segment number
818 @param Address Address of the operation.
819 @param Buffer Pointer to the buffer to write to I/O space.
821 @retval EFI_SUCCESS The data was written to the EFI System.
822 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
824 The Buffer is not aligned for the given Width.
825 Address is outside the legal range of I/O ports.
826 @note A known Limitations in the implementation which is the 'Segment' parameter is assumed as
827 Zero, or else, assert.
833 IN S3_BOOT_SCRIPT_LIB_WIDTH Width
,
840 return ScriptPciCfgWrite (Width
, Address
, Buffer
);
843 Perform Pci configuration Write operation.
845 @param Script The pointer of typed node in boot script table
847 @retval EFI_SUCCESS The operation was executed successfully
850 BootScriptExecutePciCfgWrite (
860 EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE PciConfigWrite
;
862 CopyMem ((VOID
*)&PciConfigWrite
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE
));
863 Status
= EFI_SUCCESS
;
865 PciAddress
= PciConfigWrite
.Address
;
866 DataWidth
= (UINT32
)(0x01 << (PciConfigWrite
.Width
));
867 Buffer
= Script
+ sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE
);
869 DEBUG ((EFI_D_INFO
, "BootScriptExecutePciCfgWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN
)PciAddress
, (UINTN
)PciConfigWrite
.Count
, (UINTN
)DataWidth
));
871 for (Index
= 0; Index
< PciConfigWrite
.Count
; Index
++) {
872 Status
= ScriptPciCfgWrite (
873 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciConfigWrite
.Width
,
878 if ( S3BootScriptWidthFillUint8
!= PciConfigWrite
.Width
||
879 S3BootScriptWidthFillUint16
!= PciConfigWrite
.Width
||
880 S3BootScriptWidthFillUint32
!= PciConfigWrite
.Width
||
881 S3BootScriptWidthFillUint64
!= PciConfigWrite
.Width
){
882 Reg
= (UINT8
) ((UINT8
) PciAddress
+ DataWidth
);
883 PciAddress
= (PciAddress
& 0xFFFFFFFFFFFFFF00ULL
) + Reg
;
886 if (S3BootScriptWidthFifoUint8
!= PciConfigWrite
.Width
||
887 S3BootScriptWidthFifoUint16
!= PciConfigWrite
.Width
||
888 S3BootScriptWidthFifoUint32
!= PciConfigWrite
.Width
||
889 S3BootScriptWidthFifoUint64
!= PciConfigWrite
.Width
) {
897 Excute the script to perform IO modification operation.
899 @param Script The pointer of typed node in boot script table
900 @param AndMask Mask value for 'and' operation
901 @param OrMask Mask value for 'or' operation
903 @retval EFI_SUCCESS The operation was executed successfully
906 BootScriptExecuteIoReadWrite (
915 EFI_BOOT_SCRIPT_IO_READ_WRITE IoReadWrite
;
919 CopyMem((VOID
*)&IoReadWrite
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_IO_READ_WRITE
));
921 DEBUG ((EFI_D_INFO
, "BootScriptExecuteIoReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN
)IoReadWrite
.Address
, (UINT64
)AndMask
, (UINT64
)OrMask
));
923 Status
= ScriptIoRead (
924 (S3_BOOT_SCRIPT_LIB_WIDTH
) IoReadWrite
.Width
,
929 if (!EFI_ERROR (Status
)) {
930 Data
= (Data
& AndMask
) | OrMask
;
931 Status
= ScriptIoWrite (
932 (S3_BOOT_SCRIPT_LIB_WIDTH
) IoReadWrite
.Width
,
941 Excute the script to perform memory modification operation.
943 @param Script The pointer of typed node in boot script table
944 @param AndMask Mask value for 'and' operation
945 @param OrMask Mask value for 'or' operation
947 @retval EFI_SUCCESS The operation was executed successfully
950 BootScriptExecuteMemoryReadWrite (
959 EFI_BOOT_SCRIPT_MEM_READ_WRITE MemReadWrite
;
963 CopyMem((VOID
*)&MemReadWrite
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_MEM_READ_WRITE
));
965 DEBUG ((EFI_D_INFO
, "BootScriptExecuteMemoryReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN
)MemReadWrite
.Address
, (UINT64
)AndMask
, (UINT64
)OrMask
));
967 Status
= ScriptMemoryRead (
968 (S3_BOOT_SCRIPT_LIB_WIDTH
) MemReadWrite
.Width
,
969 MemReadWrite
.Address
,
973 if (!EFI_ERROR (Status
)) {
974 Data
= (Data
& AndMask
) | OrMask
;
975 Status
= ScriptMemoryWrite (
976 (S3_BOOT_SCRIPT_LIB_WIDTH
) MemReadWrite
.Width
,
977 MemReadWrite
.Address
,
985 Excute the script to perform PCI IO modification operation.
987 @param Script The pointer of typed node in boot script table
988 @param AndMask Mask value for 'and' operation
989 @param OrMask Mask value for 'or' operation
991 @retval EFI_SUCCESS The operation was executed successfully
994 BootScriptExecutePciCfgReadWrite (
1003 EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE PciCfgReadWrite
;
1005 CopyMem((VOID
*)&PciCfgReadWrite
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE
));
1007 DEBUG ((EFI_D_INFO
, "BootScriptExecutePciCfgReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN
)PciCfgReadWrite
.Address
, (UINT64
)AndMask
, (UINT64
)OrMask
));
1009 Status
= ScriptPciCfgRead (
1010 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfgReadWrite
.Width
,
1011 PciCfgReadWrite
.Address
,
1014 if (EFI_ERROR (Status
)) {
1018 Data
= (Data
& AndMask
) | OrMask
;
1020 Status
= ScriptPciCfgWrite (
1021 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfgReadWrite
.Width
,
1022 PciCfgReadWrite
.Address
,
1029 To Execute SMBUS command.
1031 @param Script The pointer of typed node in boot script table
1033 @retval EFI_SUCCESS The operation was executed successfully
1034 @retval EFI_UNSUPPORTED Cannot locate smbus ppi or occur error of script execution
1035 @retval Others Result of script execution
1038 BootScriptExecuteSmbusExecute (
1044 EFI_BOOT_SCRIPT_SMBUS_EXECUTE SmbusExecuteEntry
;
1046 CopyMem ((VOID
*)&SmbusExecuteEntry
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_SMBUS_EXECUTE
));
1048 DEBUG ((EFI_D_INFO
, "BootScriptExecuteSmbusExecute - 0x%08x, 0x%08x\n", (UINTN
)SmbusExecuteEntry
.SmBusAddress
, (UINTN
)SmbusExecuteEntry
.Operation
));
1050 SmBusAddress
= (UINTN
)SmbusExecuteEntry
.SmBusAddress
;
1051 DataSize
= (UINTN
) SmbusExecuteEntry
.DataSize
;
1052 return SmbusExecute (
1054 (EFI_SMBUS_OPERATION
) SmbusExecuteEntry
.Operation
,
1056 Script
+ sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE
)
1060 Execute stall operation in boot script table.
1062 @param Script The pointer of typed node in boot script table
1064 @retval EFI_SUCCESS The operation was executed successfully
1067 BootScriptExecuteStall (
1071 EFI_BOOT_SCRIPT_STALL Stall
;
1073 CopyMem ((VOID
*)&Stall
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_STALL
));
1075 DEBUG ((EFI_D_INFO
, "BootScriptExecuteStall - 0x%08x\n", (UINTN
)Stall
.Duration
));
1077 MicroSecondDelay ((UINTN
) Stall
.Duration
);
1081 To execute assigned function.
1083 @param Script The pointer of typed node in boot script table
1084 @retval EFI_SUCCESS The operation was executed successfully
1087 BootScriptExecuteDispatch (
1092 DISPATCH_ENTRYPOINT_FUNC EntryFunc
;
1093 EFI_BOOT_SCRIPT_DISPATCH ScriptDispatch
;
1095 CopyMem ((VOID
*)&ScriptDispatch
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_DISPATCH
));
1096 EntryFunc
= (DISPATCH_ENTRYPOINT_FUNC
) (UINTN
) (ScriptDispatch
.EntryPoint
);
1098 DEBUG ((EFI_D_INFO
, "BootScriptExecuteDispatch - 0x%08x\n", (UINTN
)ScriptDispatch
.EntryPoint
));
1100 Status
= EntryFunc (NULL
, NULL
);
1105 Execute dispach2 opertion code which is to invoke a spcified function with one parameter.
1107 @param Script The pointer of typed node in boot script table
1108 @retval EFI_SUCCESS The operation was executed successfully
1111 BootScriptExecuteDispatch2 (
1116 DISPATCH_ENTRYPOINT_FUNC EntryFunc
;
1117 EFI_BOOT_SCRIPT_DISPATCH_2 ScriptDispatch2
;
1119 CopyMem ((VOID
*)&ScriptDispatch2
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_DISPATCH_2
));
1121 DEBUG ((EFI_D_INFO
, "BootScriptExecuteDispatch2 - 0x%08x(0x%08x)\n", (UINTN
)ScriptDispatch2
.EntryPoint
, (UINTN
)ScriptDispatch2
.Context
));
1123 EntryFunc
= (DISPATCH_ENTRYPOINT_FUNC
) (UINTN
) (ScriptDispatch2
.EntryPoint
);
1125 Status
= EntryFunc (NULL
, (VOID
*) (UINTN
) ScriptDispatch2
.Context
);
1130 Excute the script to poll memory.
1132 @param Script The pointer of typed node in boot script table
1133 @param AndMask Mask value for 'and' operation
1134 @param OrMask Mask value for 'or' operation
1136 @retval EFI_DEVICE_ERROR Data polled from memory does not equal to
1137 the epecting data within the Loop Times.
1138 @retval EFI_SUCCESS The operation was executed successfully
1141 BootScriptExecuteMemPoll (
1151 EFI_BOOT_SCRIPT_MEM_POLL MemPoll
;
1153 CopyMem ((VOID
*)&MemPoll
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_MEM_POLL
));
1155 DEBUG ((EFI_D_INFO
, "BootScriptExecuteMemPoll - 0x%08x\n", (UINTN
)MemPoll
.Address
));
1158 Status
= ScriptMemoryRead (
1159 (S3_BOOT_SCRIPT_LIB_WIDTH
) MemPoll
.Width
,
1164 if ((!EFI_ERROR (Status
)) && (Data
& AndMask
) == OrMask
) {
1168 for (LoopTimes
= 0; LoopTimes
< MemPoll
.LoopTimes
; LoopTimes
++) {
1169 NanoSecondDelay ((UINTN
)MemPoll
.Duration
);
1172 Status
= ScriptMemoryRead (
1173 (S3_BOOT_SCRIPT_LIB_WIDTH
) MemPoll
.Width
,
1178 if ((!EFI_ERROR (Status
)) && (Data
& AndMask
) == OrMask
) {
1183 if (LoopTimes
< MemPoll
.LoopTimes
) {
1186 return EFI_DEVICE_ERROR
;
1190 Execute the boot script to interpret the Store arbitrary information.
1191 This opcode is a no-op on dispatch and is only used for debugging script issues.
1193 @param Script The pointer of node in boot script table
1197 BootScriptExecuteInformation (
1203 for (Index
= 0; Index
< 10; Index
++);
1206 calculate the mask value for 'and' and 'or' operation
1207 @param ScriptHeader The pointer of header of node in boot script table
1208 @param AndMask The Mask value for 'and' operation
1209 @param OrMask The Mask value for 'or' operation
1210 @param Script Pointer to the entry.
1215 IN EFI_BOOT_SCRIPT_COMMON_HEADER
*ScriptHeader
,
1216 OUT UINT64
*AndMask
,
1224 switch (ScriptHeader
->OpCode
) {
1225 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE
:
1226 Size
= sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE
);
1229 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE
:
1230 Size
= sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE
);
1233 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE
:
1234 Size
= sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE
);
1236 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE
:
1237 Size
= sizeof (EFI_BOOT_SCRIPT_MEM_POLL
);
1240 case EFI_BOOT_SCRIPT_IO_POLL_OPCODE
:
1241 Size
= sizeof (EFI_BOOT_SCRIPT_IO_POLL
);
1244 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE
:
1245 Size
= sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE
);
1248 case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE
:
1249 Size
= sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL
);
1252 case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE
:
1253 Size
= sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL
);
1260 DataPtr
= Script
+ Size
;
1262 switch (ScriptHeader
->Width
) {
1263 case S3BootScriptWidthUint8
:
1264 *AndMask
= (UINT64
) *(DataPtr
+ 1);
1265 *OrMask
= (UINT64
) (*DataPtr
);
1268 case S3BootScriptWidthUint16
:
1269 *AndMask
= (UINT64
) (*(UINT16
*) (DataPtr
+ 2));
1270 *OrMask
= (UINT64
) (*(UINT16
*) DataPtr
);
1273 case S3BootScriptWidthUint32
:
1274 *AndMask
= (UINT64
) (*(UINT32
*) (DataPtr
+ 4));
1275 *OrMask
= (UINT64
) (*(UINT32
*) DataPtr
);
1278 case S3BootScriptWidthUint64
:
1279 *AndMask
= (UINT64
) (*(UINT64
*) (DataPtr
+ 8));
1280 *OrMask
= (UINT64
) (*(UINT64
*) DataPtr
);
1290 Excute the script to poll Io port for some time
1292 @param Script The pointer of typed node in boot script table
1293 @param AndMask Mask value for 'and' operation
1294 @param OrMask Mask value for 'or' operation
1296 @retval EFI_DEVICE_ERROR Data polled from memory does not equal to
1297 the epecting data within the Loop Times.
1298 @retval EFI_SUCCESS The operation was executed successfully
1301 BootScriptExecuteIoPoll (
1310 EFI_BOOT_SCRIPT_IO_POLL IoPoll
;
1312 CopyMem ((VOID
*)&IoPoll
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_IO_POLL
));
1314 DEBUG ((EFI_D_INFO
, "BootScriptExecuteIoPoll - 0x%08x\n", (UINTN
)IoPoll
.Address
));
1317 Status
= ScriptIoRead (
1318 (S3_BOOT_SCRIPT_LIB_WIDTH
) IoPoll
.Width
,
1323 if ((!EFI_ERROR (Status
)) && (Data
& AndMask
) == OrMask
) {
1326 for (LoopTimes
= 0; LoopTimes
< IoPoll
.Delay
; LoopTimes
++) {
1327 NanoSecondDelay (100);
1329 Status
= ScriptIoRead (
1330 (S3_BOOT_SCRIPT_LIB_WIDTH
) IoPoll
.Width
,
1335 if ((!EFI_ERROR (Status
)) &&(Data
& AndMask
) == OrMask
) {
1340 if (LoopTimes
< IoPoll
.Delay
) {
1343 return EFI_DEVICE_ERROR
;
1347 Perform Pci configuration Write operation.
1349 @param Script The pointer of S3 boot script
1351 @retval EFI_SUCCESS The operation was executed successfully
1355 BootScriptExecutePciCfg2Write (
1366 EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE PciCfg2Write
;
1368 CopyMem ((VOID
*)&PciCfg2Write
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE
));
1369 Status
= EFI_SUCCESS
;
1370 Segment
= PciCfg2Write
.Segment
;
1371 PciAddress
= PciCfg2Write
.Address
;
1372 DataWidth
= (UINT32
)(0x01 << (PciCfg2Write
.Width
));
1373 Buffer
= Script
+ sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE
);
1375 DEBUG ((EFI_D_INFO
, "BootScriptExecutePciCfg2Write - 0x%08x\n", (UINTN
)PciAddress
));
1377 for (Index
= 0; Index
< PciCfg2Write
.Count
; Index
++) {
1378 Status
= ScriptPciCfg2Write (
1379 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfg2Write
.Width
,
1384 if (S3BootScriptWidthFillUint8
!= PciCfg2Write
.Width
||
1385 S3BootScriptWidthFillUint16
!= PciCfg2Write
.Width
||
1386 S3BootScriptWidthFillUint32
!= PciCfg2Write
.Width
||
1387 S3BootScriptWidthFillUint64
!= PciCfg2Write
.Width
){
1388 Reg
= (UINT8
) ((UINT8
) PciAddress
+ DataWidth
);
1389 PciAddress
= (PciAddress
& 0xFFFFFFFFFFFFFF00ULL
) + Reg
;
1392 if (S3BootScriptWidthFifoUint8
!= PciCfg2Write
.Width
||
1393 S3BootScriptWidthFifoUint16
!= PciCfg2Write
.Width
||
1394 S3BootScriptWidthFifoUint32
!= PciCfg2Write
.Width
||
1395 S3BootScriptWidthFifoUint64
!= PciCfg2Write
.Width
) {
1396 Buffer
+= DataWidth
;
1404 Perform pci configuration read & Write operation.
1406 @param Script The pointer of S3 boot script
1407 @param AndMask Mask value for 'and' operation
1408 @param OrMask Mask value for 'or' operation
1410 @retval EFI_SUCCESS The operation was executed successfully
1414 BootScriptExecutePciCfg2ReadWrite (
1422 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE PciCfg2ReadWrite
;
1423 CopyMem ((VOID
*)&PciCfg2ReadWrite
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE
));
1425 DEBUG ((EFI_D_INFO
, "BootScriptExecutePciCfg2ReadWrite - 0x%08x\n", (UINTN
)PciCfg2ReadWrite
.Address
));
1427 Status
= ScriptPciCfg2Read (
1428 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfg2ReadWrite
.Width
,
1429 PciCfg2ReadWrite
.Segment
,
1430 PciCfg2ReadWrite
.Address
,
1433 if (EFI_ERROR (Status
)) {
1437 Data
= (Data
& AndMask
) | OrMask
;
1438 Status
= ScriptPciCfg2Write (
1439 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfg2ReadWrite
.Width
,
1440 PciCfg2ReadWrite
.Segment
,
1441 PciCfg2ReadWrite
.Address
,
1447 To perform poll pci configure operation.
1449 @param Script The pointer of S3 boot script
1450 @param AndMask Mask value for 'and' operation
1451 @param OrMask Mask value for 'or' operation
1453 @retval EFI_SUCCESS The operation was executed successfully
1454 @retval EFI_DEVICE_ERROR Data polled from Pci configuration space does not equal to
1455 epecting data within the Loop Times.
1458 BootScriptPciCfgPoll (
1467 EFI_BOOT_SCRIPT_PCI_CONFIG_POLL PciCfgPoll
;
1468 CopyMem ((VOID
*)&PciCfgPoll
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_POLL
));
1470 DEBUG ((EFI_D_INFO
, "BootScriptPciCfgPoll - 0x%08x\n", (UINTN
)PciCfgPoll
.Address
));
1473 Status
= ScriptPciCfgRead (
1474 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfgPoll
.Width
,
1478 if ((!EFI_ERROR (Status
)) &&(Data
& AndMask
) == OrMask
) {
1482 for (LoopTimes
= 0; LoopTimes
< PciCfgPoll
.Delay
; LoopTimes
++) {
1483 NanoSecondDelay (100);
1485 Status
= ScriptPciCfgRead (
1486 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfgPoll
.Width
,
1490 if ((!EFI_ERROR (Status
)) &&
1491 (Data
& AndMask
) == OrMask
) {
1496 if (LoopTimes
< PciCfgPoll
.Delay
) {
1499 return EFI_DEVICE_ERROR
;
1504 To perform poll pci configure operation.
1506 @param Script The pointer of S3 Boot Script
1507 @param AndMask Mask value for 'and' operation
1508 @param OrMask Mask value for 'or' operation
1510 @retval EFI_SUCCESS The operation was executed successfully
1511 @retval EFI_DEVICE_ERROR Data polled from Pci configuration space does not equal to
1512 epecting data within the Loop Times.
1516 BootScriptPciCfg2Poll (
1525 EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL PciCfg2Poll
;
1528 CopyMem ((VOID
*)&PciCfg2Poll
, (VOID
*)Script
, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL
));
1530 DEBUG ((EFI_D_INFO
, "BootScriptPciCfg2Poll - 0x%08x\n", (UINTN
)PciCfg2Poll
.Address
));
1532 Status
= ScriptPciCfg2Read (
1533 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfg2Poll
.Width
,
1534 PciCfg2Poll
.Segment
,
1535 PciCfg2Poll
.Address
,
1538 if ((!EFI_ERROR (Status
)) && (Data
& AndMask
) == OrMask
) {
1542 for (LoopTimes
= 0; LoopTimes
< PciCfg2Poll
.Delay
; LoopTimes
++) {
1543 NanoSecondDelay (100);
1546 Status
= ScriptPciCfg2Read (
1547 (S3_BOOT_SCRIPT_LIB_WIDTH
) PciCfg2Poll
.Width
,
1548 PciCfg2Poll
.Segment
,
1549 PciCfg2Poll
.Address
,
1552 if ((!EFI_ERROR (Status
)) && (Data
& AndMask
) == OrMask
) {
1557 if (LoopTimes
< PciCfg2Poll
.Delay
) {
1560 return EFI_DEVICE_ERROR
;
1566 Executes the S3 boot script table.
1568 @retval RETURN_SUCCESS The boot script table was executed successfully.
1569 @retval RETURN_UNSUPPORTED Invalid script table or opcode.
1571 @note A known Limitations in the implementation: When interpreting the opcode EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE
1572 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE and EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE, the 'Segment' parameter is assumed as
1573 Zero, or else, assert.
1577 S3BootScriptExecute (
1587 EFI_BOOT_SCRIPT_COMMON_HEADER ScriptHeader
;
1588 EFI_BOOT_SCRIPT_TABLE_HEADER TableHeader
;
1589 Script
= mS3BootScriptTablePtr
->TableBase
;
1591 CopyMem ((VOID
*)&TableHeader
, Script
, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER
));
1593 return EFI_INVALID_PARAMETER
;
1596 DEBUG ((EFI_D_INFO
, "S3BootScriptExecute:\n"));
1597 if (TableHeader
.OpCode
!= S3_BOOT_SCRIPT_LIB_TABLE_OPCODE
) {
1598 return EFI_UNSUPPORTED
;
1601 DEBUG ((EFI_D_INFO
, "TableHeader - 0x%08x\n", Script
));
1603 StartAddress
= (UINTN
) Script
;
1604 TableLength
= TableHeader
.TableLength
;
1605 Script
= Script
+ TableHeader
.Length
;
1606 Status
= EFI_SUCCESS
;
1610 DEBUG ((EFI_D_INFO
, "TableHeader.TableLength - 0x%08x\n", (UINTN
)TableLength
));
1612 while ((UINTN
) Script
< (UINTN
) (StartAddress
+ TableLength
)) {
1613 DEBUG ((EFI_D_INFO
, "ExecuteBootScript - %08x\n", (UINTN
)Script
));
1615 CopyMem ((VOID
*)&ScriptHeader
, Script
, sizeof(EFI_BOOT_SCRIPT_COMMON_HEADER
));
1616 switch (ScriptHeader
.OpCode
) {
1618 case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE
:
1619 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE\n"));
1620 Status
= BootScriptExecuteMemoryWrite (Script
);
1623 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE
:
1624 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE\n"));
1625 CheckAndOrMask (&ScriptHeader
, &AndMask
, &OrMask
, Script
);
1626 Status
= BootScriptExecuteMemoryReadWrite (
1633 case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE
:
1634 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_IO_WRITE_OPCODE\n"));
1635 Status
= BootScriptExecuteIoWrite (Script
);
1638 case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE
:
1639 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE\n"));
1640 Status
= BootScriptExecutePciCfgWrite (Script
);
1643 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE
:
1644 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE\n"));
1645 CheckAndOrMask (&ScriptHeader
, &AndMask
, &OrMask
, Script
);
1646 Status
= BootScriptExecutePciCfgReadWrite (
1652 case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE
:
1653 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\n"));
1654 Status
= BootScriptExecutePciCfg2Write (Script
);
1657 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE
:
1658 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE\n"));
1659 CheckAndOrMask (&ScriptHeader
, &AndMask
, &OrMask
, Script
);
1660 Status
= BootScriptExecutePciCfg2ReadWrite (
1666 case EFI_BOOT_SCRIPT_DISPATCH_OPCODE
:
1667 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_DISPATCH_OPCODE\n"));
1668 Status
= BootScriptExecuteDispatch (Script
);
1671 case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE
:
1672 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE\n"));
1673 Status
= BootScriptExecuteDispatch2 (Script
);
1676 case EFI_BOOT_SCRIPT_INFORMATION_OPCODE
:
1677 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_INFORMATION_OPCODE\n"));
1678 BootScriptExecuteInformation (Script
);
1681 case S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE
:
1682 DEBUG ((EFI_D_INFO
, "S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE\n"));
1685 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE
:
1686 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE\n"));
1687 CheckAndOrMask (&ScriptHeader
, &AndMask
, &OrMask
, Script
);
1688 Status
= BootScriptExecuteIoReadWrite (
1695 case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE
:
1696 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE\n"));
1697 Status
= BootScriptExecuteSmbusExecute (Script
);
1700 case EFI_BOOT_SCRIPT_STALL_OPCODE
:
1701 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_STALL_OPCODE\n"));
1702 Status
= BootScriptExecuteStall (Script
);
1705 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE
:
1706 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_MEM_POLL_OPCODE\n"));
1707 CheckAndOrMask (&ScriptHeader
, &AndMask
, &OrMask
, Script
);
1708 Status
= BootScriptExecuteMemPoll (Script
, AndMask
, OrMask
);
1712 case EFI_BOOT_SCRIPT_IO_POLL_OPCODE
:
1713 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_IO_POLL_OPCODE\n"));
1714 CheckAndOrMask (&ScriptHeader
, &AndMask
, &OrMask
, Script
);
1715 Status
= BootScriptExecuteIoPoll (Script
, AndMask
, OrMask
);
1718 case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE
:
1719 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE\n"));
1720 CheckAndOrMask (&ScriptHeader
, &AndMask
, &OrMask
, Script
);
1721 Status
= BootScriptPciCfgPoll (Script
, AndMask
, OrMask
);
1724 case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE
:
1725 DEBUG ((EFI_D_INFO
, "EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE\n"));
1726 CheckAndOrMask (&ScriptHeader
, &AndMask
, &OrMask
, Script
);
1727 Status
= BootScriptPciCfg2Poll (Script
, AndMask
, OrMask
);
1730 case S3_BOOT_SCRIPT_LIB_LABEL_OPCODE
:
1734 DEBUG ((EFI_D_INFO
, "S3_BOOT_SCRIPT_LIB_LABEL_OPCODE\n"));
1737 DEBUG ((EFI_D_INFO
, "S3BootScriptDone - %r\n", EFI_UNSUPPORTED
));
1738 return EFI_UNSUPPORTED
;
1741 if (EFI_ERROR (Status
)) {
1742 DEBUG ((EFI_D_INFO
, "S3BootScriptDone - %r\n", Status
));
1746 Script
= Script
+ ScriptHeader
.Length
;
1749 DEBUG ((EFI_D_INFO
, "S3BootScriptDone - %r\n", Status
));