Home | History | Annotate | Download | only in SmmScriptLib
      1 /** @file
      2   Thunk implmentation for SmmScriptLib.
      3 
      4   SmmScriptLib in Framework implementation is to save S3 Boot Script in SMM runtime.
      5   The thunk implementation for SmmScriptLib will ultilize the SmmSaveState Protocol to save SMM
      6   runtime s3 boot Script.
      7 
      8   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
      9 
     10   This program and the accompanying materials
     11   are licensed and made available under the terms and conditions
     12   of the BSD License which accompanies this distribution.  The
     13   full text of the license may be found at
     14   http://opensource.org/licenses/bsd-license.php
     15 
     16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     17   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     18 
     19 **/
     20 #include "SmmScriptLib.h"
     21 
     22 //
     23 // Define the SmmS3SaveState Protocol GUID.
     24 //
     25 EFI_GUID mEfiS3SmmSaveStateProtocolGuid = EFI_S3_SMM_SAVE_STATE_PROTOCOL_GUID;
     26 EFI_GUID mEfiSmmBase2ProtocolGuid = EFI_SMM_BASE2_PROTOCOL_GUID;
     27 EFI_S3_SMM_SAVE_STATE_PROTOCOL  *mS3SmmSaveState = NULL;
     28 EFI_SMM_SYSTEM_TABLE2           *gSmst              = NULL;
     29 
     30 /**
     31   Internal function to add IO write opcode to the table.
     32 
     33   @param  Marker                The variable argument list to get the opcode
     34                                 and associated attributes.
     35 
     36   @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
     37   @retval EFI_SUCCESS           Opcode is added.
     38 
     39 **/
     40 EFI_STATUS
     41 BootScriptIoWrite (
     42   IN VA_LIST                  Marker
     43   )
     44 {
     45   EFI_BOOT_SCRIPT_WIDTH Width;
     46   UINT64                Address;
     47   UINTN                 Count;
     48   UINT8                 *Buffer;
     49 
     50   Width       = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
     51   Address     = VA_ARG (Marker, UINT64);
     52   Count       = VA_ARG (Marker, UINTN);
     53   Buffer      = VA_ARG (Marker, UINT8 *);
     54 
     55   return mS3SmmSaveState->Write (
     56                         mS3SmmSaveState,
     57                         EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,
     58                         Width,
     59                         Address,
     60                         Count,
     61                         Buffer
     62                         );
     63 }
     64 /**
     65   Internal function to add IO read/write opcode to the table.
     66 
     67   @param  Marker                The variable argument list to get the opcode
     68                                 and associated attributes.
     69 
     70   @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
     71   @retval EFI_SUCCESS           Opcode is added.
     72 
     73 **/
     74 EFI_STATUS
     75 BootScriptIoReadWrite (
     76   IN VA_LIST                       Marker
     77   )
     78 {
     79   EFI_BOOT_SCRIPT_WIDTH Width;
     80   UINT64                Address;
     81   UINT8                 *Data;
     82   UINT8                 *DataMask;
     83 
     84   Width       = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
     85   Address     = VA_ARG (Marker, UINT64);
     86   Data        = VA_ARG (Marker, UINT8 *);
     87   DataMask    = VA_ARG (Marker, UINT8 *);
     88 
     89   return mS3SmmSaveState->Write (
     90                          mS3SmmSaveState,
     91                          EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE,
     92                          Width,
     93                          Address,
     94                          Data,
     95                          DataMask
     96                          );
     97 }
     98 /**
     99   Internal function to add memory read/write opcode to the table.
    100 
    101   @param  Marker                The variable argument list to get the opcode
    102                                 and associated attributes.
    103 
    104   @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
    105   @retval EFI_SUCCESS           Opcode is added.
    106 
    107 **/
    108 EFI_STATUS
    109 BootScriptMemReadWrite (
    110   IN VA_LIST                       Marker
    111   )
    112 {
    113   EFI_BOOT_SCRIPT_WIDTH Width;
    114   UINT64                Address;
    115   UINT8                 *Data;
    116   UINT8                 *DataMask;
    117 
    118   Width       = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
    119   Address     = VA_ARG (Marker, UINT64);
    120   Data        = VA_ARG (Marker, UINT8 *);
    121   DataMask    = VA_ARG (Marker, UINT8 *);
    122 
    123   return mS3SmmSaveState->Write (
    124                         mS3SmmSaveState,
    125                         EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE,
    126                         Width,
    127                         Address,
    128                         Data,
    129                         DataMask
    130                         );
    131 }
    132 /**
    133   Internal function to PciCfg read/write opcode to the table.
    134 
    135   @param  Marker                The variable argument list to get the opcode
    136                                 and associated attributes.
    137 
    138   @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
    139   @retval EFI_SUCCESS           Opcode is added.
    140 
    141 **/
    142 EFI_STATUS
    143 BootScriptPciCfgReadWrite (
    144   IN VA_LIST                       Marker
    145   )
    146 {
    147   EFI_BOOT_SCRIPT_WIDTH Width;
    148   UINT64                Address;
    149   UINT8                 *Data;
    150   UINT8                 *DataMask;
    151 
    152   Width       = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
    153   Address     = VA_ARG (Marker, UINT64);
    154   Data        = VA_ARG (Marker, UINT8 *);
    155   DataMask    = VA_ARG (Marker, UINT8 *);
    156 
    157   return mS3SmmSaveState->Write (
    158                           mS3SmmSaveState,
    159                           EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE,
    160                           Width,
    161                           Address,
    162                           Data,
    163                           DataMask
    164                          );
    165 }
    166 /**
    167   Internal function to add PciCfg write opcode to the table.
    168 
    169   @param  Marker                The variable argument list to get the opcode
    170                                 and associated attributes.
    171 
    172   @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
    173   @retval EFI_SUCCESS           Opcode is added.
    174 
    175 **/
    176 EFI_STATUS
    177 BootScriptPciCfgWrite (
    178   IN VA_LIST                     Marker
    179   )
    180 {
    181   EFI_BOOT_SCRIPT_WIDTH Width;
    182   UINT64                Address;
    183   UINTN                 Count;
    184   UINT8                 *Buffer;
    185 
    186   Width       = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
    187   Address     = VA_ARG (Marker, UINT64);
    188   Count       = VA_ARG (Marker, UINTN);
    189   Buffer      = VA_ARG (Marker, UINT8 *);
    190 
    191   return  mS3SmmSaveState->Write (
    192                         mS3SmmSaveState,
    193                         EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,
    194                         Width,
    195                         Address,
    196                         Count,
    197                         Buffer
    198                         );
    199 }
    200 /**
    201   Internal function to add stall opcode to the table.
    202 
    203   @param  Marker                The variable argument list to get the opcode
    204                                 and associated attributes.
    205 
    206   @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
    207   @retval EFI_SUCCESS           Opcode is added.
    208 
    209 **/
    210 EFI_STATUS
    211 BootScriptStall (
    212   IN VA_LIST                       Marker
    213   )
    214 {
    215   UINT32                Duration;
    216 
    217   Duration    = VA_ARG (Marker, UINT32);
    218 
    219   return mS3SmmSaveState->Write (
    220                           mS3SmmSaveState,
    221                           EFI_BOOT_SCRIPT_STALL_OPCODE,
    222                           Duration
    223                          );
    224 }
    225 /**
    226   Internal function to add Save jmp address according to DISPATCH_OPCODE.
    227   We ignore "Context" parameter
    228 
    229   @param  Marker                The variable argument list to get the opcode
    230                                 and associated attributes.
    231 
    232   @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
    233   @retval EFI_SUCCESS           Opcode is added.
    234 
    235 **/
    236 EFI_STATUS
    237 BootScriptDispatch (
    238   IN VA_LIST                       Marker
    239   )
    240 {
    241   VOID        *EntryPoint;
    242 
    243   EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);
    244   return mS3SmmSaveState->Write (
    245                           mS3SmmSaveState,
    246                           EFI_BOOT_SCRIPT_DISPATCH_OPCODE,
    247                           EntryPoint
    248                          );
    249 }
    250 /**
    251   Internal function to add memory write opcode to the table.
    252 
    253   @param  Marker                The variable argument list to get the opcode
    254                                 and associated attributes.
    255 
    256   @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.
    257   @retval EFI_SUCCESS           Opcode is added.
    258 
    259 **/
    260 EFI_STATUS
    261 BootScriptMemWrite (
    262   IN VA_LIST                       Marker
    263   )
    264 {
    265   EFI_BOOT_SCRIPT_WIDTH Width;
    266   UINT64                Address;
    267   UINTN                 Count;
    268   UINT8                 *Buffer;
    269 
    270   Width       = VA_ARG (Marker, EFI_BOOT_SCRIPT_WIDTH);
    271   Address     = VA_ARG (Marker, UINT64);
    272   Count       = VA_ARG (Marker, UINTN);
    273   Buffer      = VA_ARG (Marker, UINT8 *);
    274 
    275   return mS3SmmSaveState->Write (
    276                         mS3SmmSaveState,
    277                         EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,
    278                         Width,
    279                         Address,
    280                         Count,
    281                         Buffer
    282                         );
    283 }
    284 /**
    285   Adds a record into a specified Framework boot script table.
    286 
    287   This function is used to store a boot script record into a given boot
    288   script table in SMM runtime. The parameter is the same with definitionin BootScriptSave Protocol.
    289 
    290   @param  ScriptTable           Pointer to the script table to write to. In the thunk implementation, this parameter is ignored
    291                                 since the boot script table is maintained by BootScriptLib.
    292   @param  Type                  Not used.
    293   @param  OpCode                The operation code (opcode) number.
    294   @param  ...                   Argument list that is specific to each opcode.
    295 
    296   @retval EFI_SUCCESS           The operation succeeded. A record was added into the
    297                                 specified script table.
    298   @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.
    299                                 If the opcode is unknow or not supported because of the PCD
    300                                 Feature Flags.
    301   @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.
    302 **/
    303 EFI_STATUS
    304 EFIAPI
    305 SmmBootScriptWrite (
    306   IN OUT   EFI_SMM_SCRIPT_TABLE        *ScriptTable,
    307   IN       UINTN                       Type,
    308   IN       UINT16                      OpCode,
    309   ...
    310   )
    311 {
    312   EFI_STATUS  Status;
    313   VA_LIST     Marker;
    314 
    315   if (mS3SmmSaveState == NULL) {
    316     return EFI_UNSUPPORTED;
    317   }
    318 
    319   //
    320   // Build script according to opcode
    321   //
    322   switch (OpCode) {
    323 
    324   case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
    325     VA_START (Marker, OpCode);
    326     Status = BootScriptIoWrite (Marker);
    327     VA_END (Marker);
    328     break;
    329 
    330   case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
    331     VA_START (Marker, OpCode);
    332     Status = BootScriptIoReadWrite (Marker);
    333     VA_END (Marker);
    334     break;
    335 
    336   case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
    337     VA_START (Marker, OpCode);
    338     Status = BootScriptMemReadWrite (Marker);
    339     VA_END (Marker);
    340     break;
    341 
    342   case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
    343     VA_START (Marker, OpCode);
    344     Status = BootScriptPciCfgReadWrite (Marker);
    345     VA_END (Marker);
    346     break;
    347 
    348   case EFI_BOOT_SCRIPT_STALL_OPCODE:
    349     VA_START (Marker, OpCode);
    350     Status = BootScriptStall (Marker);
    351     VA_END (Marker);
    352     break;
    353 
    354   case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
    355     VA_START (Marker, OpCode);
    356     Status = BootScriptDispatch (Marker);
    357     VA_END (Marker);
    358     break;
    359 
    360 
    361   case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
    362     VA_START (Marker, OpCode);
    363     Status = BootScriptPciCfgWrite (Marker);
    364     VA_END (Marker);
    365     break;
    366 
    367   case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
    368     VA_START (Marker, OpCode);
    369     Status = BootScriptMemWrite (Marker);
    370     VA_END (Marker);
    371     break;
    372 
    373   default:
    374     Status = EFI_INVALID_PARAMETER;
    375     break;
    376   }
    377 
    378   return Status;
    379 }
    380 /**
    381   Intialize Boot Script table.
    382 
    383   This function should be called in SMM mode. The Thunk implementation is try to
    384   locate SmmSaveState protocol.
    385 
    386   @param  SystemTable         Pointer to the EFI sytem table
    387   @param  SmmScriptTablePages The expected ScriptTable page number
    388   @param  SmmScriptTableBase  The returned ScriptTable base address
    389 
    390   @retval EFI_OUT_OF_RESOURCES    No resource to do the initialization.
    391   @retval EFI_SUCCESS             Function has completed successfully.
    392 
    393 **/
    394 EFI_STATUS
    395 EFIAPI
    396 InitializeSmmScriptLib (
    397   IN  EFI_SYSTEM_TABLE     *SystemTable,
    398   IN  UINTN                SmmScriptTablePages,
    399   OUT EFI_PHYSICAL_ADDRESS *SmmScriptTableBase
    400   )
    401 {
    402   EFI_STATUS        Status;
    403   BOOLEAN           InSmm;
    404   EFI_SMM_BASE2_PROTOCOL          *InternalSmmBase2;
    405 
    406   InternalSmmBase2  = NULL;
    407   //
    408   // The boot Script table is maintained by DxeBootScript Lib. so there is no need to
    409   // allocate the table here and directly return zero
    410   //
    411   if (SmmScriptTableBase == NULL) {
    412     return EFI_INVALID_PARAMETER;
    413   }
    414   *SmmScriptTableBase = 0;
    415   //
    416   // Retrieve SMM Base2 Protocol
    417   //
    418   Status = SystemTable->BootServices->LocateProtocol (
    419                   &mEfiSmmBase2ProtocolGuid,
    420                   NULL,
    421                   (VOID **) &InternalSmmBase2
    422                   );
    423   ASSERT_EFI_ERROR (Status);
    424   ASSERT (InternalSmmBase2 != NULL);
    425 
    426   //
    427   // Check to see if we are already in SMM
    428   //
    429   InternalSmmBase2->InSmm (InternalSmmBase2, &InSmm);
    430 
    431   if (!InSmm) {
    432     //
    433     // We are not in SMM, Directly return;
    434     //
    435     return EFI_SUCCESS;
    436   }
    437 
    438   //
    439   // We are in SMM, retrieve the pointer to SMM System Table
    440   //
    441   InternalSmmBase2->GetSmstLocation (InternalSmmBase2, &gSmst);
    442 
    443   ASSERT (gSmst != NULL);
    444   //
    445   // Locate Smm S3 Save State protocol to do the boot script save operation.
    446   //
    447   Status = gSmst->SmmLocateProtocol (
    448                                  &mEfiS3SmmSaveStateProtocolGuid,
    449                                   NULL,
    450                                  (VOID**)&mS3SmmSaveState
    451                                 );
    452   return Status;
    453 }
    454 /**
    455   Create Boot Script table.
    456 
    457   It will be ignore and just return EFI_SUCCESS since the boot script table is
    458   maintained by DxeBootScriptLib. Create Table is not needed.
    459 
    460   @param  ScriptTable     Pointer to the boot script table to create.
    461   @param  Type            The type of table to creat.
    462 
    463 
    464   @retval EFI_SUCCESS     Function has completed successfully.
    465 
    466 **/
    467 EFI_STATUS
    468 EFIAPI
    469 SmmBootScriptCreateTable (
    470   IN OUT   EFI_SMM_SCRIPT_TABLE        *ScriptTable,
    471   IN       UINTN                       Type
    472   )
    473 {
    474   return EFI_SUCCESS;
    475 }
    476 /**
    477   Close Boot Script table.
    478 
    479   It will be ignore and just return EFI_SUCCESS since the boot script table
    480   is maintained by DxeBootScriptLib.
    481 
    482   @param  ScriptTableBase    Pointer to the boot script table to create.
    483   @param  ScriptTablePtr     Pointer to the script table to write to.
    484   @param  Type               The type of table to creat.
    485 
    486   @retval EFI_SUCCESS        Function has completed successfully.
    487 
    488 **/
    489 EFI_STATUS
    490 EFIAPI
    491 SmmBootScriptCloseTable (
    492   IN EFI_SMM_SCRIPT_TABLE        ScriptTableBase,
    493   IN EFI_SMM_SCRIPT_TABLE        ScriptTablePtr,
    494   IN UINTN                       Type
    495   )
    496 {
    497   return EFI_SUCCESS;
    498 }
    499