]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c
ShellPkg: Updates to 'help' command
[mirror_edk2.git] / MdeModulePkg / Library / PiDxeS3BootScriptLib / BootScriptExecute.c
CommitLineData
64d14edf 1/** @file\r
2 Interpret and execute the S3 data in S3 boot script. \r
3\r
8e4585bb 4 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
64d14edf 5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions\r
8 of the BSD License which accompanies this distribution. The\r
9 full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16#include "InternalBootScriptLib.h"\r
17\r
18/**\r
19 Checks the parameter of SmbusExecute().\r
20\r
21 This function checks the input parameters of SmbusExecute(). If the input parameters are valid\r
22 for certain SMBus bus protocol, it will return EFI_SUCCESS; otherwise, it will return certain\r
23 error code based on the input SMBus bus protocol.\r
24\r
25 @param SmBusAddress Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length, \r
26 and PEC.\r
27 @param Operation Signifies which particular SMBus hardware protocol instance that\r
28 it will use to execute the SMBus transactions. This SMBus\r
29 hardware protocol is defined by the SMBus Specification and is\r
30 not related to EFI.\r
31 @param Length Signifies the number of bytes that this operation will do. The\r
32 maximum number of bytes can be revision specific and operation\r
33 specific. This field will contain the actual number of bytes that\r
34 are executed for this operation. Not all operations require this\r
35 argument.\r
36 @param Buffer Contains the value of data to execute to the SMBus slave device.\r
37 Not all operations require this argument. The length of this\r
38 buffer is identified by Length.\r
39\r
40 @retval EFI_SUCCESS All the parameters are valid for the corresponding SMBus bus\r
41 protocol. \r
42 @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.\r
43 @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead\r
44 and EfiSmbusQuickWrite. Length is outside the range of valid\r
45 values.\r
46 @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.\r
47 @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.\r
48\r
49**/\r
50EFI_STATUS\r
51CheckParameters (\r
52 IN UINTN SmBusAddress,\r
53 IN EFI_SMBUS_OPERATION Operation,\r
54 IN OUT UINTN *Length,\r
55 IN OUT VOID *Buffer\r
56 )\r
57{\r
58 EFI_STATUS Status;\r
59 UINTN RequiredLen;\r
60 EFI_SMBUS_DEVICE_COMMAND Command;\r
61 BOOLEAN PecCheck;\r
62 \r
63 Command = SMBUS_LIB_COMMAND (SmBusAddress);\r
64 PecCheck = SMBUS_LIB_PEC (SmBusAddress);\r
65 //\r
66 // Set default value to be 2:\r
67 // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall. \r
68 //\r
69 RequiredLen = 2;\r
70 Status = EFI_SUCCESS;\r
71 switch (Operation) {\r
72 case EfiSmbusQuickRead:\r
73 case EfiSmbusQuickWrite:\r
74 if (PecCheck || Command != 0) {\r
75 return EFI_UNSUPPORTED;\r
76 }\r
77 break;\r
78 case EfiSmbusReceiveByte:\r
79 case EfiSmbusSendByte:\r
80 if (Command != 0) {\r
81 return EFI_UNSUPPORTED;\r
82 }\r
83 //\r
84 // Cascade to check length parameter.\r
85 //\r
86 case EfiSmbusReadByte:\r
87 case EfiSmbusWriteByte:\r
88 RequiredLen = 1;\r
89 //\r
90 // Cascade to check length parameter.\r
91 //\r
92 case EfiSmbusReadWord:\r
93 case EfiSmbusWriteWord:\r
94 case EfiSmbusProcessCall:\r
95 if (Buffer == NULL || Length == NULL) {\r
96 return EFI_INVALID_PARAMETER;\r
97 } else if (*Length < RequiredLen) {\r
98 Status = EFI_BUFFER_TOO_SMALL;\r
99 }\r
100 *Length = RequiredLen;\r
101 break;\r
102 case EfiSmbusReadBlock:\r
103 case EfiSmbusWriteBlock:\r
104 if ((Buffer == NULL) || \r
105 (Length == NULL) || \r
106 (*Length < MIN_SMBUS_BLOCK_LEN) ||\r
107 (*Length > MAX_SMBUS_BLOCK_LEN)) {\r
108 return EFI_INVALID_PARAMETER;\r
109 } \r
110 break;\r
111 case EfiSmbusBWBRProcessCall:\r
112 return EFI_UNSUPPORTED;\r
113 default:\r
114 return EFI_INVALID_PARAMETER;\r
115 }\r
116 return Status;\r
117}\r
118\r
119/**\r
120 Executes an SMBus operation to an SMBus controller. Returns when either the command has been\r
121 executed or an error is encountered in doing the operation.\r
122\r
123 The SmbusExecute() function provides a standard way to execute an operation as defined in the System\r
124 Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus\r
125 slave devices accept this transaction or that this function returns with error.\r
126\r
127 @param SmbusAddress Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length, \r
128 and PEC.\r
129 @param Operation Signifies which particular SMBus hardware protocol instance that\r
130 it will use to execute the SMBus transactions. This SMBus\r
131 hardware protocol is defined by the SMBus Specification and is\r
132 not related to EFI.\r
133 @param Length Signifies the number of bytes that this operation will do. The\r
134 maximum number of bytes can be revision specific and operation\r
135 specific. This field will contain the actual number of bytes that\r
136 are executed for this operation. Not all operations require this\r
137 argument.\r
138 @param Buffer Contains the value of data to execute to the SMBus slave device.\r
139 Not all operations require this argument. The length of this\r
140 buffer is identified by Length.\r
141\r
142 @retval EFI_SUCCESS The last data that was returned from the access matched the poll\r
143 exit criteria.\r
144 @retval EFI_CRC_ERROR Checksum is not correct (PEC is incorrect).\r
145 @retval EFI_TIMEOUT Timeout expired before the operation was completed. Timeout is\r
146 determined by the SMBus host controller device.\r
147 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
148 @retval EFI_DEVICE_ERROR The request was not completed because a failure that was\r
149 reflected in the Host Status Register bit. Device errors are a\r
150 result of a transaction collision, illegal command field,\r
151 unclaimed cycle (host initiated), or bus errors (collisions).\r
152 @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.\r
153 @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead\r
154 and EfiSmbusQuickWrite. Length is outside the range of valid\r
155 values.\r
156 @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.\r
157 @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.\r
158\r
159**/\r
160EFI_STATUS\r
161SmbusExecute (\r
162 IN UINTN SmbusAddress,\r
163 IN EFI_SMBUS_OPERATION Operation,\r
164 IN OUT UINTN *Length,\r
165 IN OUT VOID *Buffer\r
166 )\r
167{\r
168 EFI_STATUS Status;\r
169 UINTN WorkBufferLen;\r
170 UINT8 WorkBuffer[MAX_SMBUS_BLOCK_LEN];\r
171\r
172 Status = CheckParameters (SmbusAddress, Operation, Length, Buffer);\r
173 if (EFI_ERROR (Status)) {\r
174 return Status;\r
175 }\r
176\r
177 switch (Operation) {\r
178 case EfiSmbusQuickRead:\r
179 DEBUG ((EFI_D_INFO, "EfiSmbusQuickRead - 0x%08x\n", SmbusAddress));\r
180 SmBusQuickRead (SmbusAddress, &Status);\r
181 break;\r
182 case EfiSmbusQuickWrite:\r
183 DEBUG ((EFI_D_INFO, "EfiSmbusQuickWrite - 0x%08x\n", SmbusAddress));\r
184 SmBusQuickWrite (SmbusAddress, &Status);\r
185 break;\r
186 case EfiSmbusReceiveByte:\r
187 DEBUG ((EFI_D_INFO, "EfiSmbusReceiveByte - 0x%08x\n", SmbusAddress));\r
188 *(UINT8 *) Buffer = SmBusReceiveByte (SmbusAddress, &Status);\r
189 break;\r
190 case EfiSmbusSendByte:\r
191 DEBUG ((EFI_D_INFO, "EfiSmbusReceiveByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *) Buffer));\r
192 SmBusSendByte (SmbusAddress, *(UINT8 *) Buffer, &Status);\r
193 break;\r
194 case EfiSmbusReadByte:\r
195 DEBUG ((EFI_D_INFO, "EfiSmbusReadByte - 0x%08x\n", SmbusAddress));\r
196 *(UINT8 *) Buffer = SmBusReadDataByte (SmbusAddress, &Status);\r
197 break;\r
198 case EfiSmbusWriteByte:\r
199 DEBUG ((EFI_D_INFO, "EfiSmbusWriteByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *) Buffer));\r
200 SmBusWriteDataByte (SmbusAddress, *(UINT8 *) Buffer, &Status);\r
201 break;\r
202 case EfiSmbusReadWord:\r
203 DEBUG ((EFI_D_INFO, "EfiSmbusReadWord - 0x%08x\n", SmbusAddress));\r
204 *(UINT16 *) Buffer = SmBusReadDataWord (SmbusAddress, &Status);\r
205 break;\r
206 case EfiSmbusWriteWord:\r
207 DEBUG ((EFI_D_INFO, "EfiSmbusWriteByte - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));\r
208 SmBusWriteDataWord (SmbusAddress, *(UINT16 *) Buffer, &Status);\r
209 break;\r
210 case EfiSmbusProcessCall:\r
211 DEBUG ((EFI_D_INFO, "EfiSmbusProcessCall - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));\r
212 *(UINT16 *) Buffer = SmBusProcessCall (SmbusAddress, *(UINT16 *) Buffer, &Status);\r
213 break;\r
214 case EfiSmbusReadBlock:\r
215 DEBUG ((EFI_D_INFO, "EfiSmbusReadBlock - 0x%08x\n", SmbusAddress));\r
216 WorkBufferLen = SmBusReadBlock (SmbusAddress, WorkBuffer, &Status);\r
217 if (!EFI_ERROR (Status)) {\r
218 //\r
219 // Read block transaction is complete successfully, and then\r
220 // check whether the output buffer is large enough. \r
221 //\r
222 if (*Length >= WorkBufferLen) {\r
223 CopyMem (Buffer, WorkBuffer, WorkBufferLen);\r
224 } else {\r
225 Status = EFI_BUFFER_TOO_SMALL;\r
226 }\r
227 *Length = WorkBufferLen;\r
228 }\r
229 break;\r
230 case EfiSmbusWriteBlock:\r
231 DEBUG ((EFI_D_INFO, "EfiSmbusWriteBlock - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));\r
232 SmBusWriteBlock ((SmbusAddress + SMBUS_LIB_ADDRESS (0, 0, (*Length), FALSE)) , Buffer, &Status);\r
233 break;\r
234 case EfiSmbusBWBRProcessCall:\r
235 //\r
236 // BUGBUG: Should this case be handled?\r
237 //\r
238 break;\r
239 }\r
240\r
241 return Status; \r
242}\r
243\r
244/**\r
245 Translates boot script width and address stride to MDE library interface.\r
246\r
247\r
248 @param Width Width of the operation.\r
249 @param Address Address of the operation.\r
250 @param AddressStride Instride for stepping input buffer.\r
251 @param BufferStride Outstride for stepping output buffer. \r
252\r
253 @retval EFI_SUCCESS Successful translation.\r
254 @retval EFI_INVALID_PARAMETER Width or Address is invalid.\r
255**/\r
256EFI_STATUS\r
257BuildLoopData (\r
258 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
259 IN UINT64 Address,\r
260 OUT UINTN *AddressStride,\r
261 OUT UINTN *BufferStride\r
262 )\r
263{\r
264 UINTN AlignMask;\r
265\r
266 if (Width >= S3BootScriptWidthMaximum) {\r
267 return EFI_INVALID_PARAMETER;\r
268 }\r
269\r
270 *AddressStride = (UINT32)(1 << (Width & 0x03));\r
271 *BufferStride = *AddressStride;\r
272\r
273 AlignMask = *AddressStride - 1;\r
274 if ((Address & AlignMask) != 0) {\r
275 return EFI_INVALID_PARAMETER;\r
276 }\r
277\r
278 if (Width >= S3BootScriptWidthFifoUint8 && Width <= S3BootScriptWidthFifoUint64) {\r
279 *AddressStride = 0;\r
280 }\r
281\r
282 if (Width >= S3BootScriptWidthFillUint8 && Width <= S3BootScriptWidthFillUint64) {\r
283 *BufferStride = 0;\r
284 }\r
285\r
286 return EFI_SUCCESS;\r
287}\r
288\r
289/**\r
30f80497 290 Perform IO read operation\r
64d14edf 291 \r
292 @param[in] Width Width of the operation.\r
293 @param[in] Address Address of the operation.\r
294 @param[in] Count Count of the number of accesses to perform.\r
295 @param[out] Buffer Pointer to the buffer to read from I/O space. \r
296\r
297 @retval EFI_SUCCESS The data was written to the EFI System.\r
298 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r
299 Buffer is NULL.\r
300 The Buffer is not aligned for the given Width.\r
301 Address is outside the legal range of I/O ports. \r
302 \r
303**/\r
304EFI_STATUS\r
305ScriptIoRead (\r
306 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
307 IN UINT64 Address,\r
308 IN UINTN Count,\r
309 OUT VOID *Buffer\r
310 )\r
311{\r
312 EFI_STATUS Status;\r
313 UINTN AddressStride;\r
314 UINTN BufferStride;\r
315 PTR Out;\r
316\r
317 Out.Buf = (UINT8 *) Buffer;\r
318\r
319 if (Address > MAX_IO_ADDRESS) {\r
320 return EFI_INVALID_PARAMETER;\r
321 }\r
322\r
323 Status = BuildLoopData (Width, Address, &AddressStride, &BufferStride);\r
324 if (EFI_ERROR (Status)) {\r
325 return Status;\r
326 }\r
327 //\r
328 // Loop for each iteration and move the data\r
329 //\r
330 for (; Count > 0; Count--, Address += AddressStride, Out.Buf += BufferStride) {\r
331 switch (Width) {\r
332\r
333 case S3BootScriptWidthUint8:\r
30f80497
SZ
334 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN) Address));\r
335 *Out.Uint8 = IoRead8 ((UINTN) Address);\r
336 break;\r
64d14edf 337 case S3BootScriptWidthFifoUint8:\r
30f80497
SZ
338 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", (UINTN) Address));\r
339 *Out.Uint8 = IoRead8 ((UINTN) Address);\r
340 break;\r
64d14edf 341 case S3BootScriptWidthFillUint8:\r
30f80497 342 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", (UINTN) Address));\r
64d14edf 343 *Out.Uint8 = IoRead8 ((UINTN) Address);\r
344 break;\r
345\r
346 case S3BootScriptWidthUint16:\r
30f80497
SZ
347 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN) Address));\r
348 *Out.Uint16 = IoRead16 ((UINTN) Address);\r
349 break;\r
64d14edf 350 case S3BootScriptWidthFifoUint16:\r
30f80497
SZ
351 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", (UINTN) Address));\r
352 *Out.Uint16 = IoRead16 ((UINTN) Address);\r
353 break;\r
64d14edf 354 case S3BootScriptWidthFillUint16:\r
30f80497 355 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", (UINTN) Address));\r
64d14edf 356 *Out.Uint16 = IoRead16 ((UINTN) Address);\r
357 break;\r
358\r
359 case S3BootScriptWidthUint32:\r
30f80497
SZ
360 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN) Address));\r
361 *Out.Uint32 = IoRead32 ((UINTN) Address);\r
362 break;\r
64d14edf 363 case S3BootScriptWidthFifoUint32:\r
30f80497
SZ
364 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", (UINTN) Address));\r
365 *Out.Uint32 = IoRead32 ((UINTN) Address);\r
366 break;\r
64d14edf 367 case S3BootScriptWidthFillUint32:\r
30f80497 368 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", (UINTN) Address));\r
64d14edf 369 *Out.Uint32 = IoRead32 ((UINTN) Address);\r
370 break;\r
371\r
30f80497
SZ
372 case S3BootScriptWidthUint64:\r
373 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN) Address));\r
374 *Out.Uint64 = IoRead64 ((UINTN) Address);\r
375 break;\r
376 case S3BootScriptWidthFifoUint64:\r
377 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x\n", (UINTN) Address));\r
378 *Out.Uint64 = IoRead64 ((UINTN) Address);\r
379 break;\r
380 case S3BootScriptWidthFillUint64:\r
381 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint64 - 0x%08x\n", (UINTN) Address));\r
382 *Out.Uint64 = IoRead64 ((UINTN) Address);\r
383 break;\r
384\r
64d14edf 385 default:\r
386 return EFI_INVALID_PARAMETER;\r
387 }\r
388 }\r
389\r
390 return EFI_SUCCESS;\r
391}\r
392\r
393/**\r
30f80497 394 Perform IO write operation\r
64d14edf 395 \r
396 @param[in] Width Width of the operation.\r
397 @param[in] Address Address of the operation.\r
398 @param[in] Count Count of the number of accesses to perform.\r
399 @param[in] Buffer Pointer to the buffer to write to I/O space. \r
400\r
401 @retval EFI_SUCCESS The data was written to the EFI System.\r
402 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r
403 Buffer is NULL.\r
404 The Buffer is not aligned for the given Width.\r
405 Address is outside the legal range of I/O ports. \r
406 \r
407**/\r
408EFI_STATUS\r
409ScriptIoWrite (\r
410 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
411 IN UINT64 Address,\r
412 IN UINTN Count,\r
413 IN VOID *Buffer\r
414 )\r
415{\r
416 EFI_STATUS Status;\r
417 UINTN AddressStride;\r
418 UINTN BufferStride;\r
419 UINT64 OriginalAddress;\r
420 PTR In;\r
421 PTR OriginalIn;\r
422\r
423 In.Buf = (UINT8 *) Buffer;\r
424\r
425 if (Address > MAX_IO_ADDRESS) {\r
426 return EFI_INVALID_PARAMETER;\r
427 }\r
428\r
429 Status = BuildLoopData (Width, Address, &AddressStride, &BufferStride);\r
430 if (EFI_ERROR (Status)) {\r
431 return Status;\r
432 }\r
433 //\r
434 // Loop for each iteration and move the data\r
435 //\r
436 OriginalAddress = Address;\r
437 OriginalIn.Buf = In.Buf;\r
438 for (; Count > 0; Count--, Address += AddressStride, In.Buf += BufferStride) {\r
439 switch (Width) {\r
440 case S3BootScriptWidthUint8:\r
441 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*In.Uint8));\r
442 IoWrite8 ((UINTN) Address, *In.Uint8);\r
443 break; \r
444 case S3BootScriptWidthFifoUint8:\r
445 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint8));\r
446 IoWrite8 ((UINTN) OriginalAddress, *In.Uint8);\r
447 break; \r
448 case S3BootScriptWidthFillUint8:\r
8e4585bb 449 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint8));\r
64d14edf 450 IoWrite8 ((UINTN) Address, *OriginalIn.Uint8);\r
451 break;\r
452 case S3BootScriptWidthUint16:\r
453 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*In.Uint16));\r
454 IoWrite16 ((UINTN) Address, *In.Uint16);\r
455 break; \r
456 case S3BootScriptWidthFifoUint16:\r
457 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint16));\r
458 IoWrite16 ((UINTN) OriginalAddress, *In.Uint16);\r
459 break; \r
460 case S3BootScriptWidthFillUint16:\r
8e4585bb 461 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint16));\r
64d14edf 462 IoWrite16 ((UINTN) Address, *OriginalIn.Uint16);\r
463 break;\r
464 case S3BootScriptWidthUint32:\r
465 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*In.Uint32));\r
466 IoWrite32 ((UINTN) Address, *In.Uint32);\r
467 break; \r
468 case S3BootScriptWidthFifoUint32:\r
469 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint32));\r
470 IoWrite32 ((UINTN) OriginalAddress, *In.Uint32);\r
471 break;\r
472 case S3BootScriptWidthFillUint32:\r
8e4585bb 473 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint32));\r
64d14edf 474 IoWrite32 ((UINTN) Address, *OriginalIn.Uint32);\r
475 break;\r
476 case S3BootScriptWidthUint64:\r
477 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *In.Uint64));\r
478 IoWrite64 ((UINTN) Address, *In.Uint64);\r
479 break; \r
480 case S3BootScriptWidthFifoUint64:\r
8e4585bb 481 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x (0x%016lx)\n", (UINTN)OriginalAddress, *In.Uint64));\r
64d14edf 482 IoWrite64 ((UINTN) OriginalAddress, *In.Uint64);\r
483 break; \r
484 case S3BootScriptWidthFillUint64:\r
8e4585bb 485 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *OriginalIn.Uint64));\r
64d14edf 486 IoWrite64 ((UINTN) Address, *OriginalIn.Uint64);\r
487 break;\r
488 default:\r
489 return EFI_INVALID_PARAMETER;\r
490 }\r
491 }\r
492 \r
493\r
494 return EFI_SUCCESS;\r
495}\r
496/**\r
30f80497 497 Interprete the boot script node with EFI_BOOT_SCRIPT_IO_WRITE OP code.\r
64d14edf 498 \r
499 @param Script Pointer to the node which is to be interpreted.\r
500\r
501 @retval EFI_SUCCESS The data was written to the EFI System.\r
502 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r
503 Buffer is NULL.\r
504 The Buffer is not aligned for the given Width.\r
505 Address is outside the legal range of I/O ports. \r
506 \r
507**/\r
508EFI_STATUS\r
509BootScriptExecuteIoWrite (\r
510 IN UINT8 *Script \r
511 )\r
512{\r
513 S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
514 UINT64 Address;\r
515 UINTN Count;\r
516 VOID *Buffer;\r
517 EFI_BOOT_SCRIPT_IO_WRITE IoWrite;\r
518 \r
519 CopyMem ((VOID*)&IoWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_IO_WRITE));\r
520 Width = (S3_BOOT_SCRIPT_LIB_WIDTH) IoWrite.Width;\r
521 Address = IoWrite.Address;\r
522 Count = IoWrite.Count;\r
523 Buffer = Script + sizeof (EFI_BOOT_SCRIPT_IO_WRITE);\r
30f80497
SZ
524\r
525 DEBUG ((EFI_D_INFO, "BootScriptExecuteIoWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN)Address, Count, (UINTN)Width));\r
64d14edf 526 return ScriptIoWrite(Width, Address, Count, Buffer);\r
527}\r
528/**\r
529 Perform memory read operation\r
530 \r
531 @param Width Width of the operation.\r
532 @param Address Address of the operation.\r
533 @param Count Count of the number of accesses to perform.\r
534 @param Buffer Pointer to the buffer read from memory. \r
535\r
536 @retval EFI_SUCCESS The data was written to the EFI System.\r
537 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r
538 Buffer is NULL.\r
539 The Buffer is not aligned for the given Width.\r
540 @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count \r
541 is not valid for this EFI System. \r
542 \r
543**/\r
544EFI_STATUS\r
545ScriptMemoryRead (\r
546 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
547 IN UINT64 Address,\r
548 IN UINTN Count,\r
549 IN OUT VOID *Buffer\r
550 )\r
551{\r
552 EFI_STATUS Status;\r
553 UINTN AddressStride;\r
554 UINTN BufferStride;\r
555 PTR Out;\r
556\r
557 Out.Buf = Buffer;\r
558\r
559 Status = BuildLoopData (Width, Address, &AddressStride, &BufferStride);\r
560 if (EFI_ERROR (Status)) {\r
561 return Status;\r
562 }\r
563 //\r
564 // Loop for each iteration and move the data\r
565 //\r
566 for (; Count > 0; Count--, Address += AddressStride, Out.Buf += BufferStride) {\r
567 switch (Width) {\r
568 case S3BootScriptWidthUint8:\r
30f80497
SZ
569 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN)Address));\r
570 *Out.Uint8 = MmioRead8 ((UINTN) Address);\r
571 break;\r
64d14edf 572 case S3BootScriptWidthFifoUint8:\r
30f80497
SZ
573 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", (UINTN)Address));\r
574 *Out.Uint8 = MmioRead8 ((UINTN) Address);\r
575 break;\r
64d14edf 576 case S3BootScriptWidthFillUint8:\r
30f80497 577 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", (UINTN)Address));\r
64d14edf 578 *Out.Uint8 = MmioRead8 ((UINTN) Address);\r
579 break;\r
580\r
581 case S3BootScriptWidthUint16:\r
30f80497
SZ
582 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN)Address));\r
583 *Out.Uint16 = MmioRead16 ((UINTN) Address);\r
584 break;\r
64d14edf 585 case S3BootScriptWidthFifoUint16:\r
30f80497
SZ
586 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", (UINTN)Address));\r
587 *Out.Uint16 = MmioRead16 ((UINTN) Address);\r
588 break;\r
64d14edf 589 case S3BootScriptWidthFillUint16:\r
30f80497 590 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", (UINTN)Address));\r
64d14edf 591 *Out.Uint16 = MmioRead16 ((UINTN) Address);\r
592 break;\r
593\r
594 case S3BootScriptWidthUint32:\r
30f80497
SZ
595 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN)Address));\r
596 *Out.Uint32 = MmioRead32 ((UINTN) Address);\r
597 break;\r
64d14edf 598 case S3BootScriptWidthFifoUint32:\r
30f80497
SZ
599 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", (UINTN)Address));\r
600 *Out.Uint32 = MmioRead32 ((UINTN) Address);\r
601 break;\r
64d14edf 602 case S3BootScriptWidthFillUint32:\r
30f80497 603 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", (UINTN)Address));\r
64d14edf 604 *Out.Uint32 = MmioRead32 ((UINTN) Address);\r
605 break;\r
606\r
607 case S3BootScriptWidthUint64:\r
30f80497
SZ
608 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN)Address));\r
609 *Out.Uint64 = MmioRead64 ((UINTN) Address);\r
610 break;\r
64d14edf 611 case S3BootScriptWidthFifoUint64:\r
30f80497
SZ
612 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x\n", (UINTN)Address));\r
613 *Out.Uint64 = MmioRead64 ((UINTN) Address);\r
614 break;\r
64d14edf 615 case S3BootScriptWidthFillUint64:\r
30f80497 616 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint64 - 0x%08x\n", (UINTN)Address));\r
64d14edf 617 *Out.Uint64 = MmioRead64 ((UINTN) Address);\r
618 break;\r
619\r
620 default:\r
621 return EFI_UNSUPPORTED;\r
622 }\r
623 }\r
624\r
625 return EFI_SUCCESS;\r
626}\r
627/**\r
30f80497 628 Perform memory write operation\r
64d14edf 629 \r
630 @param Width Width of the operation.\r
631 @param Address Address of the operation.\r
632 @param Count Count of the number of accesses to perform.\r
633 @param Buffer Pointer to the buffer write to memory. \r
634\r
635 @retval EFI_SUCCESS The data was written to the EFI System.\r
636 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r
637 Buffer is NULL.\r
638 The Buffer is not aligned for the given Width.\r
639 @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count \r
640 is not valid for this EFI System. \r
641 \r
642**/\r
643EFI_STATUS\r
644ScriptMemoryWrite (\r
645 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
646 IN UINT64 Address,\r
647 IN UINTN Count,\r
648 IN OUT VOID *Buffer\r
649 )\r
650{\r
651 EFI_STATUS Status;\r
652 UINTN AddressStride;\r
653 UINT64 OriginalAddress; \r
654 UINTN BufferStride;\r
655 PTR In;\r
656 PTR OriginalIn;\r
657\r
658 In.Buf = Buffer;\r
659\r
660 Status = BuildLoopData (Width, Address, &AddressStride, &BufferStride);\r
661 if (EFI_ERROR (Status)) {\r
662 return Status;\r
663 }\r
664 //\r
665 // Loop for each iteration and move the data\r
666 //\r
667 OriginalAddress = Address;\r
668 OriginalIn.Buf = In.Buf; \r
669 for (; Count > 0; Count--, Address += AddressStride, In.Buf += BufferStride) {\r
670 switch (Width) {\r
671 case S3BootScriptWidthUint8:\r
672 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*In.Uint8));\r
673 MmioWrite8 ((UINTN) Address, *In.Uint8);\r
674 break; \r
675 case S3BootScriptWidthFifoUint8:\r
676 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint8));\r
677 MmioWrite8 ((UINTN) OriginalAddress, *In.Uint8);\r
678 break; \r
679 case S3BootScriptWidthFillUint8:\r
8e4585bb 680 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint8));\r
64d14edf 681 MmioWrite8 ((UINTN) Address, *OriginalIn.Uint8);\r
682 break;\r
683 case S3BootScriptWidthUint16:\r
684 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*In.Uint16));\r
685 MmioWrite16 ((UINTN) Address, *In.Uint16);\r
686 break; \r
687 case S3BootScriptWidthFifoUint16:\r
688 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint16));\r
689 MmioWrite16 ((UINTN) OriginalAddress, *In.Uint16);\r
690 break; \r
691 case S3BootScriptWidthFillUint16:\r
8e4585bb 692 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint16));\r
64d14edf 693 MmioWrite16 ((UINTN) Address, *OriginalIn.Uint16);\r
694 break;\r
695 case S3BootScriptWidthUint32:\r
696 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*In.Uint32));\r
697 MmioWrite32 ((UINTN) Address, *In.Uint32);\r
698 break; \r
699 case S3BootScriptWidthFifoUint32:\r
700 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint32));\r
701 MmioWrite32 ((UINTN) OriginalAddress, *In.Uint32);\r
702 break; \r
703 case S3BootScriptWidthFillUint32:\r
8e4585bb 704 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint32));\r
64d14edf 705 MmioWrite32 ((UINTN) Address, *OriginalIn.Uint32);\r
706 break;\r
707 case S3BootScriptWidthUint64:\r
708 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *In.Uint64));\r
709 MmioWrite64 ((UINTN) Address, *In.Uint64);\r
710 break; \r
711 case S3BootScriptWidthFifoUint64:\r
712 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x (0x%016lx)\n", (UINTN)OriginalAddress, *In.Uint64));\r
713 MmioWrite64 ((UINTN) OriginalAddress, *In.Uint64);\r
714 break; \r
715 case S3BootScriptWidthFillUint64:\r
8e4585bb 716 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *OriginalIn.Uint64));\r
64d14edf 717 MmioWrite64 ((UINTN) Address, *OriginalIn.Uint64);\r
718 break;\r
719 default:\r
720 return EFI_UNSUPPORTED;\r
721 }\r
722 }\r
723 return EFI_SUCCESS;\r
724}\r
725/**\r
726 Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_WRITE OP code.\r
727\r
728 @param[in] Script Pointer to the node which is to be interpreted.\r
729 \r
730 @retval EFI_SUCCESS The data was written to the EFI System.\r
731 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r
732 Buffer is NULL.\r
733 The Buffer is not aligned for the given Width.\r
734 @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count \r
735 is not valid for this EFI System. \r
736 \r
737**/\r
738EFI_STATUS\r
739BootScriptExecuteMemoryWrite (\r
740 IN UINT8 *Script\r
741 )\r
742{\r
743 VOID *Buffer;\r
744 S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
745 UINT64 Address;\r
746 UINTN Count;\r
747 EFI_BOOT_SCRIPT_MEM_WRITE MemWrite;\r
748 \r
749 CopyMem((VOID*)&MemWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_MEM_WRITE));\r
750 Width = (S3_BOOT_SCRIPT_LIB_WIDTH)MemWrite.Width;\r
751 Address = MemWrite.Address;\r
752 Count = MemWrite.Count;\r
753 Buffer = Script + sizeof(EFI_BOOT_SCRIPT_MEM_WRITE);\r
754\r
30f80497 755 DEBUG ((EFI_D_INFO, "BootScriptExecuteMemoryWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN)Address, Count, (UINTN)Width));\r
64d14edf 756 return ScriptMemoryWrite (Width,Address, Count, Buffer);\r
757 \r
758} \r
759/**\r
30f80497 760 Performance PCI configuration read operation\r
64d14edf 761\r
762 @param Width Width of the operation.\r
763 @param Address Address of the operation.\r
30f80497
SZ
764 @param Count Count of the number of accesses to perform.\r
765 @param Buffer Pointer to the buffer read from PCI config space\r
64d14edf 766 \r
767 @retval EFI_SUCCESS The read succeed.\r
768 @retval EFI_INVALID_PARAMETER if Width is not defined \r
769 \r
770**/\r
771EFI_STATUS\r
772ScriptPciCfgRead (\r
773 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
774 IN UINT64 Address,\r
30f80497 775 IN UINTN Count,\r
64d14edf 776 OUT VOID *Buffer\r
777 )\r
778{\r
30f80497
SZ
779 EFI_STATUS Status;\r
780 UINTN AddressStride;\r
781 UINTN BufferStride;\r
782 PTR Out;\r
783 UINTN PciAddress;\r
784\r
785 Out.Buf = (UINT8 *) Buffer;\r
786\r
787 PciAddress = PCI_ADDRESS_ENCODE (Address);\r
788\r
789 Status = BuildLoopData (Width, PciAddress, &AddressStride, &BufferStride);\r
790 if (EFI_ERROR (Status)) {\r
791 return Status;\r
792 }\r
793 //\r
794 // Loop for each iteration and move the data\r
795 //\r
796 for (; Count > 0; Count--, PciAddress += AddressStride, Out.Buf += BufferStride) {\r
64d14edf 797 switch (Width) {\r
798 case S3BootScriptWidthUint8:\r
30f80497
SZ
799 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", PciAddress));\r
800 *Out.Uint8 = PciRead8 (PciAddress);\r
801 break;\r
802 case S3BootScriptWidthFifoUint8:\r
803 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", PciAddress));\r
804 *Out.Uint8 = PciRead8 (PciAddress);\r
805 break;\r
806 case S3BootScriptWidthFillUint8:\r
807 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", PciAddress));\r
808 *Out.Uint8 = PciRead8 (PciAddress);\r
64d14edf 809 break;\r
810\r
811 case S3BootScriptWidthUint16:\r
30f80497
SZ
812 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", PciAddress));\r
813 *Out.Uint16 = PciRead16 (PciAddress);\r
814 break;\r
815 case S3BootScriptWidthFifoUint16:\r
816 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", PciAddress));\r
817 *Out.Uint16 = PciRead16 (PciAddress);\r
818 break;\r
819 case S3BootScriptWidthFillUint16:\r
820 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", PciAddress));\r
821 *Out.Uint16 = PciRead16 (PciAddress);\r
64d14edf 822 break;\r
823\r
824 case S3BootScriptWidthUint32:\r
30f80497
SZ
825 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", PciAddress));\r
826 *Out.Uint32 = PciRead32 (PciAddress);\r
827 break;\r
828 case S3BootScriptWidthFifoUint32:\r
829 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", PciAddress));\r
830 *Out.Uint32 = PciRead32 (PciAddress);\r
831 break;\r
832 case S3BootScriptWidthFillUint32:\r
833 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", PciAddress));\r
834 *Out.Uint32 = PciRead32 (PciAddress);\r
64d14edf 835 break;\r
836\r
837 default:\r
838 return EFI_INVALID_PARAMETER;\r
30f80497 839 }\r
64d14edf 840 }\r
30f80497 841 return EFI_SUCCESS;\r
64d14edf 842}\r
843\r
844/**\r
30f80497 845 Performance PCI configuration write operation\r
64d14edf 846\r
847 @param Width Width of the operation.\r
848 @param Address Address of the operation.\r
30f80497
SZ
849 @param Count Count of the number of accesses to perform.\r
850 @param Buffer Pointer to the buffer write to PCI config space\r
64d14edf 851 \r
852 @retval EFI_SUCCESS The write succeed.\r
853 @retval EFI_INVALID_PARAMETER if Width is not defined \r
854 \r
855**/\r
856EFI_STATUS\r
857ScriptPciCfgWrite (\r
858 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
859 IN UINT64 Address,\r
30f80497
SZ
860 IN UINTN Count,\r
861 IN VOID *Buffer\r
64d14edf 862 )\r
863{\r
30f80497
SZ
864 EFI_STATUS Status;\r
865 UINTN AddressStride;\r
866 UINTN BufferStride;\r
867 UINTN OriginalPciAddress;\r
868 PTR In;\r
869 PTR OriginalIn;\r
870 UINTN PciAddress;\r
871\r
872 In.Buf = (UINT8 *) Buffer;\r
873\r
874 PciAddress = PCI_ADDRESS_ENCODE (Address);\r
875\r
876 Status = BuildLoopData (Width, PciAddress, &AddressStride, &BufferStride);\r
877 if (EFI_ERROR (Status)) {\r
878 return Status;\r
64d14edf 879 }\r
30f80497
SZ
880 //\r
881 // Loop for each iteration and move the data\r
882 //\r
883 OriginalPciAddress = PciAddress;\r
884 OriginalIn.Buf = In.Buf;\r
885 for (; Count > 0; Count--, PciAddress += AddressStride, In.Buf += BufferStride) {\r
886 switch (Width) {\r
887 case S3BootScriptWidthUint8:\r
888 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", PciAddress, (UINTN)*In.Uint8));\r
889 PciWrite8 (PciAddress, *In.Uint8);\r
890 break; \r
891 case S3BootScriptWidthFifoUint8:\r
892 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", OriginalPciAddress, (UINTN)*In.Uint8));\r
893 PciWrite8 (OriginalPciAddress, *In.Uint8);\r
894 break; \r
895 case S3BootScriptWidthFillUint8:\r
896 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", PciAddress, (UINTN)*OriginalIn.Uint8));\r
897 PciWrite8 (PciAddress, *OriginalIn.Uint8);\r
898 break;\r
899 case S3BootScriptWidthUint16:\r
900 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", PciAddress, (UINTN)*In.Uint16));\r
901 PciWrite16 (PciAddress, *In.Uint16);\r
902 break; \r
903 case S3BootScriptWidthFifoUint16:\r
904 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", OriginalPciAddress, (UINTN)*In.Uint16));\r
905 PciWrite16 (OriginalPciAddress, *In.Uint16);\r
906 break; \r
907 case S3BootScriptWidthFillUint16:\r
908 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", PciAddress, (UINTN)*OriginalIn.Uint16));\r
909 PciWrite16 (PciAddress, *OriginalIn.Uint16);\r
910 break;\r
911 case S3BootScriptWidthUint32:\r
912 DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", PciAddress, (UINTN)*In.Uint32));\r
913 PciWrite32 (PciAddress, *In.Uint32);\r
914 break; \r
915 case S3BootScriptWidthFifoUint32:\r
916 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", OriginalPciAddress, (UINTN)*In.Uint32));\r
917 PciWrite32 (OriginalPciAddress, *In.Uint32);\r
918 break; \r
919 case S3BootScriptWidthFillUint32:\r
920 DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)PciAddress, (UINTN)*OriginalIn.Uint32));\r
921 PciWrite32 (PciAddress, *OriginalIn.Uint32);\r
922 break;\r
923 default:\r
924 return EFI_INVALID_PARAMETER;\r
925 }\r
926 }\r
927 return EFI_SUCCESS;\r
64d14edf 928}\r
929/**\r
30f80497 930 Performance PCI configuration 2 read operation\r
64d14edf 931 \r
932 @param Width Width of the operation.\r
933 @param Segment Pci segment number\r
934 @param Address Address of the operation.\r
30f80497
SZ
935 @param Count Count of the number of accesses to perform.\r
936 @param Buffer Pointer to the buffer to read from PCI config space.\r
64d14edf 937\r
938 @retval EFI_SUCCESS The data was written to the EFI System.\r
939 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r
940 Buffer is NULL.\r
941 The Buffer is not aligned for the given Width.\r
942 Address is outside the legal range of I/O ports.\r
943 @note A known Limitations in the implementation which is the 'Segment' parameter is assumed as \r
944 Zero, or else, assert.\r
945**/\r
946EFI_STATUS\r
947ScriptPciCfg2Read (\r
948 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
949 IN UINT16 Segment, \r
950 IN UINT64 Address,\r
30f80497 951 IN UINTN Count,\r
64d14edf 952 OUT VOID *Buffer\r
953 )\r
954{\r
955 ASSERT (Segment==0);\r
956 \r
30f80497 957 return ScriptPciCfgRead (Width, Address, Count, Buffer);\r
64d14edf 958}\r
959/**\r
30f80497 960 Performance PCI configuration 2 write operation\r
64d14edf 961 \r
962 @param Width Width of the operation.\r
963 @param Segment Pci segment number\r
964 @param Address Address of the operation.\r
30f80497
SZ
965 @param Count Count of the number of accesses to perform.\r
966 @param Buffer Pointer to the buffer to write to PCI config space.\r
64d14edf 967\r
968 @retval EFI_SUCCESS The data was written to the EFI System.\r
969 @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r
970 Buffer is NULL.\r
971 The Buffer is not aligned for the given Width.\r
972 Address is outside the legal range of I/O ports.\r
973 @note A known Limitations in the implementation which is the 'Segment' parameter is assumed as \r
974 Zero, or else, assert.\r
975 \r
976**/\r
977EFI_STATUS\r
978EFIAPI\r
979ScriptPciCfg2Write (\r
980 IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r
981 IN UINT16 Segment, \r
982 IN UINT64 Address,\r
30f80497
SZ
983 IN UINTN Count,\r
984 IN VOID *Buffer\r
64d14edf 985 )\r
986{\r
987 ASSERT (Segment==0);\r
30f80497 988 return ScriptPciCfgWrite (Width, Address, Count, Buffer);\r
64d14edf 989}\r
990/**\r
30f80497 991 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE OP code.\r
64d14edf 992 \r
993 @param Script The pointer of typed node in boot script table \r
994 \r
995 @retval EFI_SUCCESS The operation was executed successfully\r
996**/\r
997EFI_STATUS\r
998BootScriptExecutePciCfgWrite (\r
999 IN UINT8 *Script\r
1000 )\r
1001{\r
30f80497
SZ
1002 VOID *Buffer;\r
1003 S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
1004 UINT64 Address;\r
1005 UINTN Count;\r
1006 EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE PciCfgWrite;\r
64d14edf 1007\r
30f80497 1008 CopyMem ((VOID*)&PciCfgWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));\r
64d14edf 1009\r
30f80497
SZ
1010 Width = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfgWrite.Width;\r
1011 Address = PciCfgWrite.Address;\r
1012 Count = PciCfgWrite.Count;\r
1013 Buffer = Script + sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE);\r
64d14edf 1014\r
30f80497
SZ
1015 DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgWrite - 0x%08x, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (Address), Count, (UINTN)Width));\r
1016 return ScriptPciCfgWrite (Width, Address, Count, Buffer);\r
64d14edf 1017}\r
1018/**\r
30f80497 1019 Interprete the boot script node with EFI_BOOT_SCRIPT_IO_READ_WRITE OP code.\r
64d14edf 1020\r
1021 @param Script The pointer of typed node in boot script table \r
1022 @param AndMask Mask value for 'and' operation\r
1023 @param OrMask Mask value for 'or' operation\r
1024\r
1025 @retval EFI_SUCCESS The operation was executed successfully\r
1026**/\r
1027EFI_STATUS\r
1028BootScriptExecuteIoReadWrite (\r
1029 IN UINT8 *Script,\r
1030 IN UINT64 AndMask,\r
1031 IN UINT64 OrMask\r
1032 )\r
1033\r
1034{\r
1035 EFI_STATUS Status;\r
1036 UINT64 Data;\r
1037 EFI_BOOT_SCRIPT_IO_READ_WRITE IoReadWrite;\r
1038 \r
1039 Data = 0;\r
1040 \r
1041 CopyMem((VOID*)&IoReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_IO_READ_WRITE));\r
1042\r
30f80497 1043 DEBUG ((EFI_D_INFO, "BootScriptExecuteIoReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoReadWrite.Address, AndMask, OrMask));\r
64d14edf 1044\r
1045 Status = ScriptIoRead (\r
1046 (S3_BOOT_SCRIPT_LIB_WIDTH) IoReadWrite.Width,\r
1047 IoReadWrite.Address,\r
1048 1,\r
1049 &Data\r
1050 );\r
1051 if (!EFI_ERROR (Status)) {\r
1052 Data = (Data & AndMask) | OrMask;\r
1053 Status = ScriptIoWrite (\r
1054 (S3_BOOT_SCRIPT_LIB_WIDTH) IoReadWrite.Width,\r
1055 IoReadWrite.Address,\r
1056 1,\r
1057 &Data\r
1058 );\r
1059 }\r
1060 return Status;\r
1061}\r
1062/**\r
30f80497 1063 Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_READ_WRITE OP code.\r
64d14edf 1064\r
1065 @param Script The pointer of typed node in boot script table \r
1066 @param AndMask Mask value for 'and' operation\r
1067 @param OrMask Mask value for 'or' operation\r
1068\r
1069 @retval EFI_SUCCESS The operation was executed successfully\r
1070**/\r
1071EFI_STATUS\r
1072BootScriptExecuteMemoryReadWrite (\r
1073 IN UINT8 *Script,\r
1074 IN UINT64 AndMask,\r
1075 IN UINT64 OrMask\r
1076 )\r
1077\r
1078{\r
1079 EFI_STATUS Status;\r
1080 UINT64 Data;\r
1081 EFI_BOOT_SCRIPT_MEM_READ_WRITE MemReadWrite;\r
1082 \r
1083 Data = 0;\r
1084 \r
1085 CopyMem((VOID*)&MemReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_MEM_READ_WRITE));\r
1086\r
30f80497 1087 DEBUG ((EFI_D_INFO, "BootScriptExecuteMemoryReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemReadWrite.Address, AndMask, OrMask));\r
64d14edf 1088 \r
1089 Status = ScriptMemoryRead (\r
1090 (S3_BOOT_SCRIPT_LIB_WIDTH) MemReadWrite.Width,\r
1091 MemReadWrite.Address,\r
1092 1,\r
1093 &Data\r
1094 );\r
1095 if (!EFI_ERROR (Status)) {\r
1096 Data = (Data & AndMask) | OrMask;\r
1097 Status = ScriptMemoryWrite (\r
1098 (S3_BOOT_SCRIPT_LIB_WIDTH) MemReadWrite.Width,\r
1099 MemReadWrite.Address,\r
1100 1,\r
1101 &Data\r
1102 );\r
1103 }\r
1104 return Status;\r
1105}\r
1106/**\r
30f80497 1107 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CFG_READ_WRITE OP code.\r
64d14edf 1108\r
1109 @param Script The pointer of typed node in boot script table \r
1110 @param AndMask Mask value for 'and' operation\r
1111 @param OrMask Mask value for 'or' operation\r
1112\r
1113 @retval EFI_SUCCESS The operation was executed successfully\r
1114**/\r
1115EFI_STATUS\r
1116BootScriptExecutePciCfgReadWrite (\r
1117 IN UINT8 *Script,\r
1118 IN UINT64 AndMask,\r
1119 IN UINT64 OrMask\r
1120 )\r
1121\r
1122{\r
1123 EFI_STATUS Status;\r
1124 UINT64 Data;\r
1125 EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE PciCfgReadWrite;\r
1126 \r
1127 CopyMem((VOID*)&PciCfgReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE));\r
1128\r
30f80497 1129 DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfgReadWrite.Address), AndMask, OrMask));\r
64d14edf 1130 \r
1131 Status = ScriptPciCfgRead (\r
1132 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgReadWrite.Width,\r
1133 PciCfgReadWrite.Address,\r
30f80497 1134 1,\r
64d14edf 1135 &Data\r
1136 );\r
1137 if (EFI_ERROR (Status)) {\r
1138 return Status;\r
1139 }\r
1140\r
1141 Data = (Data & AndMask) | OrMask;\r
1142\r
1143 Status = ScriptPciCfgWrite (\r
1144 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgReadWrite.Width,\r
1145 PciCfgReadWrite.Address,\r
30f80497 1146 1,\r
64d14edf 1147 &Data\r
1148 );\r
1149\r
1150 return Status;\r
1151}\r
1152/**\r
30f80497 1153 Interprete the boot script node with EFI_BOOT_SCRIPT_SMBUS_EXECUTE OP code.\r
64d14edf 1154\r
1155 @param Script The pointer of typed node in boot script table \r
1156 \r
1157 @retval EFI_SUCCESS The operation was executed successfully\r
1158 @retval EFI_UNSUPPORTED Cannot locate smbus ppi or occur error of script execution\r
1159 @retval Others Result of script execution \r
1160**/\r
1161EFI_STATUS\r
1162BootScriptExecuteSmbusExecute (\r
1163 IN UINT8 *Script\r
1164 )\r
1165{\r
1166 UINTN SmBusAddress;\r
1167 UINTN DataSize;\r
1168 EFI_BOOT_SCRIPT_SMBUS_EXECUTE SmbusExecuteEntry;\r
1169 \r
1170 CopyMem ((VOID*)&SmbusExecuteEntry, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_SMBUS_EXECUTE ));\r
1171\r
1172 DEBUG ((EFI_D_INFO, "BootScriptExecuteSmbusExecute - 0x%08x, 0x%08x\n", (UINTN)SmbusExecuteEntry.SmBusAddress, (UINTN)SmbusExecuteEntry.Operation));\r
1173\r
1174 SmBusAddress = (UINTN)SmbusExecuteEntry.SmBusAddress;\r
1175 DataSize = (UINTN) SmbusExecuteEntry.DataSize;\r
1176 return SmbusExecute (\r
1177 SmBusAddress,\r
1178 (EFI_SMBUS_OPERATION) SmbusExecuteEntry.Operation,\r
1179 &DataSize,\r
1180 Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)\r
1181 );\r
1182}\r
1183/**\r
30f80497 1184 Interprete the boot script node with EFI_BOOT_SCRIPT_STALL OP code.\r
64d14edf 1185\r
1186 @param Script The pointer of typed node in boot script table \r
1187 \r
1188 @retval EFI_SUCCESS The operation was executed successfully\r
1189**/\r
1190EFI_STATUS\r
1191BootScriptExecuteStall (\r
1192 IN UINT8 *Script\r
1193 )\r
1194{\r
1195 EFI_BOOT_SCRIPT_STALL Stall;\r
1196 \r
1197 CopyMem ((VOID*)&Stall, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_STALL));\r
1198\r
1199 DEBUG ((EFI_D_INFO, "BootScriptExecuteStall - 0x%08x\n", (UINTN)Stall.Duration));\r
1200\r
1201 MicroSecondDelay ((UINTN) Stall.Duration);\r
1202 return EFI_SUCCESS;\r
1203}\r
1204/**\r
30f80497 1205 Interprete the boot script node with EFI_BOOT_SCRIPT_DISPATCH OP code.\r
64d14edf 1206 \r
30f80497
SZ
1207 @param Script The pointer of typed node in boot script table \r
1208 @retval EFI_SUCCESS The operation was executed successfully\r
64d14edf 1209**/\r
1210EFI_STATUS\r
1211BootScriptExecuteDispatch (\r
1212 IN UINT8 *Script\r
1213 )\r
1214{\r
1215 EFI_STATUS Status;\r
1216 DISPATCH_ENTRYPOINT_FUNC EntryFunc;\r
1217 EFI_BOOT_SCRIPT_DISPATCH ScriptDispatch;\r
1218 \r
1219 CopyMem ((VOID*)&ScriptDispatch, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_DISPATCH));\r
1220 EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (ScriptDispatch.EntryPoint);\r
1221\r
1222 DEBUG ((EFI_D_INFO, "BootScriptExecuteDispatch - 0x%08x\n", (UINTN)ScriptDispatch.EntryPoint));\r
1223\r
1224 Status = EntryFunc (NULL, NULL);\r
1225\r
1226 return Status;\r
1227}\r
1228/**\r
30f80497 1229 Interprete the boot script node with EFI_BOOT_SCRIPT_DISPATCH_2 OP code.\r
64d14edf 1230\r
1231 @param Script The pointer of typed node in boot script table \r
1232 @retval EFI_SUCCESS The operation was executed successfully\r
1233**/\r
1234EFI_STATUS\r
1235BootScriptExecuteDispatch2 (\r
1236 IN UINT8 *Script\r
1237 )\r
1238{\r
1239 EFI_STATUS Status;\r
1240 DISPATCH_ENTRYPOINT_FUNC EntryFunc;\r
1241 EFI_BOOT_SCRIPT_DISPATCH_2 ScriptDispatch2;\r
1242 \r
1243 CopyMem ((VOID*)&ScriptDispatch2, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_DISPATCH_2));\r
1244\r
1245 DEBUG ((EFI_D_INFO, "BootScriptExecuteDispatch2 - 0x%08x(0x%08x)\n", (UINTN)ScriptDispatch2.EntryPoint, (UINTN)ScriptDispatch2.Context));\r
1246 \r
1247 EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (ScriptDispatch2.EntryPoint);\r
1248\r
1249 Status = EntryFunc (NULL, (VOID *) (UINTN) ScriptDispatch2.Context);\r
1250\r
1251 return Status;\r
1252}\r
1253/**\r
30f80497 1254 Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_POLL OP code.\r
64d14edf 1255\r
1256 @param Script The pointer of typed node in boot script table \r
1257 @param AndMask Mask value for 'and' operation\r
1258 @param OrMask Mask value for 'or' operation\r
1259 \r
1260 @retval EFI_DEVICE_ERROR Data polled from memory does not equal to \r
1261 the epecting data within the Loop Times.\r
1262 @retval EFI_SUCCESS The operation was executed successfully\r
1263**/\r
1264EFI_STATUS\r
1265BootScriptExecuteMemPoll (\r
1266 IN UINT8 *Script,\r
1267 IN UINT64 AndMask,\r
1268 IN UINT64 OrMask \r
1269 )\r
1270{\r
1271 \r
1272 UINT64 Data;\r
1273 UINT64 LoopTimes;\r
1274 EFI_STATUS Status;\r
1275 EFI_BOOT_SCRIPT_MEM_POLL MemPoll;\r
1276 \r
1277 CopyMem ((VOID*)&MemPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_MEM_POLL));\r
1278\r
30f80497 1279 DEBUG ((EFI_D_INFO, "BootScriptExecuteMemPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemPoll.Address, AndMask, OrMask));\r
64d14edf 1280\r
1281 Data = 0;\r
1282 Status = ScriptMemoryRead (\r
1283 (S3_BOOT_SCRIPT_LIB_WIDTH) MemPoll.Width,\r
1284 MemPoll.Address,\r
1285 1,\r
1286 &Data\r
1287 );\r
1288 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1289 return EFI_SUCCESS;\r
1290 }\r
1291\r
1292 for (LoopTimes = 0; LoopTimes < MemPoll.LoopTimes; LoopTimes++) {\r
1293 NanoSecondDelay ((UINTN)MemPoll.Duration);\r
1294\r
1295 Data = 0;\r
1296 Status = ScriptMemoryRead (\r
1297 (S3_BOOT_SCRIPT_LIB_WIDTH) MemPoll.Width,\r
1298 MemPoll.Address,\r
1299 1,\r
1300 &Data\r
1301 );\r
1302 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1303 return EFI_SUCCESS;\r
1304 }\r
1305 }\r
1306\r
1307 if (LoopTimes < MemPoll.LoopTimes) {\r
1308 return EFI_SUCCESS;\r
1309 } else {\r
1310 return EFI_DEVICE_ERROR;\r
1311 }\r
1312}\r
1313/**\r
30f80497 1314 Execute the boot script to interpret the Store arbitrary information.\r
64d14edf 1315 This opcode is a no-op on dispatch and is only used for debugging script issues.\r
1316\r
1317 @param Script The pointer of node in boot script table \r
1318 \r
1319**/\r
1320VOID\r
1321BootScriptExecuteInformation (\r
1322 IN UINT8 *Script\r
1323 )\r
1324\r
1325{\r
f6ec0c77
JY
1326 UINT32 Index;\r
1327 EFI_BOOT_SCRIPT_INFORMATION Information;\r
93b21ade 1328 UINT8 *InformationData;\r
f6ec0c77 1329\r
93b21ade 1330 CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_INFORMATION));\r
f6ec0c77 1331\r
93b21ade
SZ
1332 InformationData = Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION);\r
1333 DEBUG ((EFI_D_INFO, "BootScriptExecuteInformation - 0x%08x\n", (UINTN) InformationData));\r
f6ec0c77
JY
1334\r
1335 DEBUG ((EFI_D_INFO, "BootScriptInformation: "));\r
1336 for (Index = 0; Index < Information.InformationLength; Index++) {\r
93b21ade 1337 DEBUG ((EFI_D_INFO, "%02x ", InformationData[Index]));\r
f6ec0c77
JY
1338 }\r
1339 DEBUG ((EFI_D_INFO, "\n"));\r
64d14edf 1340}\r
8e4585bb
SZ
1341\r
1342/**\r
1343 Execute the boot script to interpret the Label information. \r
1344\r
1345 @param Script The pointer of node in boot script table \r
1346 \r
1347**/\r
1348VOID\r
1349BootScriptExecuteLabel (\r
1350 IN UINT8 *Script\r
1351 )\r
1352\r
1353{\r
1354 UINT32 Index;\r
1355 EFI_BOOT_SCRIPT_INFORMATION Information;\r
93b21ade 1356 UINT8 *InformationData;\r
8e4585bb 1357\r
93b21ade 1358 CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_INFORMATION));\r
8e4585bb 1359\r
93b21ade
SZ
1360 InformationData = Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION);\r
1361 DEBUG ((EFI_D_INFO, "BootScriptExecuteLabel - 0x%08x\n", (UINTN) InformationData));\r
8e4585bb
SZ
1362\r
1363 DEBUG ((EFI_D_INFO, "BootScriptLabel: "));\r
1364 for (Index = 0; Index < Information.InformationLength; Index++) {\r
93b21ade 1365 DEBUG ((EFI_D_INFO, "%02x ", InformationData[Index]));\r
8e4585bb
SZ
1366 }\r
1367 DEBUG ((EFI_D_INFO, "\n"));\r
1368}\r
1369\r
64d14edf 1370/**\r
1371 calculate the mask value for 'and' and 'or' operation\r
1372 @param ScriptHeader The pointer of header of node in boot script table \r
1373 @param AndMask The Mask value for 'and' operation\r
1374 @param OrMask The Mask value for 'or' operation\r
1375 @param Script Pointer to the entry.\r
1376\r
1377**/\r
1378VOID\r
1379CheckAndOrMask (\r
1380 IN EFI_BOOT_SCRIPT_COMMON_HEADER *ScriptHeader,\r
1381 OUT UINT64 *AndMask,\r
1382 OUT UINT64 *OrMask,\r
1383 IN UINT8 *Script\r
1384 )\r
1385{\r
1386 UINT8 *DataPtr;\r
1387 UINTN Size;\r
1388\r
1389 switch (ScriptHeader->OpCode) {\r
1390 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
1391 Size = sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE);\r
1392 break;\r
1393\r
1394 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
1395 Size = sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE);\r
1396 break;\r
1397\r
1398 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
1399 Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE);\r
1400 break;\r
1401 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
1402 Size = sizeof (EFI_BOOT_SCRIPT_MEM_POLL);\r
1403 break;\r
1404 \r
1405 case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:\r
1406 Size = sizeof (EFI_BOOT_SCRIPT_IO_POLL);\r
1407 break; \r
1408 \r
1409 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
1410 Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE);\r
1411 break;\r
1412 \r
1413 case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r
1414 Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL);\r
1415 break;\r
1416 \r
1417 case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:\r
1418 Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL);\r
1419 break;\r
1420 \r
1421 default:\r
1422 return;\r
1423 }\r
1424 \r
1425 DataPtr = Script + Size;\r
1426\r
1427 switch (ScriptHeader->Width) {\r
1428 case S3BootScriptWidthUint8:\r
1429 *AndMask = (UINT64) *(DataPtr + 1);\r
1430 *OrMask = (UINT64) (*DataPtr);\r
1431 break;\r
1432\r
1433 case S3BootScriptWidthUint16:\r
1434 *AndMask = (UINT64) (*(UINT16 *) (DataPtr + 2));\r
1435 *OrMask = (UINT64) (*(UINT16 *) DataPtr);\r
1436 break;\r
1437\r
1438 case S3BootScriptWidthUint32:\r
1439 *AndMask = (UINT64) (*(UINT32 *) (DataPtr + 4));\r
1440 *OrMask = (UINT64) (*(UINT32 *) DataPtr);\r
1441 break;\r
1442\r
1443 case S3BootScriptWidthUint64:\r
1444 *AndMask = (UINT64) (*(UINT64 *) (DataPtr + 8));\r
1445 *OrMask = (UINT64) (*(UINT64 *) DataPtr);\r
1446 break;\r
1447\r
1448 default:\r
1449 break;\r
1450 }\r
1451\r
1452 return;\r
1453}\r
1454/**\r
30f80497 1455 Interprete the boot script node with EFI_BOOT_SCRIPT_IO_POLL OP code.\r
64d14edf 1456\r
1457 @param Script The pointer of typed node in boot script table \r
1458 @param AndMask Mask value for 'and' operation\r
1459 @param OrMask Mask value for 'or' operation\r
1460 \r
1461 @retval EFI_DEVICE_ERROR Data polled from memory does not equal to \r
1462 the epecting data within the Loop Times.\r
1463 @retval EFI_SUCCESS The operation was executed successfully\r
1464**/\r
1465EFI_STATUS\r
1466BootScriptExecuteIoPoll (\r
1467 IN UINT8 *Script,\r
1468 IN UINT64 AndMask,\r
1469 IN UINT64 OrMask\r
1470 )\r
1471{\r
1472 EFI_STATUS Status;\r
1473 UINT64 Data;\r
1474 UINT64 LoopTimes;\r
1475 EFI_BOOT_SCRIPT_IO_POLL IoPoll;\r
1476 \r
1477 CopyMem ((VOID*)&IoPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_IO_POLL));\r
1478\r
30f80497 1479 DEBUG ((EFI_D_INFO, "BootScriptExecuteIoPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoPoll.Address, AndMask, OrMask));\r
64d14edf 1480\r
1481 Data = 0;\r
1482 Status = ScriptIoRead (\r
1483 (S3_BOOT_SCRIPT_LIB_WIDTH) IoPoll.Width,\r
1484 IoPoll.Address,\r
1485 1,\r
1486 &Data\r
1487 );\r
1488 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1489 return EFI_SUCCESS;\r
1490 }\r
1491 for (LoopTimes = 0; LoopTimes < IoPoll.Delay; LoopTimes++) {\r
1492 NanoSecondDelay (100);\r
1493 Data = 0;\r
1494 Status = ScriptIoRead (\r
1495 (S3_BOOT_SCRIPT_LIB_WIDTH) IoPoll.Width,\r
1496 IoPoll.Address,\r
1497 1,\r
1498 &Data\r
1499 );\r
1500 if ((!EFI_ERROR (Status)) &&(Data & AndMask) == OrMask) {\r
1501 return EFI_SUCCESS;\r
1502 } \r
1503 }\r
1504\r
1505 if (LoopTimes < IoPoll.Delay) {\r
1506 return EFI_SUCCESS;\r
1507 } else {\r
1508 return EFI_DEVICE_ERROR;\r
1509 }\r
1510}\r
1511/**\r
30f80497 1512 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE OP code.\r
64d14edf 1513\r
1514 @param Script The pointer of S3 boot script\r
1515\r
1516 @retval EFI_SUCCESS The operation was executed successfully\r
1517\r
1518**/\r
1519EFI_STATUS\r
1520BootScriptExecutePciCfg2Write (\r
1521 IN UINT8 *Script\r
1522 )\r
1523{\r
30f80497
SZ
1524 VOID *Buffer;\r
1525 S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
1526 UINT16 Segment;\r
1527 UINT64 Address;\r
1528 UINTN Count;\r
1529 EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE PciCfg2Write;\r
64d14edf 1530 \r
1531 CopyMem ((VOID*)&PciCfg2Write, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));\r
64d14edf 1532\r
30f80497
SZ
1533 Width = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2Write.Width;\r
1534 Segment = PciCfg2Write.Segment;\r
1535 Address = PciCfg2Write.Address;\r
1536 Count = PciCfg2Write.Count;\r
1537 Buffer = Script + sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE);\r
1538\r
1539 DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2Write - 0x%04x, 0x%08x, 0x%08x, 0x%08x\n", Segment, PCI_ADDRESS_ENCODE (Address), Count, (UINTN)Width));\r
1540 return ScriptPciCfg2Write (Width, Segment, Address, Count, Buffer);\r
64d14edf 1541}\r
1542\r
1543\r
1544/**\r
30f80497 1545 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE OP code.\r
64d14edf 1546 \r
1547 @param Script The pointer of S3 boot script\r
1548 @param AndMask Mask value for 'and' operation\r
1549 @param OrMask Mask value for 'or' operation\r
1550\r
1551 @retval EFI_SUCCESS The operation was executed successfully\r
1552\r
1553**/\r
1554EFI_STATUS\r
1555BootScriptExecutePciCfg2ReadWrite (\r
1556 IN UINT8 *Script,\r
1557 IN UINT64 AndMask,\r
1558 IN UINT64 OrMask\r
1559 )\r
1560{\r
1561 UINT64 Data;\r
1562 EFI_STATUS Status;\r
1563 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE PciCfg2ReadWrite;\r
1564 CopyMem ((VOID*)&PciCfg2ReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE));\r
1565\r
30f80497 1566 DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2ReadWrite - 0x%04x, 0x%08x, 0x%016lx, 0x%016lx\n", PciCfg2ReadWrite.Segment, PCI_ADDRESS_ENCODE (PciCfg2ReadWrite.Address), AndMask, OrMask));\r
64d14edf 1567 \r
1568 Status = ScriptPciCfg2Read (\r
1569 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2ReadWrite.Width,\r
1570 PciCfg2ReadWrite.Segment,\r
1571 PciCfg2ReadWrite.Address,\r
30f80497 1572 1,\r
64d14edf 1573 &Data\r
1574 );\r
1575 if (EFI_ERROR (Status)) {\r
1576 return Status;\r
1577 }\r
1578\r
1579 Data = (Data & AndMask) | OrMask;\r
1580 Status = ScriptPciCfg2Write (\r
1581 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2ReadWrite.Width,\r
1582 PciCfg2ReadWrite.Segment,\r
1583 PciCfg2ReadWrite.Address,\r
30f80497 1584 1,\r
64d14edf 1585 &Data\r
1586 );\r
1587 return Status;\r
1588}\r
1589/**\r
30f80497 1590 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_POLL OP code.\r
64d14edf 1591 \r
1592 @param Script The pointer of S3 boot script\r
1593 @param AndMask Mask value for 'and' operation\r
1594 @param OrMask Mask value for 'or' operation\r
1595\r
1596 @retval EFI_SUCCESS The operation was executed successfully\r
1597 @retval EFI_DEVICE_ERROR Data polled from Pci configuration space does not equal to \r
1598 epecting data within the Loop Times.\r
1599**/\r
1600EFI_STATUS\r
1601BootScriptPciCfgPoll (\r
1602 IN UINT8 *Script,\r
1603 IN UINT64 AndMask,\r
1604 IN UINT64 OrMask \r
1605 )\r
1606{\r
1607 UINT64 Data;\r
1608 UINT64 LoopTimes;\r
1609 EFI_STATUS Status;\r
1610 EFI_BOOT_SCRIPT_PCI_CONFIG_POLL PciCfgPoll;\r
1611 CopyMem ((VOID*)&PciCfgPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_POLL));\r
1612\r
30f80497 1613 DEBUG ((EFI_D_INFO, "BootScriptPciCfgPoll - 0x%08x, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfgPoll.Address), AndMask, OrMask));\r
64d14edf 1614 \r
1615 Data = 0;\r
1616 Status = ScriptPciCfgRead (\r
1617 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgPoll.Width,\r
1618 PciCfgPoll.Address,\r
30f80497 1619 1,\r
64d14edf 1620 &Data\r
1621 );\r
1622 if ((!EFI_ERROR (Status)) &&(Data & AndMask) == OrMask) {\r
1623 return EFI_SUCCESS;\r
1624 }\r
1625\r
1626 for (LoopTimes = 0; LoopTimes < PciCfgPoll.Delay; LoopTimes++) {\r
1627 NanoSecondDelay (100);\r
1628 Data = 0;\r
1629 Status = ScriptPciCfgRead (\r
1630 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgPoll.Width,\r
1631 PciCfgPoll.Address,\r
30f80497 1632 1,\r
64d14edf 1633 &Data\r
1634 );\r
1635 if ((!EFI_ERROR (Status)) &&\r
1636 (Data & AndMask) == OrMask) {\r
1637 return EFI_SUCCESS;\r
1638 }\r
1639 }\r
1640\r
1641 if (LoopTimes < PciCfgPoll.Delay) {\r
1642 return EFI_SUCCESS;\r
1643 } else {\r
1644 return EFI_DEVICE_ERROR;\r
1645 }\r
1646}\r
1647\r
1648/**\r
30f80497 1649 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL OP code.\r
64d14edf 1650 \r
1651 @param Script The pointer of S3 Boot Script\r
1652 @param AndMask Mask value for 'and' operation\r
1653 @param OrMask Mask value for 'or' operation\r
1654\r
1655 @retval EFI_SUCCESS The operation was executed successfully\r
1656 @retval EFI_DEVICE_ERROR Data polled from Pci configuration space does not equal to \r
1657 epecting data within the Loop Times.\r
1658\r
1659**/\r
1660EFI_STATUS\r
1661BootScriptPciCfg2Poll (\r
1662 IN UINT8 *Script,\r
1663 IN UINT64 AndMask,\r
1664 IN UINT64 OrMask \r
1665 )\r
1666{\r
1667 EFI_STATUS Status;\r
1668 UINT64 Data;\r
1669 UINT64 LoopTimes;\r
1670 EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL PciCfg2Poll;\r
1671\r
1672 Data = 0;\r
1673 CopyMem ((VOID*)&PciCfg2Poll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL));\r
1674\r
30f80497 1675 DEBUG ((EFI_D_INFO, "BootScriptPciCfg2Poll - 0x%04x, 0x%08x, 0x%016lx, 0x%016lx\n", PciCfg2Poll.Segment, PCI_ADDRESS_ENCODE (PciCfg2Poll.Address), AndMask, OrMask));\r
64d14edf 1676 \r
1677 Status = ScriptPciCfg2Read (\r
1678 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Poll.Width,\r
1679 PciCfg2Poll.Segment,\r
1680 PciCfg2Poll.Address,\r
30f80497 1681 1,\r
64d14edf 1682 &Data\r
1683 );\r
1684 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1685 return EFI_SUCCESS;\r
1686 }\r
1687\r
1688 for (LoopTimes = 0; LoopTimes < PciCfg2Poll.Delay; LoopTimes++) {\r
1689 NanoSecondDelay (100);\r
1690\r
1691 Data = 0;\r
1692 Status = ScriptPciCfg2Read (\r
1693 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Poll.Width,\r
1694 PciCfg2Poll.Segment, \r
1695 PciCfg2Poll.Address,\r
30f80497 1696 1,\r
64d14edf 1697 &Data\r
1698 );\r
1699 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1700 return EFI_SUCCESS;\r
1701 }\r
1702 }\r
1703\r
1704 if (LoopTimes < PciCfg2Poll.Delay) {\r
1705 return EFI_SUCCESS;\r
1706 } else {\r
1707 return EFI_DEVICE_ERROR;\r
1708 }\r
1709 \r
1710}\r
1711\r
1712/**\r
1713 Executes the S3 boot script table.\r
1714 \r
1715 @retval RETURN_SUCCESS The boot script table was executed successfully.\r
1716 @retval RETURN_UNSUPPORTED Invalid script table or opcode. \r
1717 \r
1718 @note A known Limitations in the implementation: When interpreting the opcode EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\r
1719 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE and EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE, the 'Segment' parameter is assumed as \r
1720 Zero, or else, assert.\r
1721**/\r
1722RETURN_STATUS\r
1723EFIAPI\r
1724S3BootScriptExecute (\r
1725 VOID\r
1726 )\r
1727{\r
1728 EFI_STATUS Status;\r
1729 UINT8* Script;\r
1730 UINTN StartAddress;\r
1731 UINT32 TableLength;\r
1732 UINT64 AndMask;\r
1733 UINT64 OrMask;\r
1734 EFI_BOOT_SCRIPT_COMMON_HEADER ScriptHeader;\r
1735 EFI_BOOT_SCRIPT_TABLE_HEADER TableHeader;\r
1736 Script = mS3BootScriptTablePtr->TableBase;\r
1737 if (Script != 0) { \r
1738 CopyMem ((VOID*)&TableHeader, Script, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));\r
1739 } else {\r
1740 return EFI_INVALID_PARAMETER;\r
1741 }\r
1742\r
1743 DEBUG ((EFI_D_INFO, "S3BootScriptExecute:\n"));\r
1744 if (TableHeader.OpCode != S3_BOOT_SCRIPT_LIB_TABLE_OPCODE) {\r
1745 return EFI_UNSUPPORTED;\r
1746 }\r
1747\r
1748 DEBUG ((EFI_D_INFO, "TableHeader - 0x%08x\n", Script));\r
1749 \r
1750 StartAddress = (UINTN) Script;\r
1751 TableLength = TableHeader.TableLength;\r
1752 Script = Script + TableHeader.Length;\r
1753 Status = EFI_SUCCESS;\r
1754 AndMask = 0;\r
1755 OrMask = 0;\r
1756\r
1757 DEBUG ((EFI_D_INFO, "TableHeader.TableLength - 0x%08x\n", (UINTN)TableLength));\r
1758\r
1759 while ((UINTN) Script < (UINTN) (StartAddress + TableLength)) {\r
1760 DEBUG ((EFI_D_INFO, "ExecuteBootScript - %08x\n", (UINTN)Script));\r
1761 \r
1762 CopyMem ((VOID*)&ScriptHeader, Script, sizeof(EFI_BOOT_SCRIPT_COMMON_HEADER));\r
1763 switch (ScriptHeader.OpCode) {\r
1764\r
1765 case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:\r
1766 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE\n"));\r
1767 Status = BootScriptExecuteMemoryWrite (Script);\r
1768 break;\r
1769\r
1770 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
1771 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE\n"));\r
1772 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1773 Status = BootScriptExecuteMemoryReadWrite (\r
1774 Script,\r
1775 AndMask,\r
1776 OrMask\r
1777 );\r
1778 break;\r
1779\r
1780 case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:\r
1781 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_WRITE_OPCODE\n"));\r
1782 Status = BootScriptExecuteIoWrite (Script);\r
1783 break;\r
1784\r
1785 case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:\r
1786 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE\n"));\r
1787 Status = BootScriptExecutePciCfgWrite (Script);\r
1788 break;\r
1789\r
1790 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
1791 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE\n"));\r
1792 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1793 Status = BootScriptExecutePciCfgReadWrite (\r
1794 Script,\r
1795 AndMask,\r
1796 OrMask\r
1797 );\r
1798 break;\r
1799 case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:\r
1800 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\n"));\r
1801 Status = BootScriptExecutePciCfg2Write (Script);\r
1802 break;\r
1803\r
1804 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
1805 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE\n"));\r
1806 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1807 Status = BootScriptExecutePciCfg2ReadWrite (\r
1808 Script,\r
1809 AndMask,\r
1810 OrMask\r
1811 );\r
1812 break;\r
1813 case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:\r
1814 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_DISPATCH_OPCODE\n"));\r
1815 Status = BootScriptExecuteDispatch (Script);\r
1816 break;\r
1817\r
1818 case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:\r
1819 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE\n"));\r
1820 Status = BootScriptExecuteDispatch2 (Script);\r
1821 break;\r
1822\r
1823 case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
1824 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_INFORMATION_OPCODE\n"));\r
1825 BootScriptExecuteInformation (Script);\r
1826 break; \r
1827\r
1828 case S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE:\r
1829 DEBUG ((EFI_D_INFO, "S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE\n"));\r
8e4585bb 1830 DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", EFI_SUCCESS));\r
64d14edf 1831 return EFI_SUCCESS;\r
1832\r
1833 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
1834 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE\n"));\r
1835 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1836 Status = BootScriptExecuteIoReadWrite (\r
1837 Script,\r
1838 AndMask,\r
1839 OrMask\r
1840 );\r
1841 break;\r
1842\r
1843 case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:\r
1844 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE\n"));\r
1845 Status = BootScriptExecuteSmbusExecute (Script);\r
1846 break;\r
1847\r
1848 case EFI_BOOT_SCRIPT_STALL_OPCODE:\r
1849 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_STALL_OPCODE\n"));\r
1850 Status = BootScriptExecuteStall (Script);\r
1851 break;\r
1852\r
1853 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
1854 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_POLL_OPCODE\n"));\r
1855 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1856 Status = BootScriptExecuteMemPoll (Script, AndMask, OrMask);\r
1857 \r
1858 break;\r
1859 \r
1860 case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:\r
1861 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_POLL_OPCODE\n"));\r
1862 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1863 Status = BootScriptExecuteIoPoll (Script, AndMask, OrMask);\r
1864 break;\r
1865 \r
1866 case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:\r
1867 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE\n"));\r
1868 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1869 Status = BootScriptPciCfgPoll (Script, AndMask, OrMask);\r
1870 break;\r
1871 \r
1872 case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r
1873 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE\n"));\r
1874 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1875 Status = BootScriptPciCfg2Poll (Script, AndMask, OrMask);\r
1876 break;\r
1877\r
1878 case S3_BOOT_SCRIPT_LIB_LABEL_OPCODE:\r
1879 //\r
1880 // For label\r
1881 //\r
1882 DEBUG ((EFI_D_INFO, "S3_BOOT_SCRIPT_LIB_LABEL_OPCODE\n"));\r
8e4585bb 1883 BootScriptExecuteLabel (Script);\r
64d14edf 1884 break;\r
1885 default:\r
1886 DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", EFI_UNSUPPORTED));\r
1887 return EFI_UNSUPPORTED;\r
1888 }\r
1889\r
1890 if (EFI_ERROR (Status)) {\r
1891 DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", Status));\r
1892 return Status;\r
1893 }\r
1894\r
1895 Script = Script + ScriptHeader.Length;\r
1896 }\r
1897\r
1898 DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", Status));\r
1899\r
1900 return Status;\r
1901}\r
1902\r