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