]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c
Initialize Data.
[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
0f4e03da
SZ
1126\r
1127 Data = 0;\r
1128\r
64d14edf 1129 CopyMem((VOID*)&PciCfgReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE));\r
1130\r
30f80497 1131 DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfgReadWrite.Address), AndMask, OrMask));\r
64d14edf 1132 \r
1133 Status = ScriptPciCfgRead (\r
1134 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgReadWrite.Width,\r
1135 PciCfgReadWrite.Address,\r
30f80497 1136 1,\r
64d14edf 1137 &Data\r
1138 );\r
1139 if (EFI_ERROR (Status)) {\r
1140 return Status;\r
1141 }\r
1142\r
1143 Data = (Data & AndMask) | OrMask;\r
1144\r
1145 Status = ScriptPciCfgWrite (\r
1146 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgReadWrite.Width,\r
1147 PciCfgReadWrite.Address,\r
30f80497 1148 1,\r
64d14edf 1149 &Data\r
1150 );\r
1151\r
1152 return Status;\r
1153}\r
1154/**\r
30f80497 1155 Interprete the boot script node with EFI_BOOT_SCRIPT_SMBUS_EXECUTE OP code.\r
64d14edf 1156\r
1157 @param Script The pointer of typed node in boot script table \r
1158 \r
1159 @retval EFI_SUCCESS The operation was executed successfully\r
1160 @retval EFI_UNSUPPORTED Cannot locate smbus ppi or occur error of script execution\r
1161 @retval Others Result of script execution \r
1162**/\r
1163EFI_STATUS\r
1164BootScriptExecuteSmbusExecute (\r
1165 IN UINT8 *Script\r
1166 )\r
1167{\r
1168 UINTN SmBusAddress;\r
1169 UINTN DataSize;\r
1170 EFI_BOOT_SCRIPT_SMBUS_EXECUTE SmbusExecuteEntry;\r
1171 \r
1172 CopyMem ((VOID*)&SmbusExecuteEntry, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_SMBUS_EXECUTE ));\r
1173\r
1174 DEBUG ((EFI_D_INFO, "BootScriptExecuteSmbusExecute - 0x%08x, 0x%08x\n", (UINTN)SmbusExecuteEntry.SmBusAddress, (UINTN)SmbusExecuteEntry.Operation));\r
1175\r
1176 SmBusAddress = (UINTN)SmbusExecuteEntry.SmBusAddress;\r
1177 DataSize = (UINTN) SmbusExecuteEntry.DataSize;\r
1178 return SmbusExecute (\r
1179 SmBusAddress,\r
1180 (EFI_SMBUS_OPERATION) SmbusExecuteEntry.Operation,\r
1181 &DataSize,\r
1182 Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)\r
1183 );\r
1184}\r
1185/**\r
30f80497 1186 Interprete the boot script node with EFI_BOOT_SCRIPT_STALL OP code.\r
64d14edf 1187\r
1188 @param Script The pointer of typed node in boot script table \r
1189 \r
1190 @retval EFI_SUCCESS The operation was executed successfully\r
1191**/\r
1192EFI_STATUS\r
1193BootScriptExecuteStall (\r
1194 IN UINT8 *Script\r
1195 )\r
1196{\r
1197 EFI_BOOT_SCRIPT_STALL Stall;\r
1198 \r
1199 CopyMem ((VOID*)&Stall, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_STALL));\r
1200\r
1201 DEBUG ((EFI_D_INFO, "BootScriptExecuteStall - 0x%08x\n", (UINTN)Stall.Duration));\r
1202\r
1203 MicroSecondDelay ((UINTN) Stall.Duration);\r
1204 return EFI_SUCCESS;\r
1205}\r
1206/**\r
30f80497 1207 Interprete the boot script node with EFI_BOOT_SCRIPT_DISPATCH OP code.\r
64d14edf 1208 \r
30f80497
SZ
1209 @param Script The pointer of typed node in boot script table \r
1210 @retval EFI_SUCCESS The operation was executed successfully\r
64d14edf 1211**/\r
1212EFI_STATUS\r
1213BootScriptExecuteDispatch (\r
1214 IN UINT8 *Script\r
1215 )\r
1216{\r
1217 EFI_STATUS Status;\r
1218 DISPATCH_ENTRYPOINT_FUNC EntryFunc;\r
1219 EFI_BOOT_SCRIPT_DISPATCH ScriptDispatch;\r
1220 \r
1221 CopyMem ((VOID*)&ScriptDispatch, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_DISPATCH));\r
1222 EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (ScriptDispatch.EntryPoint);\r
1223\r
1224 DEBUG ((EFI_D_INFO, "BootScriptExecuteDispatch - 0x%08x\n", (UINTN)ScriptDispatch.EntryPoint));\r
1225\r
1226 Status = EntryFunc (NULL, NULL);\r
1227\r
1228 return Status;\r
1229}\r
1230/**\r
30f80497 1231 Interprete the boot script node with EFI_BOOT_SCRIPT_DISPATCH_2 OP code.\r
64d14edf 1232\r
1233 @param Script The pointer of typed node in boot script table \r
1234 @retval EFI_SUCCESS The operation was executed successfully\r
1235**/\r
1236EFI_STATUS\r
1237BootScriptExecuteDispatch2 (\r
1238 IN UINT8 *Script\r
1239 )\r
1240{\r
1241 EFI_STATUS Status;\r
1242 DISPATCH_ENTRYPOINT_FUNC EntryFunc;\r
1243 EFI_BOOT_SCRIPT_DISPATCH_2 ScriptDispatch2;\r
1244 \r
1245 CopyMem ((VOID*)&ScriptDispatch2, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_DISPATCH_2));\r
1246\r
1247 DEBUG ((EFI_D_INFO, "BootScriptExecuteDispatch2 - 0x%08x(0x%08x)\n", (UINTN)ScriptDispatch2.EntryPoint, (UINTN)ScriptDispatch2.Context));\r
1248 \r
1249 EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (ScriptDispatch2.EntryPoint);\r
1250\r
1251 Status = EntryFunc (NULL, (VOID *) (UINTN) ScriptDispatch2.Context);\r
1252\r
1253 return Status;\r
1254}\r
1255/**\r
30f80497 1256 Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_POLL OP code.\r
64d14edf 1257\r
1258 @param Script The pointer of typed node in boot script table \r
1259 @param AndMask Mask value for 'and' operation\r
1260 @param OrMask Mask value for 'or' operation\r
1261 \r
1262 @retval EFI_DEVICE_ERROR Data polled from memory does not equal to \r
1263 the epecting data within the Loop Times.\r
1264 @retval EFI_SUCCESS The operation was executed successfully\r
1265**/\r
1266EFI_STATUS\r
1267BootScriptExecuteMemPoll (\r
1268 IN UINT8 *Script,\r
1269 IN UINT64 AndMask,\r
1270 IN UINT64 OrMask \r
1271 )\r
1272{\r
1273 \r
1274 UINT64 Data;\r
1275 UINT64 LoopTimes;\r
1276 EFI_STATUS Status;\r
1277 EFI_BOOT_SCRIPT_MEM_POLL MemPoll;\r
1278 \r
1279 CopyMem ((VOID*)&MemPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_MEM_POLL));\r
1280\r
30f80497 1281 DEBUG ((EFI_D_INFO, "BootScriptExecuteMemPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemPoll.Address, AndMask, OrMask));\r
64d14edf 1282\r
1283 Data = 0;\r
1284 Status = ScriptMemoryRead (\r
1285 (S3_BOOT_SCRIPT_LIB_WIDTH) MemPoll.Width,\r
1286 MemPoll.Address,\r
1287 1,\r
1288 &Data\r
1289 );\r
1290 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1291 return EFI_SUCCESS;\r
1292 }\r
1293\r
1294 for (LoopTimes = 0; LoopTimes < MemPoll.LoopTimes; LoopTimes++) {\r
1295 NanoSecondDelay ((UINTN)MemPoll.Duration);\r
1296\r
1297 Data = 0;\r
1298 Status = ScriptMemoryRead (\r
1299 (S3_BOOT_SCRIPT_LIB_WIDTH) MemPoll.Width,\r
1300 MemPoll.Address,\r
1301 1,\r
1302 &Data\r
1303 );\r
1304 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1305 return EFI_SUCCESS;\r
1306 }\r
1307 }\r
1308\r
1309 if (LoopTimes < MemPoll.LoopTimes) {\r
1310 return EFI_SUCCESS;\r
1311 } else {\r
1312 return EFI_DEVICE_ERROR;\r
1313 }\r
1314}\r
1315/**\r
30f80497 1316 Execute the boot script to interpret the Store arbitrary information.\r
64d14edf 1317 This opcode is a no-op on dispatch and is only used for debugging script issues.\r
1318\r
1319 @param Script The pointer of node in boot script table \r
1320 \r
1321**/\r
1322VOID\r
1323BootScriptExecuteInformation (\r
1324 IN UINT8 *Script\r
1325 )\r
1326\r
1327{\r
f6ec0c77
JY
1328 UINT32 Index;\r
1329 EFI_BOOT_SCRIPT_INFORMATION Information;\r
93b21ade 1330 UINT8 *InformationData;\r
f6ec0c77 1331\r
93b21ade 1332 CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_INFORMATION));\r
f6ec0c77 1333\r
93b21ade
SZ
1334 InformationData = Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION);\r
1335 DEBUG ((EFI_D_INFO, "BootScriptExecuteInformation - 0x%08x\n", (UINTN) InformationData));\r
f6ec0c77
JY
1336\r
1337 DEBUG ((EFI_D_INFO, "BootScriptInformation: "));\r
1338 for (Index = 0; Index < Information.InformationLength; Index++) {\r
93b21ade 1339 DEBUG ((EFI_D_INFO, "%02x ", InformationData[Index]));\r
f6ec0c77
JY
1340 }\r
1341 DEBUG ((EFI_D_INFO, "\n"));\r
64d14edf 1342}\r
8e4585bb
SZ
1343\r
1344/**\r
1345 Execute the boot script to interpret the Label information. \r
1346\r
1347 @param Script The pointer of node in boot script table \r
1348 \r
1349**/\r
1350VOID\r
1351BootScriptExecuteLabel (\r
1352 IN UINT8 *Script\r
1353 )\r
1354\r
1355{\r
1356 UINT32 Index;\r
1357 EFI_BOOT_SCRIPT_INFORMATION Information;\r
93b21ade 1358 UINT8 *InformationData;\r
8e4585bb 1359\r
93b21ade 1360 CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_INFORMATION));\r
8e4585bb 1361\r
93b21ade
SZ
1362 InformationData = Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION);\r
1363 DEBUG ((EFI_D_INFO, "BootScriptExecuteLabel - 0x%08x\n", (UINTN) InformationData));\r
8e4585bb
SZ
1364\r
1365 DEBUG ((EFI_D_INFO, "BootScriptLabel: "));\r
1366 for (Index = 0; Index < Information.InformationLength; Index++) {\r
93b21ade 1367 DEBUG ((EFI_D_INFO, "%02x ", InformationData[Index]));\r
8e4585bb
SZ
1368 }\r
1369 DEBUG ((EFI_D_INFO, "\n"));\r
1370}\r
1371\r
64d14edf 1372/**\r
1373 calculate the mask value for 'and' and 'or' operation\r
1374 @param ScriptHeader The pointer of header of node in boot script table \r
1375 @param AndMask The Mask value for 'and' operation\r
1376 @param OrMask The Mask value for 'or' operation\r
1377 @param Script Pointer to the entry.\r
1378\r
1379**/\r
1380VOID\r
1381CheckAndOrMask (\r
1382 IN EFI_BOOT_SCRIPT_COMMON_HEADER *ScriptHeader,\r
1383 OUT UINT64 *AndMask,\r
1384 OUT UINT64 *OrMask,\r
1385 IN UINT8 *Script\r
1386 )\r
1387{\r
1388 UINT8 *DataPtr;\r
1389 UINTN Size;\r
1390\r
1391 switch (ScriptHeader->OpCode) {\r
1392 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
1393 Size = sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE);\r
1394 break;\r
1395\r
1396 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
1397 Size = sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE);\r
1398 break;\r
1399\r
1400 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
1401 Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE);\r
1402 break;\r
1403 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
1404 Size = sizeof (EFI_BOOT_SCRIPT_MEM_POLL);\r
1405 break;\r
1406 \r
1407 case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:\r
1408 Size = sizeof (EFI_BOOT_SCRIPT_IO_POLL);\r
1409 break; \r
1410 \r
1411 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
1412 Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE);\r
1413 break;\r
1414 \r
1415 case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r
1416 Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL);\r
1417 break;\r
1418 \r
1419 case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:\r
1420 Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL);\r
1421 break;\r
1422 \r
1423 default:\r
1424 return;\r
1425 }\r
1426 \r
1427 DataPtr = Script + Size;\r
1428\r
1429 switch (ScriptHeader->Width) {\r
1430 case S3BootScriptWidthUint8:\r
1431 *AndMask = (UINT64) *(DataPtr + 1);\r
1432 *OrMask = (UINT64) (*DataPtr);\r
1433 break;\r
1434\r
1435 case S3BootScriptWidthUint16:\r
1436 *AndMask = (UINT64) (*(UINT16 *) (DataPtr + 2));\r
1437 *OrMask = (UINT64) (*(UINT16 *) DataPtr);\r
1438 break;\r
1439\r
1440 case S3BootScriptWidthUint32:\r
1441 *AndMask = (UINT64) (*(UINT32 *) (DataPtr + 4));\r
1442 *OrMask = (UINT64) (*(UINT32 *) DataPtr);\r
1443 break;\r
1444\r
1445 case S3BootScriptWidthUint64:\r
1446 *AndMask = (UINT64) (*(UINT64 *) (DataPtr + 8));\r
1447 *OrMask = (UINT64) (*(UINT64 *) DataPtr);\r
1448 break;\r
1449\r
1450 default:\r
1451 break;\r
1452 }\r
1453\r
1454 return;\r
1455}\r
1456/**\r
30f80497 1457 Interprete the boot script node with EFI_BOOT_SCRIPT_IO_POLL OP code.\r
64d14edf 1458\r
1459 @param Script The pointer of typed node in boot script table \r
1460 @param AndMask Mask value for 'and' operation\r
1461 @param OrMask Mask value for 'or' operation\r
1462 \r
1463 @retval EFI_DEVICE_ERROR Data polled from memory does not equal to \r
1464 the epecting data within the Loop Times.\r
1465 @retval EFI_SUCCESS The operation was executed successfully\r
1466**/\r
1467EFI_STATUS\r
1468BootScriptExecuteIoPoll (\r
1469 IN UINT8 *Script,\r
1470 IN UINT64 AndMask,\r
1471 IN UINT64 OrMask\r
1472 )\r
1473{\r
1474 EFI_STATUS Status;\r
1475 UINT64 Data;\r
1476 UINT64 LoopTimes;\r
1477 EFI_BOOT_SCRIPT_IO_POLL IoPoll;\r
1478 \r
1479 CopyMem ((VOID*)&IoPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_IO_POLL));\r
1480\r
30f80497 1481 DEBUG ((EFI_D_INFO, "BootScriptExecuteIoPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoPoll.Address, AndMask, OrMask));\r
64d14edf 1482\r
1483 Data = 0;\r
1484 Status = ScriptIoRead (\r
1485 (S3_BOOT_SCRIPT_LIB_WIDTH) IoPoll.Width,\r
1486 IoPoll.Address,\r
1487 1,\r
1488 &Data\r
1489 );\r
1490 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1491 return EFI_SUCCESS;\r
1492 }\r
1493 for (LoopTimes = 0; LoopTimes < IoPoll.Delay; LoopTimes++) {\r
1494 NanoSecondDelay (100);\r
1495 Data = 0;\r
1496 Status = ScriptIoRead (\r
1497 (S3_BOOT_SCRIPT_LIB_WIDTH) IoPoll.Width,\r
1498 IoPoll.Address,\r
1499 1,\r
1500 &Data\r
1501 );\r
1502 if ((!EFI_ERROR (Status)) &&(Data & AndMask) == OrMask) {\r
1503 return EFI_SUCCESS;\r
1504 } \r
1505 }\r
1506\r
1507 if (LoopTimes < IoPoll.Delay) {\r
1508 return EFI_SUCCESS;\r
1509 } else {\r
1510 return EFI_DEVICE_ERROR;\r
1511 }\r
1512}\r
1513/**\r
30f80497 1514 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE OP code.\r
64d14edf 1515\r
1516 @param Script The pointer of S3 boot script\r
1517\r
1518 @retval EFI_SUCCESS The operation was executed successfully\r
1519\r
1520**/\r
1521EFI_STATUS\r
1522BootScriptExecutePciCfg2Write (\r
1523 IN UINT8 *Script\r
1524 )\r
1525{\r
30f80497
SZ
1526 VOID *Buffer;\r
1527 S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
1528 UINT16 Segment;\r
1529 UINT64 Address;\r
1530 UINTN Count;\r
1531 EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE PciCfg2Write;\r
64d14edf 1532 \r
1533 CopyMem ((VOID*)&PciCfg2Write, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));\r
64d14edf 1534\r
30f80497
SZ
1535 Width = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2Write.Width;\r
1536 Segment = PciCfg2Write.Segment;\r
1537 Address = PciCfg2Write.Address;\r
1538 Count = PciCfg2Write.Count;\r
1539 Buffer = Script + sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE);\r
1540\r
1541 DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2Write - 0x%04x, 0x%08x, 0x%08x, 0x%08x\n", Segment, PCI_ADDRESS_ENCODE (Address), Count, (UINTN)Width));\r
1542 return ScriptPciCfg2Write (Width, Segment, Address, Count, Buffer);\r
64d14edf 1543}\r
1544\r
1545\r
1546/**\r
30f80497 1547 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE OP code.\r
64d14edf 1548 \r
1549 @param Script The pointer of S3 boot script\r
1550 @param AndMask Mask value for 'and' operation\r
1551 @param OrMask Mask value for 'or' operation\r
1552\r
1553 @retval EFI_SUCCESS The operation was executed successfully\r
1554\r
1555**/\r
1556EFI_STATUS\r
1557BootScriptExecutePciCfg2ReadWrite (\r
1558 IN UINT8 *Script,\r
1559 IN UINT64 AndMask,\r
1560 IN UINT64 OrMask\r
1561 )\r
1562{\r
1563 UINT64 Data;\r
1564 EFI_STATUS Status;\r
1565 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE PciCfg2ReadWrite;\r
0f4e03da
SZ
1566\r
1567 Data = 0;\r
1568\r
64d14edf 1569 CopyMem ((VOID*)&PciCfg2ReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE));\r
1570\r
30f80497 1571 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 1572 \r
1573 Status = ScriptPciCfg2Read (\r
1574 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2ReadWrite.Width,\r
1575 PciCfg2ReadWrite.Segment,\r
1576 PciCfg2ReadWrite.Address,\r
30f80497 1577 1,\r
64d14edf 1578 &Data\r
1579 );\r
1580 if (EFI_ERROR (Status)) {\r
1581 return Status;\r
1582 }\r
1583\r
1584 Data = (Data & AndMask) | OrMask;\r
1585 Status = ScriptPciCfg2Write (\r
1586 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2ReadWrite.Width,\r
1587 PciCfg2ReadWrite.Segment,\r
1588 PciCfg2ReadWrite.Address,\r
30f80497 1589 1,\r
64d14edf 1590 &Data\r
1591 );\r
1592 return Status;\r
1593}\r
1594/**\r
30f80497 1595 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_POLL OP code.\r
64d14edf 1596 \r
1597 @param Script The pointer of S3 boot script\r
1598 @param AndMask Mask value for 'and' operation\r
1599 @param OrMask Mask value for 'or' operation\r
1600\r
1601 @retval EFI_SUCCESS The operation was executed successfully\r
1602 @retval EFI_DEVICE_ERROR Data polled from Pci configuration space does not equal to \r
1603 epecting data within the Loop Times.\r
1604**/\r
1605EFI_STATUS\r
1606BootScriptPciCfgPoll (\r
1607 IN UINT8 *Script,\r
1608 IN UINT64 AndMask,\r
1609 IN UINT64 OrMask \r
1610 )\r
1611{\r
1612 UINT64 Data;\r
1613 UINT64 LoopTimes;\r
1614 EFI_STATUS Status;\r
1615 EFI_BOOT_SCRIPT_PCI_CONFIG_POLL PciCfgPoll;\r
1616 CopyMem ((VOID*)&PciCfgPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_POLL));\r
1617\r
30f80497 1618 DEBUG ((EFI_D_INFO, "BootScriptPciCfgPoll - 0x%08x, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfgPoll.Address), AndMask, OrMask));\r
64d14edf 1619 \r
1620 Data = 0;\r
1621 Status = ScriptPciCfgRead (\r
1622 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgPoll.Width,\r
1623 PciCfgPoll.Address,\r
30f80497 1624 1,\r
64d14edf 1625 &Data\r
1626 );\r
1627 if ((!EFI_ERROR (Status)) &&(Data & AndMask) == OrMask) {\r
1628 return EFI_SUCCESS;\r
1629 }\r
1630\r
1631 for (LoopTimes = 0; LoopTimes < PciCfgPoll.Delay; LoopTimes++) {\r
1632 NanoSecondDelay (100);\r
1633 Data = 0;\r
1634 Status = ScriptPciCfgRead (\r
1635 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgPoll.Width,\r
1636 PciCfgPoll.Address,\r
30f80497 1637 1,\r
64d14edf 1638 &Data\r
1639 );\r
1640 if ((!EFI_ERROR (Status)) &&\r
1641 (Data & AndMask) == OrMask) {\r
1642 return EFI_SUCCESS;\r
1643 }\r
1644 }\r
1645\r
1646 if (LoopTimes < PciCfgPoll.Delay) {\r
1647 return EFI_SUCCESS;\r
1648 } else {\r
1649 return EFI_DEVICE_ERROR;\r
1650 }\r
1651}\r
1652\r
1653/**\r
30f80497 1654 Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL OP code.\r
64d14edf 1655 \r
1656 @param Script The pointer of S3 Boot Script\r
1657 @param AndMask Mask value for 'and' operation\r
1658 @param OrMask Mask value for 'or' operation\r
1659\r
1660 @retval EFI_SUCCESS The operation was executed successfully\r
1661 @retval EFI_DEVICE_ERROR Data polled from Pci configuration space does not equal to \r
1662 epecting data within the Loop Times.\r
1663\r
1664**/\r
1665EFI_STATUS\r
1666BootScriptPciCfg2Poll (\r
1667 IN UINT8 *Script,\r
1668 IN UINT64 AndMask,\r
1669 IN UINT64 OrMask \r
1670 )\r
1671{\r
1672 EFI_STATUS Status;\r
1673 UINT64 Data;\r
1674 UINT64 LoopTimes;\r
1675 EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL PciCfg2Poll;\r
1676\r
1677 Data = 0;\r
1678 CopyMem ((VOID*)&PciCfg2Poll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL));\r
1679\r
30f80497 1680 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 1681 \r
1682 Status = ScriptPciCfg2Read (\r
1683 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Poll.Width,\r
1684 PciCfg2Poll.Segment,\r
1685 PciCfg2Poll.Address,\r
30f80497 1686 1,\r
64d14edf 1687 &Data\r
1688 );\r
1689 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1690 return EFI_SUCCESS;\r
1691 }\r
1692\r
1693 for (LoopTimes = 0; LoopTimes < PciCfg2Poll.Delay; LoopTimes++) {\r
1694 NanoSecondDelay (100);\r
1695\r
1696 Data = 0;\r
1697 Status = ScriptPciCfg2Read (\r
1698 (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Poll.Width,\r
1699 PciCfg2Poll.Segment, \r
1700 PciCfg2Poll.Address,\r
30f80497 1701 1,\r
64d14edf 1702 &Data\r
1703 );\r
1704 if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r
1705 return EFI_SUCCESS;\r
1706 }\r
1707 }\r
1708\r
1709 if (LoopTimes < PciCfg2Poll.Delay) {\r
1710 return EFI_SUCCESS;\r
1711 } else {\r
1712 return EFI_DEVICE_ERROR;\r
1713 }\r
1714 \r
1715}\r
1716\r
1717/**\r
1718 Executes the S3 boot script table.\r
1719 \r
1720 @retval RETURN_SUCCESS The boot script table was executed successfully.\r
1721 @retval RETURN_UNSUPPORTED Invalid script table or opcode. \r
1722 \r
1723 @note A known Limitations in the implementation: When interpreting the opcode EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\r
1724 EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE and EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE, the 'Segment' parameter is assumed as \r
1725 Zero, or else, assert.\r
1726**/\r
1727RETURN_STATUS\r
1728EFIAPI\r
1729S3BootScriptExecute (\r
1730 VOID\r
1731 )\r
1732{\r
1733 EFI_STATUS Status;\r
1734 UINT8* Script;\r
1735 UINTN StartAddress;\r
1736 UINT32 TableLength;\r
1737 UINT64 AndMask;\r
1738 UINT64 OrMask;\r
1739 EFI_BOOT_SCRIPT_COMMON_HEADER ScriptHeader;\r
1740 EFI_BOOT_SCRIPT_TABLE_HEADER TableHeader;\r
1741 Script = mS3BootScriptTablePtr->TableBase;\r
1742 if (Script != 0) { \r
1743 CopyMem ((VOID*)&TableHeader, Script, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));\r
1744 } else {\r
1745 return EFI_INVALID_PARAMETER;\r
1746 }\r
1747\r
1748 DEBUG ((EFI_D_INFO, "S3BootScriptExecute:\n"));\r
1749 if (TableHeader.OpCode != S3_BOOT_SCRIPT_LIB_TABLE_OPCODE) {\r
1750 return EFI_UNSUPPORTED;\r
1751 }\r
1752\r
1753 DEBUG ((EFI_D_INFO, "TableHeader - 0x%08x\n", Script));\r
1754 \r
1755 StartAddress = (UINTN) Script;\r
1756 TableLength = TableHeader.TableLength;\r
1757 Script = Script + TableHeader.Length;\r
1758 Status = EFI_SUCCESS;\r
1759 AndMask = 0;\r
1760 OrMask = 0;\r
1761\r
1762 DEBUG ((EFI_D_INFO, "TableHeader.TableLength - 0x%08x\n", (UINTN)TableLength));\r
1763\r
1764 while ((UINTN) Script < (UINTN) (StartAddress + TableLength)) {\r
1765 DEBUG ((EFI_D_INFO, "ExecuteBootScript - %08x\n", (UINTN)Script));\r
1766 \r
1767 CopyMem ((VOID*)&ScriptHeader, Script, sizeof(EFI_BOOT_SCRIPT_COMMON_HEADER));\r
1768 switch (ScriptHeader.OpCode) {\r
1769\r
1770 case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:\r
1771 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE\n"));\r
1772 Status = BootScriptExecuteMemoryWrite (Script);\r
1773 break;\r
1774\r
1775 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
1776 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE\n"));\r
1777 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1778 Status = BootScriptExecuteMemoryReadWrite (\r
1779 Script,\r
1780 AndMask,\r
1781 OrMask\r
1782 );\r
1783 break;\r
1784\r
1785 case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:\r
1786 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_WRITE_OPCODE\n"));\r
1787 Status = BootScriptExecuteIoWrite (Script);\r
1788 break;\r
1789\r
1790 case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:\r
1791 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE\n"));\r
1792 Status = BootScriptExecutePciCfgWrite (Script);\r
1793 break;\r
1794\r
1795 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
1796 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE\n"));\r
1797 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1798 Status = BootScriptExecutePciCfgReadWrite (\r
1799 Script,\r
1800 AndMask,\r
1801 OrMask\r
1802 );\r
1803 break;\r
1804 case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:\r
1805 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\n"));\r
1806 Status = BootScriptExecutePciCfg2Write (Script);\r
1807 break;\r
1808\r
1809 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
1810 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE\n"));\r
1811 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1812 Status = BootScriptExecutePciCfg2ReadWrite (\r
1813 Script,\r
1814 AndMask,\r
1815 OrMask\r
1816 );\r
1817 break;\r
1818 case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:\r
1819 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_DISPATCH_OPCODE\n"));\r
1820 Status = BootScriptExecuteDispatch (Script);\r
1821 break;\r
1822\r
1823 case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:\r
1824 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE\n"));\r
1825 Status = BootScriptExecuteDispatch2 (Script);\r
1826 break;\r
1827\r
1828 case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
1829 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_INFORMATION_OPCODE\n"));\r
1830 BootScriptExecuteInformation (Script);\r
1831 break; \r
1832\r
1833 case S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE:\r
1834 DEBUG ((EFI_D_INFO, "S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE\n"));\r
8e4585bb 1835 DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", EFI_SUCCESS));\r
64d14edf 1836 return EFI_SUCCESS;\r
1837\r
1838 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
1839 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE\n"));\r
1840 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1841 Status = BootScriptExecuteIoReadWrite (\r
1842 Script,\r
1843 AndMask,\r
1844 OrMask\r
1845 );\r
1846 break;\r
1847\r
1848 case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:\r
1849 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE\n"));\r
1850 Status = BootScriptExecuteSmbusExecute (Script);\r
1851 break;\r
1852\r
1853 case EFI_BOOT_SCRIPT_STALL_OPCODE:\r
1854 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_STALL_OPCODE\n"));\r
1855 Status = BootScriptExecuteStall (Script);\r
1856 break;\r
1857\r
1858 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
1859 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_POLL_OPCODE\n"));\r
1860 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1861 Status = BootScriptExecuteMemPoll (Script, AndMask, OrMask);\r
1862 \r
1863 break;\r
1864 \r
1865 case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:\r
1866 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_POLL_OPCODE\n"));\r
1867 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1868 Status = BootScriptExecuteIoPoll (Script, AndMask, OrMask);\r
1869 break;\r
1870 \r
1871 case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:\r
1872 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE\n"));\r
1873 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1874 Status = BootScriptPciCfgPoll (Script, AndMask, OrMask);\r
1875 break;\r
1876 \r
1877 case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r
1878 DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE\n"));\r
1879 CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r
1880 Status = BootScriptPciCfg2Poll (Script, AndMask, OrMask);\r
1881 break;\r
1882\r
1883 case S3_BOOT_SCRIPT_LIB_LABEL_OPCODE:\r
1884 //\r
1885 // For label\r
1886 //\r
1887 DEBUG ((EFI_D_INFO, "S3_BOOT_SCRIPT_LIB_LABEL_OPCODE\n"));\r
8e4585bb 1888 BootScriptExecuteLabel (Script);\r
64d14edf 1889 break;\r
1890 default:\r
1891 DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", EFI_UNSUPPORTED));\r
1892 return EFI_UNSUPPORTED;\r
1893 }\r
1894\r
1895 if (EFI_ERROR (Status)) {\r
1896 DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", Status));\r
1897 return Status;\r
1898 }\r
1899\r
1900 Script = Script + ScriptHeader.Length;\r
1901 }\r
1902\r
1903 DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", Status));\r
1904\r
1905 return Status;\r
1906}\r
1907\r