]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/BootScriptSaveDxe/ScriptSave.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / BootScriptSaveDxe / ScriptSave.c
1 /** @file
2 Implementation for S3 Boot Script Saver driver.
3
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License that accompanies this distribution.
8 The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14
15 **/
16
17 #include "InternalBootScriptSave.h"
18
19 EFI_HANDLE mHandle = NULL;
20 EFI_BOOT_SCRIPT_SAVE_PROTOCOL mS3ScriptSave = {
21 BootScriptWrite,
22 BootScriptCloseTable
23 };
24
25 /**
26 Internal function to add IO write opcode to the table.
27
28 @param Marker The variable argument list to get the opcode
29 and associated attributes.
30
31 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
32 @retval EFI_SUCCESS Opcode is added.
33
34 **/
35 EFI_STATUS
36 BootScriptIoWrite (
37 IN VA_LIST Marker
38 )
39 {
40 S3_BOOT_SCRIPT_LIB_WIDTH Width;
41 UINT64 Address;
42 UINTN Count;
43 UINT8 *Buffer;
44
45 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
46 Address = VA_ARG (Marker, UINT64);
47 Count = VA_ARG (Marker, UINTN);
48 Buffer = VA_ARG (Marker, UINT8 *);
49
50 return S3BootScriptSaveIoWrite (Width, Address, Count, Buffer);
51 }
52
53 /**
54 Internal function to add IO read/write opcode to the table.
55
56 @param Marker The variable argument list to get the opcode
57 and associated attributes.
58
59 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
60 @retval EFI_SUCCESS Opcode is added.
61
62 **/
63 EFI_STATUS
64 BootScriptIoReadWrite (
65 IN VA_LIST Marker
66 )
67 {
68 S3_BOOT_SCRIPT_LIB_WIDTH Width;
69 UINT64 Address;
70 UINT8 *Data;
71 UINT8 *DataMask;
72
73 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
74 Address = VA_ARG (Marker, UINT64);
75 Data = VA_ARG (Marker, UINT8 *);
76 DataMask = VA_ARG (Marker, UINT8 *);
77
78 return S3BootScriptSaveIoReadWrite (Width, Address, Data, DataMask);
79 }
80
81 /**
82 Internal function to add memory write opcode to the table.
83
84 @param Marker The variable argument list to get the opcode
85 and associated attributes.
86
87 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
88 @retval EFI_SUCCESS Opcode is added.
89
90 **/
91 EFI_STATUS
92 BootScriptMemWrite (
93 IN VA_LIST Marker
94 )
95 {
96 S3_BOOT_SCRIPT_LIB_WIDTH Width;
97 UINT64 Address;
98 UINTN Count;
99 UINT8 *Buffer;
100
101 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
102 Address = VA_ARG (Marker, UINT64);
103 Count = VA_ARG (Marker, UINTN);
104 Buffer = VA_ARG (Marker, UINT8 *);
105
106 return S3BootScriptSaveMemWrite (Width, Address, Count, Buffer);
107 }
108
109 /**
110 Internal function to add memory read/write opcode to the table.
111
112 @param Marker The variable argument list to get the opcode
113 and associated attributes.
114
115 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
116 @retval EFI_SUCCESS Opcode is added.
117
118 **/
119 EFI_STATUS
120 BootScriptMemReadWrite (
121 IN VA_LIST Marker
122 )
123 {
124 S3_BOOT_SCRIPT_LIB_WIDTH Width;
125 UINT64 Address;
126 UINT8 *Data;
127 UINT8 *DataMask;
128
129 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
130 Address = VA_ARG (Marker, UINT64);
131 Data = VA_ARG (Marker, UINT8 *);
132 DataMask = VA_ARG (Marker, UINT8 *);
133
134 return S3BootScriptSaveMemReadWrite (Width, Address, Data, DataMask);
135 }
136
137 /**
138 Internal function to add PciCfg write opcode to the table.
139
140 @param Marker The variable argument list to get the opcode
141 and associated attributes.
142
143 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
144 @retval EFI_SUCCESS Opcode is added.
145
146 **/
147 EFI_STATUS
148 BootScriptPciCfgWrite (
149 IN VA_LIST Marker
150 )
151 {
152 S3_BOOT_SCRIPT_LIB_WIDTH Width;
153 UINT64 Address;
154 UINTN Count;
155 UINT8 *Buffer;
156
157 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
158 Address = VA_ARG (Marker, UINT64);
159 Count = VA_ARG (Marker, UINTN);
160 Buffer = VA_ARG (Marker, UINT8 *);
161
162 return S3BootScriptSavePciCfgWrite (Width, Address, Count, Buffer);
163 }
164
165 /**
166 Internal function to PciCfg read/write opcode to the table.
167
168 @param Marker The variable argument list to get the opcode
169 and associated attributes.
170
171 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
172 @retval EFI_SUCCESS Opcode is added.
173
174 **/
175 EFI_STATUS
176 BootScriptPciCfgReadWrite (
177 IN VA_LIST Marker
178 )
179 {
180 S3_BOOT_SCRIPT_LIB_WIDTH Width;
181 UINT64 Address;
182 UINT8 *Data;
183 UINT8 *DataMask;
184
185 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
186 Address = VA_ARG (Marker, UINT64);
187 Data = VA_ARG (Marker, UINT8 *);
188 DataMask = VA_ARG (Marker, UINT8 *);
189
190 return S3BootScriptSavePciCfgReadWrite (Width, Address, Data, DataMask);
191 }
192
193 /**
194 Internal function to add PciCfg2 write opcode to the table.
195
196 @param Marker The variable argument list to get the opcode
197 and associated attributes.
198
199 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
200 @retval EFI_SUCCESS Opcode is added.
201
202 **/
203 EFI_STATUS
204 BootScriptPciCfg2Write (
205 IN VA_LIST Marker
206 )
207 {
208 S3_BOOT_SCRIPT_LIB_WIDTH Width;
209 UINT64 Address;
210 UINTN Count;
211 UINT8 *Buffer;
212 UINT16 Segment;
213
214 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
215 Address = VA_ARG (Marker, UINT64);
216 Count = VA_ARG (Marker, UINTN);
217 Buffer = VA_ARG (Marker, UINT8 *);
218 Segment = VA_ARG (Marker, UINT16);
219
220 return S3BootScriptSavePciCfg2Write (Width, Segment, Address, Count, Buffer);
221 }
222
223 /**
224 Internal function to PciCfg2 read/write opcode to the table.
225
226 @param Marker The variable argument list to get the opcode
227 and associated attributes.
228
229 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
230 @retval EFI_SUCCESS Opcode is added.
231
232 **/
233 EFI_STATUS
234 BootScriptPciCfg2ReadWrite (
235 IN VA_LIST Marker
236 )
237 {
238 S3_BOOT_SCRIPT_LIB_WIDTH Width;
239 UINT16 Segment;
240 UINT64 Address;
241 UINT8 *Data;
242 UINT8 *DataMask;
243
244 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
245 Address = VA_ARG (Marker, UINT64);
246 Segment = VA_ARG (Marker, UINT16);
247 Data = VA_ARG (Marker, UINT8 *);
248 DataMask = VA_ARG (Marker, UINT8 *);
249
250 return S3BootScriptSavePciCfg2ReadWrite (Width, Segment, Address, Data, DataMask);
251 }
252
253 /**
254 Internal function to add smbus excute opcode to the table.
255
256 @param Marker The variable argument list to get the opcode
257 and associated attributes.
258
259 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
260 @retval EFI_SUCCESS Opcode is added.
261
262 **/
263 EFI_STATUS
264 BootScriptSmbusExecute (
265 IN VA_LIST Marker
266 )
267 {
268 EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
269 EFI_SMBUS_DEVICE_COMMAND Command;
270 EFI_SMBUS_OPERATION Operation;
271 BOOLEAN PecCheck;
272 VOID *Buffer;
273 UINTN *DataSize;
274 UINTN SmBusAddress;
275
276 SlaveAddress.SmbusDeviceAddress = VA_ARG (Marker, UINTN);
277 Command = VA_ARG (Marker, EFI_SMBUS_DEVICE_COMMAND);
278 Operation = VA_ARG (Marker, EFI_SMBUS_OPERATION);
279 PecCheck = VA_ARG (Marker, BOOLEAN);
280 SmBusAddress = SMBUS_LIB_ADDRESS (SlaveAddress.SmbusDeviceAddress,Command,0,PecCheck);
281 DataSize = VA_ARG (Marker, UINTN *);
282 Buffer = VA_ARG (Marker, VOID *);
283
284 return S3BootScriptSaveSmbusExecute (SmBusAddress, Operation, DataSize, Buffer);
285 }
286
287 /**
288 Internal function to add stall opcode to the table.
289
290 @param Marker The variable argument list to get the opcode
291 and associated attributes.
292
293 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
294 @retval EFI_SUCCESS Opcode is added.
295
296 **/
297 EFI_STATUS
298 BootScriptStall (
299 IN VA_LIST Marker
300 )
301 {
302 UINT32 Duration;
303
304 Duration = VA_ARG (Marker, UINT32);
305
306 return S3BootScriptSaveStall (Duration);
307 }
308
309 /**
310 Internal function to add Save jmp address according to DISPATCH_OPCODE.
311 We ignore "Context" parameter.
312
313 @param Marker The variable argument list to get the opcode
314 and associated attributes.
315
316 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
317 @retval EFI_SUCCESS Opcode is added.
318
319 **/
320 EFI_STATUS
321 BootScriptDispatch (
322 IN VA_LIST Marker
323 )
324 {
325 VOID *EntryPoint;
326
327 EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
328 return S3BootScriptSaveDispatch (EntryPoint);
329 }
330
331 /**
332 Internal function to add memory pool operation to the table.
333
334 @param Marker The variable argument list to get the opcode
335 and associated attributes.
336
337 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
338 @retval EFI_SUCCESS Opcode is added.
339
340 **/
341 EFI_STATUS
342 BootScriptMemPoll (
343 IN VA_LIST Marker
344 )
345 {
346 S3_BOOT_SCRIPT_LIB_WIDTH Width;
347 UINT64 Address;
348 UINT8 *BitMask;
349 UINT8 *BitValue;
350 UINTN Duration;
351 UINTN LoopTimes;
352
353 Width = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);
354 Address = VA_ARG (Marker, UINT64);
355 BitMask = VA_ARG (Marker, UINT8 *);
356 BitValue = VA_ARG (Marker, UINT8 *);
357 Duration = (UINTN)VA_ARG (Marker, UINT64);
358 LoopTimes = (UINTN)VA_ARG (Marker, UINT64);
359
360 return S3BootScriptSaveMemPoll (Width, Address, BitMask, BitValue, Duration, LoopTimes);
361 }
362
363 /**
364 Internal function to add Save jmp address according to DISPATCH_OPCODE2.
365 The "Context" parameter is not ignored.
366
367 @param Marker The variable argument list to get the opcode
368 and associated attributes.
369
370 @retval EFI_OUT_OF_RESOURCES Not enough resource to do operation.
371 @retval EFI_SUCCESS Opcode is added.
372
373 **/
374 EFI_STATUS
375 BootScriptDispatch2 (
376 IN VA_LIST Marker
377 )
378 {
379 VOID *EntryPoint;
380 VOID *Context;
381
382 EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
383 Context = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
384
385 return S3BootScriptSaveDispatch2 (EntryPoint, Context);
386 }
387
388 /**
389 Internal function to add the opcode link node to the link list.
390
391 @param Marker The variable argument list to get the opcode
392 and associated attributes.
393
394 @retval EFI_OUT_OF_RESOURCES Not enought resource to complete the operations.
395 @retval EFI_SUCCESS The opcode entry is added to the link list
396 successfully.
397 **/
398 EFI_STATUS
399 BootScriptInformation (
400 IN VA_LIST Marker
401 )
402 {
403 UINT32 InformationLength;
404 EFI_PHYSICAL_ADDRESS Information;
405
406 InformationLength = VA_ARG (Marker, UINT32);
407 Information = VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
408 return S3BootScriptSaveInformation (InformationLength, (VOID*)(UINTN)Information);
409 }
410
411 /**
412 Adds a record into a specified Framework boot script table.
413
414 This function is used to store a boot script record into a given boot
415 script table. If the table specified by TableName is nonexistent in the
416 system, a new table will automatically be created and then the script record
417 will be added into the new table. A boot script table can add new script records
418 until EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable() is called. Currently, the only
419 meaningful table name is EFI_ACPI_S3_RESUME_SCRIPT_TABLE. This function is
420 responsible for allocating necessary memory for the script.
421
422 This function has a variable parameter list. The exact parameter list depends on
423 the OpCode that is passed into the function. If an unsupported OpCode or illegal
424 parameter list is passed in, this function returns EFI_INVALID_PARAMETER.
425 If there are not enough resources available for storing more scripts, this function returns
426 EFI_OUT_OF_RESOURCES.
427
428 @param This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
429 @param TableName Name of the script table. Currently, the only meaningful value is
430 EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
431 @param OpCode The operation code (opcode) number.
432 @param ... Argument list that is specific to each opcode.
433
434 @retval EFI_SUCCESS The operation succeeded. A record was added into the
435 specified script table.
436 @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.
437 If the opcode is unknow or not supported because of the PCD
438 Feature Flags.
439 @retval EFI_OUT_OF_RESOURCES There is insufficient memory to store the boot script.
440
441 **/
442 EFI_STATUS
443 EFIAPI
444 BootScriptWrite (
445 IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
446 IN UINT16 TableName,
447 IN UINT16 OpCode,
448 ...
449 )
450 {
451 EFI_STATUS Status;
452 VA_LIST Marker;
453
454 if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {
455 //
456 // Only S3 boot script is supported for now.
457 //
458 return EFI_OUT_OF_RESOURCES;
459 }
460
461 //
462 // Build script according to opcode.
463 //
464 switch (OpCode) {
465
466 case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
467 VA_START (Marker, OpCode);
468 Status = BootScriptIoWrite (Marker);
469 VA_END (Marker);
470 break;
471
472 case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
473 VA_START (Marker, OpCode);
474 Status = BootScriptIoReadWrite (Marker);
475 VA_END (Marker);
476 break;
477
478 case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
479 VA_START (Marker, OpCode);
480 Status = BootScriptMemWrite (Marker);
481 VA_END (Marker);
482 break;
483
484 case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
485 VA_START (Marker, OpCode);
486 Status = BootScriptMemReadWrite (Marker);
487 VA_END (Marker);
488 break;
489
490 case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
491 VA_START (Marker, OpCode);
492 Status = BootScriptPciCfgWrite (Marker);
493 VA_END (Marker);
494 break;
495
496 case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
497 VA_START (Marker, OpCode);
498 Status = BootScriptPciCfgReadWrite (Marker);
499 VA_END (Marker);
500 break;
501
502 case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:
503 VA_START (Marker, OpCode);
504 Status = BootScriptSmbusExecute (Marker);
505 VA_END (Marker);
506 break;
507
508 case EFI_BOOT_SCRIPT_STALL_OPCODE:
509 VA_START (Marker, OpCode);
510 Status = BootScriptStall (Marker);
511 VA_END (Marker);
512
513 break;
514
515 case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
516 VA_START (Marker, OpCode);
517 Status = BootScriptDispatch (Marker);
518 VA_END (Marker);
519 break;
520
521 case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
522 VA_START (Marker, OpCode);
523 Status = BootScriptDispatch2 (Marker);
524 VA_END (Marker);
525 break;
526
527 case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
528 VA_START (Marker, OpCode);
529 Status = BootScriptInformation (Marker);
530 VA_END (Marker);
531 break;
532
533 case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
534 VA_START (Marker, OpCode);
535 Status = BootScriptMemPoll (Marker);
536 VA_END (Marker);
537 break;
538
539 case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:
540 VA_START (Marker, OpCode);
541 Status = BootScriptPciCfg2Write (Marker);
542 VA_END (Marker);
543 break;
544
545 case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
546 VA_START (Marker, OpCode);
547 Status = BootScriptPciCfg2ReadWrite (Marker);
548 VA_END (Marker);
549 break;
550
551 default:
552 Status = EFI_INVALID_PARAMETER;
553 break;
554 }
555
556 return Status;
557 }
558
559 /**
560 Closes the specified script table.
561
562 This function closes the specified boot script table and returns the base address
563 of the table. It allocates a new pool to duplicate all the boot scripts in the specified
564 table. Once this function is called, the specified table will be destroyed after it is
565 copied into the allocated pool. As a result, any attempts to add a script record into a
566 closed table will cause a new table to be created. The base address of the allocated pool
567 will be returned in Address. After using the boot script table, the caller is responsible
568 for freeing the pool that is allocated by this function. If the boot script table,
569 such as EFI_ACPI_S3_RESUME_SCRIPT_TABLE, is required to be stored in a nonperturbed
570 memory region, the caller should copy the table into the nonperturbed memory region by itself.
571
572 @param This A pointer to the EFI_BOOT_SCRIPT_SAVE_PROTOCOL instance.
573 @param TableName Name of the script table. Currently, the only meaningful value is
574 EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
575 @param Address A pointer to the physical address where the table begins.
576
577 @retval EFI_SUCCESS The table was successfully returned.
578 @retval EFI_NOT_FOUND The specified table was not created previously.
579 @retval EFI_OUT_OF_RESOURCE Memory is insufficient to hold the reorganized boot script table.
580 @retval EFI_UNSUPPORTED The table type is not EFI_ACPI_S3_RESUME_SCRIPT_TABLE.
581
582 **/
583 EFI_STATUS
584 EFIAPI
585 BootScriptCloseTable (
586 IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
587 IN UINT16 TableName,
588 OUT EFI_PHYSICAL_ADDRESS *Address
589 )
590 {
591 if (TableName != FRAMEWORK_EFI_ACPI_S3_RESUME_SCRIPT_TABLE) {
592 //
593 // Only S3 boot script is supported for now.
594 //
595 return EFI_NOT_FOUND;
596 }
597 *Address = (EFI_PHYSICAL_ADDRESS)(UINTN)S3BootScriptCloseTable ();
598
599 if (*Address == 0) {
600 return EFI_NOT_FOUND;
601 }
602 return EFI_SUCCESS;
603 }
604
605 /**
606 This routine is entry point of ScriptSave driver.
607
608 @param ImageHandle Handle for this drivers loaded image protocol.
609 @param SystemTable EFI system table.
610
611 @retval EFI_OUT_OF_RESOURCES No enough resource.
612 @retval EFI_SUCCESS Succesfully installed the ScriptSave driver.
613 @retval other Errors occured.
614
615 **/
616 EFI_STATUS
617 EFIAPI
618 InitializeScriptSave (
619 IN EFI_HANDLE ImageHandle,
620 IN EFI_SYSTEM_TABLE *SystemTable
621 )
622 {
623 return gBS->InstallProtocolInterface (
624 &mHandle,
625 &gEfiBootScriptSaveProtocolGuid,
626 EFI_NATIVE_INTERFACE,
627 &mS3ScriptSave
628 );
629
630 }
631