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