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