VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/PiDxeS3BootScriptLib/BootScriptExecute.c

Last change on this file was 99404, checked in by vboxsync, 2 years ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette