]>
Commit | Line | Data |
---|---|---|
64d14edf | 1 | /** @file\r |
3a03e95e | 2 | Interpret and execute the S3 data in S3 boot script.\r |
64d14edf | 3 | \r |
3d20524a | 4 | Copyright (c) 2006 - 2016, 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 | |
3a03e95e | 26 | @param SmbusAddress Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length,\r |
64d14edf | 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 | |
59 | EFI_STATUS\r | |
60 | SmbusExecute (\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 | |
3a03e95e | 123 | return Status;\r |
64d14edf | 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 | |
3a03e95e | 133 | @param BufferStride Outstride for stepping output buffer.\r |
64d14edf | 134 | \r |
135 | @retval EFI_SUCCESS Successful translation.\r | |
136 | @retval EFI_INVALID_PARAMETER Width or Address is invalid.\r | |
137 | **/\r | |
138 | EFI_STATUS\r | |
139 | BuildLoopData (\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 |
3a03e95e | 173 | \r |
64d14edf | 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 | |
3a03e95e | 177 | @param[out] Buffer Pointer to the buffer to read from I/O space.\r |
64d14edf | 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 | |
3a03e95e SZ |
183 | Address is outside the legal range of I/O ports.\r |
184 | \r | |
64d14edf | 185 | **/\r |
186 | EFI_STATUS\r | |
187 | ScriptIoRead (\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 |
3a03e95e | 277 | \r |
64d14edf | 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 | |
3a03e95e | 281 | @param[in] Buffer Pointer to the buffer to write to I/O space.\r |
64d14edf | 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 | |
3a03e95e SZ |
287 | Address is outside the legal range of I/O ports.\r |
288 | \r | |
64d14edf | 289 | **/\r |
290 | EFI_STATUS\r | |
291 | ScriptIoWrite (\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 | |
3a03e95e | 325 | break;\r |
64d14edf | 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 | |
3a03e95e | 329 | break;\r |
64d14edf | 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 | |
3a03e95e | 337 | break;\r |
64d14edf | 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 | |
3a03e95e | 341 | break;\r |
64d14edf | 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 | |
3a03e95e | 349 | break;\r |
64d14edf | 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 | |
3a03e95e | 361 | break;\r |
64d14edf | 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 |
3a03e95e | 365 | break;\r |
64d14edf | 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 | |
3a03e95e | 374 | \r |
64d14edf | 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 |
3a03e95e | 380 | \r |
64d14edf | 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 | |
3a03e95e SZ |
387 | Address is outside the legal range of I/O ports.\r |
388 | \r | |
64d14edf | 389 | **/\r |
390 | EFI_STATUS\r | |
391 | BootScriptExecuteIoWrite (\r | |
3a03e95e | 392 | IN UINT8 *Script\r |
64d14edf | 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 | |
3a03e95e | 400 | \r |
64d14edf | 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 | |
3a03e95e | 412 | \r |
64d14edf | 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 | |
3a03e95e | 416 | @param Buffer Pointer to the buffer read from memory.\r |
64d14edf | 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 | |
3a03e95e SZ |
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 | |
64d14edf | 425 | **/\r |
426 | EFI_STATUS\r | |
427 | ScriptMemoryRead (\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 |
3a03e95e | 511 | \r |
64d14edf | 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 | |
3a03e95e | 515 | @param Buffer Pointer to the buffer write to memory.\r |
64d14edf | 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 | |
3a03e95e SZ |
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 | |
64d14edf | 524 | **/\r |
525 | EFI_STATUS\r | |
526 | ScriptMemoryWrite (\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 | |
3a03e95e | 535 | UINT64 OriginalAddress;\r |
64d14edf | 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 | |
3a03e95e | 550 | OriginalIn.Buf = In.Buf;\r |
64d14edf | 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 | |
3a03e95e | 556 | break;\r |
64d14edf | 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 | |
3a03e95e | 560 | break;\r |
64d14edf | 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 | |
3a03e95e | 568 | break;\r |
64d14edf | 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 | |
3a03e95e | 572 | break;\r |
64d14edf | 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 | |
3a03e95e | 580 | break;\r |
64d14edf | 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 | |
3a03e95e | 584 | break;\r |
64d14edf | 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 | |
3a03e95e | 592 | break;\r |
64d14edf | 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 | |
3a03e95e | 596 | break;\r |
64d14edf | 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 | |
3a03e95e | 611 | \r |
64d14edf | 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 | |
3a03e95e SZ |
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 | |
64d14edf | 619 | **/\r |
620 | EFI_STATUS\r | |
621 | BootScriptExecuteMemoryWrite (\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 | |
3a03e95e | 630 | \r |
64d14edf | 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 |
3a03e95e SZ |
639 | \r |
640 | }\r | |
64d14edf | 641 | /**\r |
3d20524a | 642 | Performance PCI configuration 2 read operation\r |
64d14edf | 643 | \r |
644 | @param Width Width of the operation.\r | |
3d20524a | 645 | @param Segment Pci segment number\r |
64d14edf | 646 | @param Address Address of the operation.\r |
30f80497 SZ |
647 | @param Count Count of the number of accesses to perform.\r |
648 | @param Buffer Pointer to the buffer read from PCI config space\r | |
3a03e95e | 649 | \r |
64d14edf | 650 | @retval EFI_SUCCESS The read succeed.\r |
3a03e95e | 651 | @retval EFI_INVALID_PARAMETER if Width is not defined\r |
2a956f74 SZ |
652 | @note A known Limitations in the implementation which is 64bits operations are not supported.\r |
653 | \r | |
64d14edf | 654 | **/\r |
655 | EFI_STATUS\r | |
3d20524a | 656 | ScriptPciCfg2Read (\r |
64d14edf | 657 | IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r |
3d20524a | 658 | IN UINT16 Segment,\r |
64d14edf | 659 | IN UINT64 Address,\r |
30f80497 | 660 | IN UINTN Count,\r |
64d14edf | 661 | OUT VOID *Buffer\r |
662 | )\r | |
663 | {\r | |
30f80497 SZ |
664 | EFI_STATUS Status;\r |
665 | UINTN AddressStride;\r | |
666 | UINTN BufferStride;\r | |
667 | PTR Out;\r | |
3d20524a | 668 | UINT64 PciAddress;\r |
30f80497 SZ |
669 | \r |
670 | Out.Buf = (UINT8 *) Buffer;\r | |
671 | \r | |
3d20524a | 672 | PciAddress = PCI_ADDRESS_ENCODE (Segment, Address);\r |
30f80497 SZ |
673 | \r |
674 | Status = BuildLoopData (Width, PciAddress, &AddressStride, &BufferStride);\r | |
675 | if (EFI_ERROR (Status)) {\r | |
676 | return Status;\r | |
677 | }\r | |
678 | //\r | |
679 | // Loop for each iteration and move the data\r | |
680 | //\r | |
681 | for (; Count > 0; Count--, PciAddress += AddressStride, Out.Buf += BufferStride) {\r | |
64d14edf | 682 | switch (Width) {\r |
683 | case S3BootScriptWidthUint8:\r | |
3d20524a SZ |
684 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%016lx\n", PciAddress));\r |
685 | *Out.Uint8 = PciSegmentRead8 (PciAddress);\r | |
30f80497 SZ |
686 | break;\r |
687 | case S3BootScriptWidthFifoUint8:\r | |
3d20524a SZ |
688 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%016lx\n", PciAddress));\r |
689 | *Out.Uint8 = PciSegmentRead8 (PciAddress);\r | |
30f80497 SZ |
690 | break;\r |
691 | case S3BootScriptWidthFillUint8:\r | |
3d20524a SZ |
692 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%016lx\n", PciAddress));\r |
693 | *Out.Uint8 = PciSegmentRead8 (PciAddress);\r | |
64d14edf | 694 | break;\r |
695 | \r | |
696 | case S3BootScriptWidthUint16:\r | |
3d20524a SZ |
697 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%016lx\n", PciAddress));\r |
698 | *Out.Uint16 = PciSegmentRead16 (PciAddress);\r | |
30f80497 SZ |
699 | break;\r |
700 | case S3BootScriptWidthFifoUint16:\r | |
3d20524a SZ |
701 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%016lx\n", PciAddress));\r |
702 | *Out.Uint16 = PciSegmentRead16 (PciAddress);\r | |
30f80497 SZ |
703 | break;\r |
704 | case S3BootScriptWidthFillUint16:\r | |
3d20524a SZ |
705 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%016lx\n", PciAddress));\r |
706 | *Out.Uint16 = PciSegmentRead16 (PciAddress);\r | |
64d14edf | 707 | break;\r |
708 | \r | |
709 | case S3BootScriptWidthUint32:\r | |
3d20524a SZ |
710 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%016lx\n", PciAddress));\r |
711 | *Out.Uint32 = PciSegmentRead32 (PciAddress);\r | |
30f80497 SZ |
712 | break;\r |
713 | case S3BootScriptWidthFifoUint32:\r | |
3d20524a SZ |
714 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%016lx\n", PciAddress));\r |
715 | *Out.Uint32 = PciSegmentRead32 (PciAddress);\r | |
30f80497 SZ |
716 | break;\r |
717 | case S3BootScriptWidthFillUint32:\r | |
3d20524a SZ |
718 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%016lx\n", PciAddress));\r |
719 | *Out.Uint32 = PciSegmentRead32 (PciAddress);\r | |
64d14edf | 720 | break;\r |
721 | \r | |
722 | default:\r | |
723 | return EFI_INVALID_PARAMETER;\r | |
30f80497 | 724 | }\r |
64d14edf | 725 | }\r |
30f80497 | 726 | return EFI_SUCCESS;\r |
64d14edf | 727 | }\r |
728 | \r | |
729 | /**\r | |
3d20524a | 730 | Performance PCI configuration 2 write operation\r |
64d14edf | 731 | \r |
732 | @param Width Width of the operation.\r | |
3d20524a | 733 | @param Segment Pci segment number\r |
64d14edf | 734 | @param Address Address of the operation.\r |
30f80497 SZ |
735 | @param Count Count of the number of accesses to perform.\r |
736 | @param Buffer Pointer to the buffer write to PCI config space\r | |
3a03e95e | 737 | \r |
64d14edf | 738 | @retval EFI_SUCCESS The write succeed.\r |
3a03e95e | 739 | @retval EFI_INVALID_PARAMETER if Width is not defined\r |
2a956f74 SZ |
740 | @note A known Limitations in the implementation which is 64bits operations are not supported.\r |
741 | \r | |
64d14edf | 742 | **/\r |
743 | EFI_STATUS\r | |
3d20524a | 744 | ScriptPciCfg2Write (\r |
64d14edf | 745 | IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r |
3d20524a | 746 | IN UINT16 Segment,\r |
64d14edf | 747 | IN UINT64 Address,\r |
30f80497 SZ |
748 | IN UINTN Count,\r |
749 | IN VOID *Buffer\r | |
64d14edf | 750 | )\r |
751 | {\r | |
30f80497 SZ |
752 | EFI_STATUS Status;\r |
753 | UINTN AddressStride;\r | |
754 | UINTN BufferStride;\r | |
3d20524a | 755 | UINT64 OriginalPciAddress;\r |
30f80497 SZ |
756 | PTR In;\r |
757 | PTR OriginalIn;\r | |
3d20524a | 758 | UINT64 PciAddress;\r |
30f80497 SZ |
759 | \r |
760 | In.Buf = (UINT8 *) Buffer;\r | |
761 | \r | |
3d20524a | 762 | PciAddress = PCI_ADDRESS_ENCODE (Segment, Address);\r |
30f80497 SZ |
763 | \r |
764 | Status = BuildLoopData (Width, PciAddress, &AddressStride, &BufferStride);\r | |
765 | if (EFI_ERROR (Status)) {\r | |
766 | return Status;\r | |
64d14edf | 767 | }\r |
30f80497 SZ |
768 | //\r |
769 | // Loop for each iteration and move the data\r | |
770 | //\r | |
771 | OriginalPciAddress = PciAddress;\r | |
772 | OriginalIn.Buf = In.Buf;\r | |
773 | for (; Count > 0; Count--, PciAddress += AddressStride, In.Buf += BufferStride) {\r | |
774 | switch (Width) {\r | |
775 | case S3BootScriptWidthUint8:\r | |
3d20524a SZ |
776 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%016lx (0x%02x)\n", PciAddress, (UINTN)*In.Uint8));\r |
777 | PciSegmentWrite8 (PciAddress, *In.Uint8);\r | |
3a03e95e | 778 | break;\r |
30f80497 | 779 | case S3BootScriptWidthFifoUint8:\r |
3d20524a SZ |
780 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%016lx (0x%02x)\n", OriginalPciAddress, (UINTN)*In.Uint8));\r |
781 | PciSegmentWrite8 (OriginalPciAddress, *In.Uint8);\r | |
3a03e95e | 782 | break;\r |
30f80497 | 783 | case S3BootScriptWidthFillUint8:\r |
3d20524a SZ |
784 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%016lx (0x%02x)\n", PciAddress, (UINTN)*OriginalIn.Uint8));\r |
785 | PciSegmentWrite8 (PciAddress, *OriginalIn.Uint8);\r | |
30f80497 SZ |
786 | break;\r |
787 | case S3BootScriptWidthUint16:\r | |
3d20524a SZ |
788 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%016lx (0x%04x)\n", PciAddress, (UINTN)*In.Uint16));\r |
789 | PciSegmentWrite16 (PciAddress, *In.Uint16);\r | |
3a03e95e | 790 | break;\r |
30f80497 | 791 | case S3BootScriptWidthFifoUint16:\r |
3d20524a SZ |
792 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%016lx (0x%04x)\n", OriginalPciAddress, (UINTN)*In.Uint16));\r |
793 | PciSegmentWrite16 (OriginalPciAddress, *In.Uint16);\r | |
3a03e95e | 794 | break;\r |
30f80497 | 795 | case S3BootScriptWidthFillUint16:\r |
3d20524a SZ |
796 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%016lx (0x%04x)\n", PciAddress, (UINTN)*OriginalIn.Uint16));\r |
797 | PciSegmentWrite16 (PciAddress, *OriginalIn.Uint16);\r | |
30f80497 SZ |
798 | break;\r |
799 | case S3BootScriptWidthUint32:\r | |
3d20524a SZ |
800 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%016lx (0x%08x)\n", PciAddress, (UINTN)*In.Uint32));\r |
801 | PciSegmentWrite32 (PciAddress, *In.Uint32);\r | |
3a03e95e | 802 | break;\r |
30f80497 | 803 | case S3BootScriptWidthFifoUint32:\r |
3d20524a SZ |
804 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%016lx (0x%08x)\n", OriginalPciAddress, (UINTN)*In.Uint32));\r |
805 | PciSegmentWrite32 (OriginalPciAddress, *In.Uint32);\r | |
3a03e95e | 806 | break;\r |
30f80497 | 807 | case S3BootScriptWidthFillUint32:\r |
3d20524a SZ |
808 | DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%016lx (0x%08x)\n", (UINTN)PciAddress, (UINTN)*OriginalIn.Uint32));\r |
809 | PciSegmentWrite32 (PciAddress, *OriginalIn.Uint32);\r | |
30f80497 SZ |
810 | break;\r |
811 | default:\r | |
812 | return EFI_INVALID_PARAMETER;\r | |
813 | }\r | |
814 | }\r | |
815 | return EFI_SUCCESS;\r | |
64d14edf | 816 | }\r |
817 | /**\r | |
3d20524a | 818 | Performance PCI configuration read operation\r |
3a03e95e | 819 | \r |
64d14edf | 820 | @param Width Width of the operation.\r |
64d14edf | 821 | @param Address Address of the operation.\r |
30f80497 SZ |
822 | @param Count Count of the number of accesses to perform.\r |
823 | @param Buffer Pointer to the buffer to read from PCI config space.\r | |
64d14edf | 824 | \r |
825 | @retval EFI_SUCCESS The data was written to the EFI System.\r | |
826 | @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r | |
827 | Buffer is NULL.\r | |
828 | The Buffer is not aligned for the given Width.\r | |
829 | Address is outside the legal range of I/O ports.\r | |
3d20524a | 830 | \r |
64d14edf | 831 | **/\r |
832 | EFI_STATUS\r | |
3d20524a | 833 | ScriptPciCfgRead (\r |
64d14edf | 834 | IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r |
64d14edf | 835 | IN UINT64 Address,\r |
30f80497 | 836 | IN UINTN Count,\r |
64d14edf | 837 | OUT VOID *Buffer\r |
838 | )\r | |
839 | {\r | |
3d20524a | 840 | return ScriptPciCfg2Read (Width, 0, Address, Count, Buffer);\r |
64d14edf | 841 | }\r |
842 | /**\r | |
3d20524a | 843 | Performance PCI configuration write operation\r |
3a03e95e | 844 | \r |
64d14edf | 845 | @param Width Width of the operation.\r |
64d14edf | 846 | @param Address Address of the operation.\r |
30f80497 SZ |
847 | @param Count Count of the number of accesses to perform.\r |
848 | @param Buffer Pointer to the buffer to write to PCI config space.\r | |
64d14edf | 849 | \r |
850 | @retval EFI_SUCCESS The data was written to the EFI System.\r | |
851 | @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.\r | |
852 | Buffer is NULL.\r | |
853 | The Buffer is not aligned for the given Width.\r | |
854 | Address is outside the legal range of I/O ports.\r | |
3a03e95e | 855 | \r |
64d14edf | 856 | **/\r |
857 | EFI_STATUS\r | |
858 | EFIAPI\r | |
3d20524a | 859 | ScriptPciCfgWrite (\r |
64d14edf | 860 | IN S3_BOOT_SCRIPT_LIB_WIDTH Width,\r |
64d14edf | 861 | IN UINT64 Address,\r |
30f80497 SZ |
862 | IN UINTN Count,\r |
863 | IN VOID *Buffer\r | |
64d14edf | 864 | )\r |
865 | {\r | |
3d20524a | 866 | return ScriptPciCfg2Write (Width, 0, Address, Count, Buffer);\r |
64d14edf | 867 | }\r |
868 | /**\r | |
30f80497 | 869 | Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE OP code.\r |
3a03e95e SZ |
870 | \r |
871 | @param Script The pointer of typed node in boot script table\r | |
872 | \r | |
64d14edf | 873 | @retval EFI_SUCCESS The operation was executed successfully\r |
874 | **/\r | |
875 | EFI_STATUS\r | |
876 | BootScriptExecutePciCfgWrite (\r | |
877 | IN UINT8 *Script\r | |
878 | )\r | |
879 | {\r | |
30f80497 SZ |
880 | VOID *Buffer;\r |
881 | S3_BOOT_SCRIPT_LIB_WIDTH Width;\r | |
882 | UINT64 Address;\r | |
883 | UINTN Count;\r | |
884 | EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE PciCfgWrite;\r | |
64d14edf | 885 | \r |
30f80497 | 886 | CopyMem ((VOID*)&PciCfgWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));\r |
64d14edf | 887 | \r |
30f80497 SZ |
888 | Width = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfgWrite.Width;\r |
889 | Address = PciCfgWrite.Address;\r | |
890 | Count = PciCfgWrite.Count;\r | |
891 | Buffer = Script + sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE);\r | |
64d14edf | 892 | \r |
3d20524a | 893 | DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgWrite - 0x%016lx, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (0, Address), Count, (UINTN)Width));\r |
30f80497 | 894 | return ScriptPciCfgWrite (Width, Address, Count, Buffer);\r |
64d14edf | 895 | }\r |
896 | /**\r | |
30f80497 | 897 | Interprete the boot script node with EFI_BOOT_SCRIPT_IO_READ_WRITE OP code.\r |
64d14edf | 898 | \r |
3a03e95e | 899 | @param Script The pointer of typed node in boot script table\r |
64d14edf | 900 | @param AndMask Mask value for 'and' operation\r |
901 | @param OrMask Mask value for 'or' operation\r | |
902 | \r | |
903 | @retval EFI_SUCCESS The operation was executed successfully\r | |
904 | **/\r | |
905 | EFI_STATUS\r | |
906 | BootScriptExecuteIoReadWrite (\r | |
907 | IN UINT8 *Script,\r | |
908 | IN UINT64 AndMask,\r | |
909 | IN UINT64 OrMask\r | |
910 | )\r | |
911 | \r | |
912 | {\r | |
913 | EFI_STATUS Status;\r | |
914 | UINT64 Data;\r | |
915 | EFI_BOOT_SCRIPT_IO_READ_WRITE IoReadWrite;\r | |
3a03e95e | 916 | \r |
64d14edf | 917 | Data = 0;\r |
3a03e95e | 918 | \r |
64d14edf | 919 | CopyMem((VOID*)&IoReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_IO_READ_WRITE));\r |
920 | \r | |
30f80497 | 921 | DEBUG ((EFI_D_INFO, "BootScriptExecuteIoReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoReadWrite.Address, AndMask, OrMask));\r |
64d14edf | 922 | \r |
923 | Status = ScriptIoRead (\r | |
924 | (S3_BOOT_SCRIPT_LIB_WIDTH) IoReadWrite.Width,\r | |
925 | IoReadWrite.Address,\r | |
926 | 1,\r | |
927 | &Data\r | |
928 | );\r | |
929 | if (!EFI_ERROR (Status)) {\r | |
930 | Data = (Data & AndMask) | OrMask;\r | |
931 | Status = ScriptIoWrite (\r | |
932 | (S3_BOOT_SCRIPT_LIB_WIDTH) IoReadWrite.Width,\r | |
933 | IoReadWrite.Address,\r | |
934 | 1,\r | |
935 | &Data\r | |
936 | );\r | |
937 | }\r | |
938 | return Status;\r | |
939 | }\r | |
940 | /**\r | |
30f80497 | 941 | Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_READ_WRITE OP code.\r |
64d14edf | 942 | \r |
3a03e95e | 943 | @param Script The pointer of typed node in boot script table\r |
64d14edf | 944 | @param AndMask Mask value for 'and' operation\r |
945 | @param OrMask Mask value for 'or' operation\r | |
946 | \r | |
947 | @retval EFI_SUCCESS The operation was executed successfully\r | |
948 | **/\r | |
949 | EFI_STATUS\r | |
950 | BootScriptExecuteMemoryReadWrite (\r | |
951 | IN UINT8 *Script,\r | |
952 | IN UINT64 AndMask,\r | |
953 | IN UINT64 OrMask\r | |
954 | )\r | |
955 | \r | |
956 | {\r | |
957 | EFI_STATUS Status;\r | |
958 | UINT64 Data;\r | |
959 | EFI_BOOT_SCRIPT_MEM_READ_WRITE MemReadWrite;\r | |
3a03e95e | 960 | \r |
64d14edf | 961 | Data = 0;\r |
3a03e95e | 962 | \r |
64d14edf | 963 | CopyMem((VOID*)&MemReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_MEM_READ_WRITE));\r |
964 | \r | |
30f80497 | 965 | DEBUG ((EFI_D_INFO, "BootScriptExecuteMemoryReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemReadWrite.Address, AndMask, OrMask));\r |
3a03e95e | 966 | \r |
64d14edf | 967 | Status = ScriptMemoryRead (\r |
968 | (S3_BOOT_SCRIPT_LIB_WIDTH) MemReadWrite.Width,\r | |
969 | MemReadWrite.Address,\r | |
970 | 1,\r | |
971 | &Data\r | |
972 | );\r | |
973 | if (!EFI_ERROR (Status)) {\r | |
974 | Data = (Data & AndMask) | OrMask;\r | |
975 | Status = ScriptMemoryWrite (\r | |
976 | (S3_BOOT_SCRIPT_LIB_WIDTH) MemReadWrite.Width,\r | |
977 | MemReadWrite.Address,\r | |
978 | 1,\r | |
979 | &Data\r | |
980 | );\r | |
981 | }\r | |
982 | return Status;\r | |
983 | }\r | |
984 | /**\r | |
30f80497 | 985 | Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CFG_READ_WRITE OP code.\r |
64d14edf | 986 | \r |
3a03e95e | 987 | @param Script The pointer of typed node in boot script table\r |
64d14edf | 988 | @param AndMask Mask value for 'and' operation\r |
989 | @param OrMask Mask value for 'or' operation\r | |
990 | \r | |
991 | @retval EFI_SUCCESS The operation was executed successfully\r | |
992 | **/\r | |
993 | EFI_STATUS\r | |
994 | BootScriptExecutePciCfgReadWrite (\r | |
995 | IN UINT8 *Script,\r | |
996 | IN UINT64 AndMask,\r | |
997 | IN UINT64 OrMask\r | |
998 | )\r | |
999 | \r | |
1000 | {\r | |
1001 | EFI_STATUS Status;\r | |
1002 | UINT64 Data;\r | |
1003 | EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE PciCfgReadWrite;\r | |
0f4e03da SZ |
1004 | \r |
1005 | Data = 0;\r | |
1006 | \r | |
64d14edf | 1007 | CopyMem((VOID*)&PciCfgReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE));\r |
1008 | \r | |
3d20524a | 1009 | DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfgReadWrite - 0x%016lx, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (0, PciCfgReadWrite.Address), AndMask, OrMask));\r |
3a03e95e | 1010 | \r |
64d14edf | 1011 | Status = ScriptPciCfgRead (\r |
1012 | (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgReadWrite.Width,\r | |
1013 | PciCfgReadWrite.Address,\r | |
30f80497 | 1014 | 1,\r |
64d14edf | 1015 | &Data\r |
1016 | );\r | |
1017 | if (EFI_ERROR (Status)) {\r | |
1018 | return Status;\r | |
1019 | }\r | |
1020 | \r | |
1021 | Data = (Data & AndMask) | OrMask;\r | |
1022 | \r | |
1023 | Status = ScriptPciCfgWrite (\r | |
1024 | (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgReadWrite.Width,\r | |
1025 | PciCfgReadWrite.Address,\r | |
30f80497 | 1026 | 1,\r |
64d14edf | 1027 | &Data\r |
1028 | );\r | |
1029 | \r | |
1030 | return Status;\r | |
1031 | }\r | |
1032 | /**\r | |
30f80497 | 1033 | Interprete the boot script node with EFI_BOOT_SCRIPT_SMBUS_EXECUTE OP code.\r |
64d14edf | 1034 | \r |
3a03e95e SZ |
1035 | @param Script The pointer of typed node in boot script table\r |
1036 | \r | |
64d14edf | 1037 | @retval EFI_SUCCESS The operation was executed successfully\r |
1038 | @retval EFI_UNSUPPORTED Cannot locate smbus ppi or occur error of script execution\r | |
3a03e95e | 1039 | @retval Others Result of script execution\r |
64d14edf | 1040 | **/\r |
1041 | EFI_STATUS\r | |
1042 | BootScriptExecuteSmbusExecute (\r | |
1043 | IN UINT8 *Script\r | |
1044 | )\r | |
1045 | {\r | |
1046 | UINTN SmBusAddress;\r | |
1047 | UINTN DataSize;\r | |
1048 | EFI_BOOT_SCRIPT_SMBUS_EXECUTE SmbusExecuteEntry;\r | |
3a03e95e | 1049 | \r |
64d14edf | 1050 | CopyMem ((VOID*)&SmbusExecuteEntry, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_SMBUS_EXECUTE ));\r |
1051 | \r | |
1052 | DEBUG ((EFI_D_INFO, "BootScriptExecuteSmbusExecute - 0x%08x, 0x%08x\n", (UINTN)SmbusExecuteEntry.SmBusAddress, (UINTN)SmbusExecuteEntry.Operation));\r | |
1053 | \r | |
1054 | SmBusAddress = (UINTN)SmbusExecuteEntry.SmBusAddress;\r | |
1055 | DataSize = (UINTN) SmbusExecuteEntry.DataSize;\r | |
1056 | return SmbusExecute (\r | |
1057 | SmBusAddress,\r | |
1058 | (EFI_SMBUS_OPERATION) SmbusExecuteEntry.Operation,\r | |
1059 | &DataSize,\r | |
1060 | Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)\r | |
1061 | );\r | |
1062 | }\r | |
1063 | /**\r | |
30f80497 | 1064 | Interprete the boot script node with EFI_BOOT_SCRIPT_STALL OP code.\r |
64d14edf | 1065 | \r |
3a03e95e SZ |
1066 | @param Script The pointer of typed node in boot script table\r |
1067 | \r | |
64d14edf | 1068 | @retval EFI_SUCCESS The operation was executed successfully\r |
1069 | **/\r | |
1070 | EFI_STATUS\r | |
1071 | BootScriptExecuteStall (\r | |
1072 | IN UINT8 *Script\r | |
1073 | )\r | |
1074 | {\r | |
1075 | EFI_BOOT_SCRIPT_STALL Stall;\r | |
3a03e95e | 1076 | \r |
64d14edf | 1077 | CopyMem ((VOID*)&Stall, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_STALL));\r |
1078 | \r | |
1079 | DEBUG ((EFI_D_INFO, "BootScriptExecuteStall - 0x%08x\n", (UINTN)Stall.Duration));\r | |
1080 | \r | |
1081 | MicroSecondDelay ((UINTN) Stall.Duration);\r | |
1082 | return EFI_SUCCESS;\r | |
1083 | }\r | |
1084 | /**\r | |
30f80497 | 1085 | Interprete the boot script node with EFI_BOOT_SCRIPT_DISPATCH OP code.\r |
3a03e95e SZ |
1086 | \r |
1087 | @param Script The pointer of typed node in boot script table\r | |
30f80497 | 1088 | @retval EFI_SUCCESS The operation was executed successfully\r |
64d14edf | 1089 | **/\r |
1090 | EFI_STATUS\r | |
1091 | BootScriptExecuteDispatch (\r | |
1092 | IN UINT8 *Script\r | |
1093 | )\r | |
1094 | {\r | |
1095 | EFI_STATUS Status;\r | |
1096 | DISPATCH_ENTRYPOINT_FUNC EntryFunc;\r | |
1097 | EFI_BOOT_SCRIPT_DISPATCH ScriptDispatch;\r | |
3a03e95e | 1098 | \r |
64d14edf | 1099 | CopyMem ((VOID*)&ScriptDispatch, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_DISPATCH));\r |
1100 | EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (ScriptDispatch.EntryPoint);\r | |
1101 | \r | |
1102 | DEBUG ((EFI_D_INFO, "BootScriptExecuteDispatch - 0x%08x\n", (UINTN)ScriptDispatch.EntryPoint));\r | |
1103 | \r | |
1104 | Status = EntryFunc (NULL, NULL);\r | |
1105 | \r | |
1106 | return Status;\r | |
1107 | }\r | |
1108 | /**\r | |
30f80497 | 1109 | Interprete the boot script node with EFI_BOOT_SCRIPT_DISPATCH_2 OP code.\r |
64d14edf | 1110 | \r |
3a03e95e | 1111 | @param Script The pointer of typed node in boot script table\r |
64d14edf | 1112 | @retval EFI_SUCCESS The operation was executed successfully\r |
1113 | **/\r | |
1114 | EFI_STATUS\r | |
1115 | BootScriptExecuteDispatch2 (\r | |
1116 | IN UINT8 *Script\r | |
1117 | )\r | |
1118 | {\r | |
1119 | EFI_STATUS Status;\r | |
1120 | DISPATCH_ENTRYPOINT_FUNC EntryFunc;\r | |
1121 | EFI_BOOT_SCRIPT_DISPATCH_2 ScriptDispatch2;\r | |
3a03e95e | 1122 | \r |
64d14edf | 1123 | CopyMem ((VOID*)&ScriptDispatch2, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_DISPATCH_2));\r |
1124 | \r | |
1125 | DEBUG ((EFI_D_INFO, "BootScriptExecuteDispatch2 - 0x%08x(0x%08x)\n", (UINTN)ScriptDispatch2.EntryPoint, (UINTN)ScriptDispatch2.Context));\r | |
3a03e95e | 1126 | \r |
64d14edf | 1127 | EntryFunc = (DISPATCH_ENTRYPOINT_FUNC) (UINTN) (ScriptDispatch2.EntryPoint);\r |
1128 | \r | |
1129 | Status = EntryFunc (NULL, (VOID *) (UINTN) ScriptDispatch2.Context);\r | |
1130 | \r | |
1131 | return Status;\r | |
1132 | }\r | |
1133 | /**\r | |
30f80497 | 1134 | Interprete the boot script node with EFI_BOOT_SCRIPT_MEM_POLL OP code.\r |
64d14edf | 1135 | \r |
3a03e95e | 1136 | @param Script The pointer of typed node in boot script table\r |
64d14edf | 1137 | @param AndMask Mask value for 'and' operation\r |
1138 | @param OrMask Mask value for 'or' operation\r | |
3a03e95e SZ |
1139 | \r |
1140 | @retval EFI_DEVICE_ERROR Data polled from memory does not equal to\r | |
64d14edf | 1141 | the epecting data within the Loop Times.\r |
1142 | @retval EFI_SUCCESS The operation was executed successfully\r | |
1143 | **/\r | |
1144 | EFI_STATUS\r | |
1145 | BootScriptExecuteMemPoll (\r | |
1146 | IN UINT8 *Script,\r | |
1147 | IN UINT64 AndMask,\r | |
3a03e95e | 1148 | IN UINT64 OrMask\r |
64d14edf | 1149 | )\r |
1150 | {\r | |
3a03e95e | 1151 | \r |
64d14edf | 1152 | UINT64 Data;\r |
1153 | UINT64 LoopTimes;\r | |
1154 | EFI_STATUS Status;\r | |
1155 | EFI_BOOT_SCRIPT_MEM_POLL MemPoll;\r | |
3a03e95e | 1156 | \r |
64d14edf | 1157 | CopyMem ((VOID*)&MemPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_MEM_POLL));\r |
1158 | \r | |
30f80497 | 1159 | DEBUG ((EFI_D_INFO, "BootScriptExecuteMemPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemPoll.Address, AndMask, OrMask));\r |
64d14edf | 1160 | \r |
1161 | Data = 0;\r | |
1162 | Status = ScriptMemoryRead (\r | |
1163 | (S3_BOOT_SCRIPT_LIB_WIDTH) MemPoll.Width,\r | |
1164 | MemPoll.Address,\r | |
1165 | 1,\r | |
1166 | &Data\r | |
1167 | );\r | |
1168 | if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r | |
1169 | return EFI_SUCCESS;\r | |
1170 | }\r | |
1171 | \r | |
1172 | for (LoopTimes = 0; LoopTimes < MemPoll.LoopTimes; LoopTimes++) {\r | |
30522140 | 1173 | MicroSecondDelay ((UINTN)MemPoll.Duration);\r |
64d14edf | 1174 | \r |
1175 | Data = 0;\r | |
1176 | Status = ScriptMemoryRead (\r | |
1177 | (S3_BOOT_SCRIPT_LIB_WIDTH) MemPoll.Width,\r | |
1178 | MemPoll.Address,\r | |
1179 | 1,\r | |
1180 | &Data\r | |
1181 | );\r | |
1182 | if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r | |
1183 | return EFI_SUCCESS;\r | |
1184 | }\r | |
1185 | }\r | |
1186 | \r | |
1187 | if (LoopTimes < MemPoll.LoopTimes) {\r | |
1188 | return EFI_SUCCESS;\r | |
1189 | } else {\r | |
1190 | return EFI_DEVICE_ERROR;\r | |
1191 | }\r | |
1192 | }\r | |
1193 | /**\r | |
30f80497 | 1194 | Execute the boot script to interpret the Store arbitrary information.\r |
64d14edf | 1195 | This opcode is a no-op on dispatch and is only used for debugging script issues.\r |
1196 | \r | |
3a03e95e SZ |
1197 | @param Script The pointer of node in boot script table\r |
1198 | \r | |
64d14edf | 1199 | **/\r |
1200 | VOID\r | |
1201 | BootScriptExecuteInformation (\r | |
1202 | IN UINT8 *Script\r | |
1203 | )\r | |
1204 | \r | |
1205 | {\r | |
f6ec0c77 JY |
1206 | UINT32 Index;\r |
1207 | EFI_BOOT_SCRIPT_INFORMATION Information;\r | |
93b21ade | 1208 | UINT8 *InformationData;\r |
f6ec0c77 | 1209 | \r |
93b21ade | 1210 | CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_INFORMATION));\r |
f6ec0c77 | 1211 | \r |
93b21ade SZ |
1212 | InformationData = Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION);\r |
1213 | DEBUG ((EFI_D_INFO, "BootScriptExecuteInformation - 0x%08x\n", (UINTN) InformationData));\r | |
f6ec0c77 JY |
1214 | \r |
1215 | DEBUG ((EFI_D_INFO, "BootScriptInformation: "));\r | |
1216 | for (Index = 0; Index < Information.InformationLength; Index++) {\r | |
93b21ade | 1217 | DEBUG ((EFI_D_INFO, "%02x ", InformationData[Index]));\r |
f6ec0c77 JY |
1218 | }\r |
1219 | DEBUG ((EFI_D_INFO, "\n"));\r | |
64d14edf | 1220 | }\r |
8e4585bb SZ |
1221 | \r |
1222 | /**\r | |
3a03e95e SZ |
1223 | Execute the boot script to interpret the Label information.\r |
1224 | \r | |
1225 | @param Script The pointer of node in boot script table\r | |
8e4585bb | 1226 | \r |
8e4585bb SZ |
1227 | **/\r |
1228 | VOID\r | |
1229 | BootScriptExecuteLabel (\r | |
1230 | IN UINT8 *Script\r | |
1231 | )\r | |
1232 | \r | |
1233 | {\r | |
1234 | UINT32 Index;\r | |
1235 | EFI_BOOT_SCRIPT_INFORMATION Information;\r | |
93b21ade | 1236 | UINT8 *InformationData;\r |
8e4585bb | 1237 | \r |
93b21ade | 1238 | CopyMem ((VOID*)&Information, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_INFORMATION));\r |
8e4585bb | 1239 | \r |
93b21ade SZ |
1240 | InformationData = Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION);\r |
1241 | DEBUG ((EFI_D_INFO, "BootScriptExecuteLabel - 0x%08x\n", (UINTN) InformationData));\r | |
8e4585bb SZ |
1242 | \r |
1243 | DEBUG ((EFI_D_INFO, "BootScriptLabel: "));\r | |
1244 | for (Index = 0; Index < Information.InformationLength; Index++) {\r | |
93b21ade | 1245 | DEBUG ((EFI_D_INFO, "%02x ", InformationData[Index]));\r |
8e4585bb SZ |
1246 | }\r |
1247 | DEBUG ((EFI_D_INFO, "\n"));\r | |
1248 | }\r | |
1249 | \r | |
64d14edf | 1250 | /**\r |
1251 | calculate the mask value for 'and' and 'or' operation\r | |
3a03e95e | 1252 | @param ScriptHeader The pointer of header of node in boot script table\r |
64d14edf | 1253 | @param AndMask The Mask value for 'and' operation\r |
1254 | @param OrMask The Mask value for 'or' operation\r | |
1255 | @param Script Pointer to the entry.\r | |
1256 | \r | |
1257 | **/\r | |
1258 | VOID\r | |
1259 | CheckAndOrMask (\r | |
1260 | IN EFI_BOOT_SCRIPT_COMMON_HEADER *ScriptHeader,\r | |
1261 | OUT UINT64 *AndMask,\r | |
1262 | OUT UINT64 *OrMask,\r | |
1263 | IN UINT8 *Script\r | |
1264 | )\r | |
1265 | {\r | |
1266 | UINT8 *DataPtr;\r | |
1267 | UINTN Size;\r | |
1268 | \r | |
1269 | switch (ScriptHeader->OpCode) {\r | |
1270 | case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r | |
1271 | Size = sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE);\r | |
1272 | break;\r | |
1273 | \r | |
1274 | case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r | |
1275 | Size = sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE);\r | |
1276 | break;\r | |
1277 | \r | |
1278 | case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r | |
1279 | Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE);\r | |
1280 | break;\r | |
1281 | case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r | |
1282 | Size = sizeof (EFI_BOOT_SCRIPT_MEM_POLL);\r | |
1283 | break;\r | |
3a03e95e | 1284 | \r |
64d14edf | 1285 | case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:\r |
1286 | Size = sizeof (EFI_BOOT_SCRIPT_IO_POLL);\r | |
3a03e95e SZ |
1287 | break;\r |
1288 | \r | |
64d14edf | 1289 | case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r |
1290 | Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE);\r | |
1291 | break;\r | |
3a03e95e | 1292 | \r |
64d14edf | 1293 | case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r |
1294 | Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL);\r | |
1295 | break;\r | |
3a03e95e | 1296 | \r |
64d14edf | 1297 | case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:\r |
1298 | Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL);\r | |
1299 | break;\r | |
3a03e95e | 1300 | \r |
64d14edf | 1301 | default:\r |
1302 | return;\r | |
1303 | }\r | |
3a03e95e | 1304 | \r |
64d14edf | 1305 | DataPtr = Script + Size;\r |
1306 | \r | |
1307 | switch (ScriptHeader->Width) {\r | |
1308 | case S3BootScriptWidthUint8:\r | |
6e1e5405 | 1309 | *AndMask = (UINT64) (*(UINT8*) (DataPtr + 1));\r |
64d14edf | 1310 | *OrMask = (UINT64) (*DataPtr);\r |
1311 | break;\r | |
1312 | \r | |
1313 | case S3BootScriptWidthUint16:\r | |
1314 | *AndMask = (UINT64) (*(UINT16 *) (DataPtr + 2));\r | |
1315 | *OrMask = (UINT64) (*(UINT16 *) DataPtr);\r | |
1316 | break;\r | |
1317 | \r | |
1318 | case S3BootScriptWidthUint32:\r | |
1319 | *AndMask = (UINT64) (*(UINT32 *) (DataPtr + 4));\r | |
1320 | *OrMask = (UINT64) (*(UINT32 *) DataPtr);\r | |
1321 | break;\r | |
1322 | \r | |
1323 | case S3BootScriptWidthUint64:\r | |
1324 | *AndMask = (UINT64) (*(UINT64 *) (DataPtr + 8));\r | |
1325 | *OrMask = (UINT64) (*(UINT64 *) DataPtr);\r | |
1326 | break;\r | |
1327 | \r | |
1328 | default:\r | |
1329 | break;\r | |
1330 | }\r | |
1331 | \r | |
1332 | return;\r | |
1333 | }\r | |
1334 | /**\r | |
30f80497 | 1335 | Interprete the boot script node with EFI_BOOT_SCRIPT_IO_POLL OP code.\r |
64d14edf | 1336 | \r |
3a03e95e | 1337 | @param Script The pointer of typed node in boot script table\r |
64d14edf | 1338 | @param AndMask Mask value for 'and' operation\r |
1339 | @param OrMask Mask value for 'or' operation\r | |
3a03e95e SZ |
1340 | \r |
1341 | @retval EFI_DEVICE_ERROR Data polled from memory does not equal to\r | |
64d14edf | 1342 | the epecting data within the Loop Times.\r |
1343 | @retval EFI_SUCCESS The operation was executed successfully\r | |
1344 | **/\r | |
1345 | EFI_STATUS\r | |
1346 | BootScriptExecuteIoPoll (\r | |
1347 | IN UINT8 *Script,\r | |
1348 | IN UINT64 AndMask,\r | |
1349 | IN UINT64 OrMask\r | |
1350 | )\r | |
1351 | {\r | |
1352 | EFI_STATUS Status;\r | |
1353 | UINT64 Data;\r | |
1354 | UINT64 LoopTimes;\r | |
1355 | EFI_BOOT_SCRIPT_IO_POLL IoPoll;\r | |
3a03e95e | 1356 | \r |
64d14edf | 1357 | CopyMem ((VOID*)&IoPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_IO_POLL));\r |
1358 | \r | |
30f80497 | 1359 | DEBUG ((EFI_D_INFO, "BootScriptExecuteIoPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoPoll.Address, AndMask, OrMask));\r |
64d14edf | 1360 | \r |
1361 | Data = 0;\r | |
1362 | Status = ScriptIoRead (\r | |
1363 | (S3_BOOT_SCRIPT_LIB_WIDTH) IoPoll.Width,\r | |
1364 | IoPoll.Address,\r | |
1365 | 1,\r | |
1366 | &Data\r | |
1367 | );\r | |
1368 | if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r | |
1369 | return EFI_SUCCESS;\r | |
1370 | }\r | |
1371 | for (LoopTimes = 0; LoopTimes < IoPoll.Delay; LoopTimes++) {\r | |
1372 | NanoSecondDelay (100);\r | |
1373 | Data = 0;\r | |
1374 | Status = ScriptIoRead (\r | |
1375 | (S3_BOOT_SCRIPT_LIB_WIDTH) IoPoll.Width,\r | |
1376 | IoPoll.Address,\r | |
1377 | 1,\r | |
1378 | &Data\r | |
1379 | );\r | |
1380 | if ((!EFI_ERROR (Status)) &&(Data & AndMask) == OrMask) {\r | |
1381 | return EFI_SUCCESS;\r | |
3a03e95e | 1382 | }\r |
64d14edf | 1383 | }\r |
1384 | \r | |
1385 | if (LoopTimes < IoPoll.Delay) {\r | |
1386 | return EFI_SUCCESS;\r | |
1387 | } else {\r | |
1388 | return EFI_DEVICE_ERROR;\r | |
1389 | }\r | |
1390 | }\r | |
1391 | /**\r | |
30f80497 | 1392 | Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE OP code.\r |
64d14edf | 1393 | \r |
1394 | @param Script The pointer of S3 boot script\r | |
1395 | \r | |
1396 | @retval EFI_SUCCESS The operation was executed successfully\r | |
1397 | \r | |
1398 | **/\r | |
1399 | EFI_STATUS\r | |
1400 | BootScriptExecutePciCfg2Write (\r | |
1401 | IN UINT8 *Script\r | |
1402 | )\r | |
1403 | {\r | |
30f80497 SZ |
1404 | VOID *Buffer;\r |
1405 | S3_BOOT_SCRIPT_LIB_WIDTH Width;\r | |
1406 | UINT16 Segment;\r | |
1407 | UINT64 Address;\r | |
1408 | UINTN Count;\r | |
1409 | EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE PciCfg2Write;\r | |
3a03e95e | 1410 | \r |
64d14edf | 1411 | CopyMem ((VOID*)&PciCfg2Write, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));\r |
64d14edf | 1412 | \r |
30f80497 SZ |
1413 | Width = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2Write.Width;\r |
1414 | Segment = PciCfg2Write.Segment;\r | |
1415 | Address = PciCfg2Write.Address;\r | |
1416 | Count = PciCfg2Write.Count;\r | |
1417 | Buffer = Script + sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE);\r | |
1418 | \r | |
3d20524a | 1419 | DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2Write - 0x%016lx, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (Segment, Address), Count, (UINTN)Width));\r |
30f80497 | 1420 | return ScriptPciCfg2Write (Width, Segment, Address, Count, Buffer);\r |
64d14edf | 1421 | }\r |
1422 | \r | |
1423 | \r | |
1424 | /**\r | |
30f80497 | 1425 | Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE OP code.\r |
3a03e95e | 1426 | \r |
64d14edf | 1427 | @param Script The pointer of S3 boot script\r |
1428 | @param AndMask Mask value for 'and' operation\r | |
1429 | @param OrMask Mask value for 'or' operation\r | |
1430 | \r | |
1431 | @retval EFI_SUCCESS The operation was executed successfully\r | |
1432 | \r | |
1433 | **/\r | |
1434 | EFI_STATUS\r | |
1435 | BootScriptExecutePciCfg2ReadWrite (\r | |
1436 | IN UINT8 *Script,\r | |
1437 | IN UINT64 AndMask,\r | |
1438 | IN UINT64 OrMask\r | |
1439 | )\r | |
1440 | {\r | |
1441 | UINT64 Data;\r | |
1442 | EFI_STATUS Status;\r | |
1443 | EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE PciCfg2ReadWrite;\r | |
0f4e03da SZ |
1444 | \r |
1445 | Data = 0;\r | |
1446 | \r | |
64d14edf | 1447 | CopyMem ((VOID*)&PciCfg2ReadWrite, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE));\r |
1448 | \r | |
3d20524a | 1449 | DEBUG ((EFI_D_INFO, "BootScriptExecutePciCfg2ReadWrite - 0x%016lx, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfg2ReadWrite.Segment, PciCfg2ReadWrite.Address), AndMask, OrMask));\r |
3a03e95e | 1450 | \r |
64d14edf | 1451 | Status = ScriptPciCfg2Read (\r |
1452 | (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2ReadWrite.Width,\r | |
1453 | PciCfg2ReadWrite.Segment,\r | |
1454 | PciCfg2ReadWrite.Address,\r | |
30f80497 | 1455 | 1,\r |
64d14edf | 1456 | &Data\r |
1457 | );\r | |
1458 | if (EFI_ERROR (Status)) {\r | |
1459 | return Status;\r | |
1460 | }\r | |
1461 | \r | |
1462 | Data = (Data & AndMask) | OrMask;\r | |
1463 | Status = ScriptPciCfg2Write (\r | |
1464 | (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2ReadWrite.Width,\r | |
1465 | PciCfg2ReadWrite.Segment,\r | |
1466 | PciCfg2ReadWrite.Address,\r | |
30f80497 | 1467 | 1,\r |
64d14edf | 1468 | &Data\r |
1469 | );\r | |
1470 | return Status;\r | |
1471 | }\r | |
1472 | /**\r | |
30f80497 | 1473 | Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_POLL OP code.\r |
3a03e95e | 1474 | \r |
64d14edf | 1475 | @param Script The pointer of S3 boot script\r |
1476 | @param AndMask Mask value for 'and' operation\r | |
1477 | @param OrMask Mask value for 'or' operation\r | |
1478 | \r | |
1479 | @retval EFI_SUCCESS The operation was executed successfully\r | |
3a03e95e | 1480 | @retval EFI_DEVICE_ERROR Data polled from Pci configuration space does not equal to\r |
64d14edf | 1481 | epecting data within the Loop Times.\r |
1482 | **/\r | |
1483 | EFI_STATUS\r | |
1484 | BootScriptPciCfgPoll (\r | |
1485 | IN UINT8 *Script,\r | |
1486 | IN UINT64 AndMask,\r | |
3a03e95e | 1487 | IN UINT64 OrMask\r |
64d14edf | 1488 | )\r |
1489 | {\r | |
1490 | UINT64 Data;\r | |
1491 | UINT64 LoopTimes;\r | |
1492 | EFI_STATUS Status;\r | |
1493 | EFI_BOOT_SCRIPT_PCI_CONFIG_POLL PciCfgPoll;\r | |
1494 | CopyMem ((VOID*)&PciCfgPoll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG_POLL));\r | |
1495 | \r | |
3d20524a | 1496 | DEBUG ((EFI_D_INFO, "BootScriptPciCfgPoll - 0x%016lx, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (0, PciCfgPoll.Address), AndMask, OrMask));\r |
3a03e95e | 1497 | \r |
64d14edf | 1498 | Data = 0;\r |
1499 | Status = ScriptPciCfgRead (\r | |
1500 | (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgPoll.Width,\r | |
1501 | PciCfgPoll.Address,\r | |
30f80497 | 1502 | 1,\r |
64d14edf | 1503 | &Data\r |
1504 | );\r | |
1505 | if ((!EFI_ERROR (Status)) &&(Data & AndMask) == OrMask) {\r | |
1506 | return EFI_SUCCESS;\r | |
1507 | }\r | |
1508 | \r | |
1509 | for (LoopTimes = 0; LoopTimes < PciCfgPoll.Delay; LoopTimes++) {\r | |
1510 | NanoSecondDelay (100);\r | |
1511 | Data = 0;\r | |
1512 | Status = ScriptPciCfgRead (\r | |
1513 | (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfgPoll.Width,\r | |
1514 | PciCfgPoll.Address,\r | |
30f80497 | 1515 | 1,\r |
64d14edf | 1516 | &Data\r |
1517 | );\r | |
1518 | if ((!EFI_ERROR (Status)) &&\r | |
1519 | (Data & AndMask) == OrMask) {\r | |
1520 | return EFI_SUCCESS;\r | |
1521 | }\r | |
1522 | }\r | |
1523 | \r | |
1524 | if (LoopTimes < PciCfgPoll.Delay) {\r | |
1525 | return EFI_SUCCESS;\r | |
1526 | } else {\r | |
1527 | return EFI_DEVICE_ERROR;\r | |
1528 | }\r | |
1529 | }\r | |
1530 | \r | |
1531 | /**\r | |
30f80497 | 1532 | Interprete the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL OP code.\r |
3a03e95e | 1533 | \r |
64d14edf | 1534 | @param Script The pointer of S3 Boot Script\r |
1535 | @param AndMask Mask value for 'and' operation\r | |
1536 | @param OrMask Mask value for 'or' operation\r | |
1537 | \r | |
1538 | @retval EFI_SUCCESS The operation was executed successfully\r | |
3a03e95e | 1539 | @retval EFI_DEVICE_ERROR Data polled from Pci configuration space does not equal to\r |
64d14edf | 1540 | epecting data within the Loop Times.\r |
1541 | \r | |
1542 | **/\r | |
1543 | EFI_STATUS\r | |
1544 | BootScriptPciCfg2Poll (\r | |
1545 | IN UINT8 *Script,\r | |
1546 | IN UINT64 AndMask,\r | |
3a03e95e | 1547 | IN UINT64 OrMask\r |
64d14edf | 1548 | )\r |
1549 | {\r | |
1550 | EFI_STATUS Status;\r | |
1551 | UINT64 Data;\r | |
1552 | UINT64 LoopTimes;\r | |
1553 | EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL PciCfg2Poll;\r | |
1554 | \r | |
1555 | Data = 0;\r | |
1556 | CopyMem ((VOID*)&PciCfg2Poll, (VOID*)Script, sizeof(EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL));\r | |
1557 | \r | |
3d20524a | 1558 | DEBUG ((EFI_D_INFO, "BootScriptPciCfg2Poll - 0x%016lx, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfg2Poll.Segment, PciCfg2Poll.Address), AndMask, OrMask));\r |
3a03e95e | 1559 | \r |
64d14edf | 1560 | Status = ScriptPciCfg2Read (\r |
1561 | (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Poll.Width,\r | |
1562 | PciCfg2Poll.Segment,\r | |
1563 | PciCfg2Poll.Address,\r | |
30f80497 | 1564 | 1,\r |
64d14edf | 1565 | &Data\r |
1566 | );\r | |
1567 | if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r | |
1568 | return EFI_SUCCESS;\r | |
1569 | }\r | |
1570 | \r | |
1571 | for (LoopTimes = 0; LoopTimes < PciCfg2Poll.Delay; LoopTimes++) {\r | |
1572 | NanoSecondDelay (100);\r | |
1573 | \r | |
1574 | Data = 0;\r | |
1575 | Status = ScriptPciCfg2Read (\r | |
1576 | (S3_BOOT_SCRIPT_LIB_WIDTH) PciCfg2Poll.Width,\r | |
3a03e95e | 1577 | PciCfg2Poll.Segment,\r |
64d14edf | 1578 | PciCfg2Poll.Address,\r |
30f80497 | 1579 | 1,\r |
64d14edf | 1580 | &Data\r |
1581 | );\r | |
1582 | if ((!EFI_ERROR (Status)) && (Data & AndMask) == OrMask) {\r | |
1583 | return EFI_SUCCESS;\r | |
1584 | }\r | |
1585 | }\r | |
1586 | \r | |
1587 | if (LoopTimes < PciCfg2Poll.Delay) {\r | |
1588 | return EFI_SUCCESS;\r | |
1589 | } else {\r | |
1590 | return EFI_DEVICE_ERROR;\r | |
1591 | }\r | |
3a03e95e | 1592 | \r |
64d14edf | 1593 | }\r |
1594 | \r | |
1595 | /**\r | |
1596 | Executes the S3 boot script table.\r | |
3a03e95e | 1597 | \r |
64d14edf | 1598 | @retval RETURN_SUCCESS The boot script table was executed successfully.\r |
3a03e95e SZ |
1599 | @retval RETURN_UNSUPPORTED Invalid script table or opcode.\r |
1600 | \r | |
64d14edf | 1601 | **/\r |
1602 | RETURN_STATUS\r | |
1603 | EFIAPI\r | |
1604 | S3BootScriptExecute (\r | |
1605 | VOID\r | |
1606 | )\r | |
1607 | {\r | |
1608 | EFI_STATUS Status;\r | |
1609 | UINT8* Script;\r | |
1610 | UINTN StartAddress;\r | |
1611 | UINT32 TableLength;\r | |
1612 | UINT64 AndMask;\r | |
1613 | UINT64 OrMask;\r | |
1614 | EFI_BOOT_SCRIPT_COMMON_HEADER ScriptHeader;\r | |
1615 | EFI_BOOT_SCRIPT_TABLE_HEADER TableHeader;\r | |
1616 | Script = mS3BootScriptTablePtr->TableBase;\r | |
3a03e95e | 1617 | if (Script != 0) {\r |
64d14edf | 1618 | CopyMem ((VOID*)&TableHeader, Script, sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER));\r |
1619 | } else {\r | |
1620 | return EFI_INVALID_PARAMETER;\r | |
1621 | }\r | |
1622 | \r | |
1623 | DEBUG ((EFI_D_INFO, "S3BootScriptExecute:\n"));\r | |
1624 | if (TableHeader.OpCode != S3_BOOT_SCRIPT_LIB_TABLE_OPCODE) {\r | |
1625 | return EFI_UNSUPPORTED;\r | |
1626 | }\r | |
1627 | \r | |
1628 | DEBUG ((EFI_D_INFO, "TableHeader - 0x%08x\n", Script));\r | |
3a03e95e | 1629 | \r |
64d14edf | 1630 | StartAddress = (UINTN) Script;\r |
1631 | TableLength = TableHeader.TableLength;\r | |
1632 | Script = Script + TableHeader.Length;\r | |
1633 | Status = EFI_SUCCESS;\r | |
1634 | AndMask = 0;\r | |
1635 | OrMask = 0;\r | |
1636 | \r | |
0a4a5b7b | 1637 | DEBUG ((EFI_D_INFO, "TableHeader.Version - 0x%04x\n", (UINTN)TableHeader.Version));\r |
64d14edf | 1638 | DEBUG ((EFI_D_INFO, "TableHeader.TableLength - 0x%08x\n", (UINTN)TableLength));\r |
1639 | \r | |
1640 | while ((UINTN) Script < (UINTN) (StartAddress + TableLength)) {\r | |
1641 | DEBUG ((EFI_D_INFO, "ExecuteBootScript - %08x\n", (UINTN)Script));\r | |
3a03e95e | 1642 | \r |
64d14edf | 1643 | CopyMem ((VOID*)&ScriptHeader, Script, sizeof(EFI_BOOT_SCRIPT_COMMON_HEADER));\r |
1644 | switch (ScriptHeader.OpCode) {\r | |
1645 | \r | |
1646 | case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:\r | |
1647 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE\n"));\r | |
1648 | Status = BootScriptExecuteMemoryWrite (Script);\r | |
1649 | break;\r | |
1650 | \r | |
1651 | case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r | |
1652 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE\n"));\r | |
1653 | CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r | |
1654 | Status = BootScriptExecuteMemoryReadWrite (\r | |
1655 | Script,\r | |
1656 | AndMask,\r | |
1657 | OrMask\r | |
1658 | );\r | |
1659 | break;\r | |
1660 | \r | |
1661 | case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:\r | |
1662 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_WRITE_OPCODE\n"));\r | |
1663 | Status = BootScriptExecuteIoWrite (Script);\r | |
1664 | break;\r | |
1665 | \r | |
1666 | case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:\r | |
1667 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE\n"));\r | |
1668 | Status = BootScriptExecutePciCfgWrite (Script);\r | |
1669 | break;\r | |
1670 | \r | |
1671 | case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r | |
1672 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE\n"));\r | |
1673 | CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r | |
1674 | Status = BootScriptExecutePciCfgReadWrite (\r | |
1675 | Script,\r | |
1676 | AndMask,\r | |
1677 | OrMask\r | |
1678 | );\r | |
1679 | break;\r | |
1680 | case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:\r | |
1681 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\n"));\r | |
1682 | Status = BootScriptExecutePciCfg2Write (Script);\r | |
1683 | break;\r | |
1684 | \r | |
1685 | case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r | |
1686 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE\n"));\r | |
1687 | CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r | |
1688 | Status = BootScriptExecutePciCfg2ReadWrite (\r | |
1689 | Script,\r | |
1690 | AndMask,\r | |
1691 | OrMask\r | |
1692 | );\r | |
1693 | break;\r | |
1694 | case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:\r | |
1695 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_DISPATCH_OPCODE\n"));\r | |
1696 | Status = BootScriptExecuteDispatch (Script);\r | |
1697 | break;\r | |
1698 | \r | |
1699 | case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:\r | |
1700 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE\n"));\r | |
1701 | Status = BootScriptExecuteDispatch2 (Script);\r | |
1702 | break;\r | |
1703 | \r | |
1704 | case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r | |
1705 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_INFORMATION_OPCODE\n"));\r | |
1706 | BootScriptExecuteInformation (Script);\r | |
3a03e95e | 1707 | break;\r |
64d14edf | 1708 | \r |
1709 | case S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE:\r | |
1710 | DEBUG ((EFI_D_INFO, "S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE\n"));\r | |
8e4585bb | 1711 | DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", EFI_SUCCESS));\r |
64d14edf | 1712 | return EFI_SUCCESS;\r |
1713 | \r | |
1714 | case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r | |
1715 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE\n"));\r | |
1716 | CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r | |
1717 | Status = BootScriptExecuteIoReadWrite (\r | |
1718 | Script,\r | |
1719 | AndMask,\r | |
1720 | OrMask\r | |
1721 | );\r | |
1722 | break;\r | |
1723 | \r | |
1724 | case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:\r | |
1725 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE\n"));\r | |
1726 | Status = BootScriptExecuteSmbusExecute (Script);\r | |
1727 | break;\r | |
1728 | \r | |
1729 | case EFI_BOOT_SCRIPT_STALL_OPCODE:\r | |
1730 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_STALL_OPCODE\n"));\r | |
1731 | Status = BootScriptExecuteStall (Script);\r | |
1732 | break;\r | |
1733 | \r | |
1734 | case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r | |
1735 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_POLL_OPCODE\n"));\r | |
1736 | CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r | |
1737 | Status = BootScriptExecuteMemPoll (Script, AndMask, OrMask);\r | |
3a03e95e | 1738 | \r |
64d14edf | 1739 | break;\r |
3a03e95e | 1740 | \r |
64d14edf | 1741 | case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:\r |
1742 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_POLL_OPCODE\n"));\r | |
1743 | CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r | |
1744 | Status = BootScriptExecuteIoPoll (Script, AndMask, OrMask);\r | |
1745 | break;\r | |
3a03e95e | 1746 | \r |
64d14edf | 1747 | case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:\r |
1748 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE\n"));\r | |
1749 | CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r | |
1750 | Status = BootScriptPciCfgPoll (Script, AndMask, OrMask);\r | |
1751 | break;\r | |
3a03e95e | 1752 | \r |
64d14edf | 1753 | case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r |
1754 | DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE\n"));\r | |
1755 | CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);\r | |
1756 | Status = BootScriptPciCfg2Poll (Script, AndMask, OrMask);\r | |
1757 | break;\r | |
1758 | \r | |
1759 | case S3_BOOT_SCRIPT_LIB_LABEL_OPCODE:\r | |
1760 | //\r | |
1761 | // For label\r | |
1762 | //\r | |
1763 | DEBUG ((EFI_D_INFO, "S3_BOOT_SCRIPT_LIB_LABEL_OPCODE\n"));\r | |
8e4585bb | 1764 | BootScriptExecuteLabel (Script);\r |
64d14edf | 1765 | break;\r |
1766 | default:\r | |
1767 | DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", EFI_UNSUPPORTED));\r | |
1768 | return EFI_UNSUPPORTED;\r | |
1769 | }\r | |
1770 | \r | |
1771 | if (EFI_ERROR (Status)) {\r | |
1772 | DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", Status));\r | |
1773 | return Status;\r | |
1774 | }\r | |
1775 | \r | |
1776 | Script = Script + ScriptHeader.Length;\r | |
1777 | }\r | |
1778 | \r | |
1779 | DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", Status));\r | |
1780 | \r | |
1781 | return Status;\r | |
1782 | }\r | |
1783 | \r |