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