Home | History | Annotate | Download | only in SecCore
      1 /** @file
      2   Get SEC platform information(2) PPI and reinstall it.
      3 
      4   Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "SecMain.h"
     16 
     17 EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformation = {
     18   SecPlatformInformationBist
     19 };
     20 
     21 EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation = {
     22   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
     23   &gEfiSecPlatformInformationPpiGuid,
     24   &mSecPlatformInformation
     25 };
     26 
     27 EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2 = {
     28   SecPlatformInformation2Bist
     29 };
     30 
     31 EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2 = {
     32   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
     33   &gEfiSecPlatformInformation2PpiGuid,
     34   &mSecPlatformInformation2
     35 };
     36 
     37 /**
     38   Worker function to parse CPU BIST information from Guided HOB.
     39 
     40   @param[in, out] StructureSize     Pointer to the variable describing size of the input buffer.
     41   @param[in, out] StructureBuffer   Pointer to the buffer save CPU BIST information.
     42 
     43   @retval EFI_SUCCESS           The data was successfully returned.
     44   @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
     45 
     46 **/
     47 EFI_STATUS
     48 GetBistFromHob (
     49   IN OUT UINT64           *StructureSize,
     50   IN OUT VOID             *StructureBuffer
     51   )
     52 {
     53   EFI_HOB_GUID_TYPE       *GuidHob;
     54   VOID                    *DataInHob;
     55   UINTN                   DataSize;
     56 
     57   GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid);
     58   if (GuidHob == NULL) {
     59     *StructureSize = 0;
     60     return EFI_SUCCESS;
     61   }
     62 
     63   DataInHob = GET_GUID_HOB_DATA (GuidHob);
     64   DataSize  = GET_GUID_HOB_DATA_SIZE (GuidHob);
     65 
     66   //
     67   // return the information from BistHob
     68   //
     69   if ((*StructureSize) < (UINT64) DataSize) {
     70     *StructureSize = (UINT64) DataSize;
     71     return EFI_BUFFER_TOO_SMALL;
     72   }
     73 
     74   *StructureSize = (UINT64) DataSize;
     75   CopyMem (StructureBuffer, DataInHob, DataSize);
     76   return EFI_SUCCESS;
     77 }
     78 
     79 /**
     80   Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI.
     81 
     82   @param[in]      PeiServices                Pointer to the PEI Services Table.
     83   @param[in, out] StructureSize              Pointer to the variable describing size of the input buffer.
     84   @param[out]     PlatformInformationRecord  Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD.
     85 
     86   @retval EFI_SUCCESS                    The data was successfully returned.
     87   @retval EFI_BUFFER_TOO_SMALL           The buffer was too small.
     88 
     89 **/
     90 EFI_STATUS
     91 EFIAPI
     92 SecPlatformInformationBist (
     93   IN CONST EFI_PEI_SERVICES                  **PeiServices,
     94   IN OUT UINT64                              *StructureSize,
     95      OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord
     96   )
     97 {
     98   return GetBistFromHob (StructureSize, PlatformInformationRecord);
     99 }
    100 
    101 /**
    102   Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
    103 
    104   @param[in]      PeiServices                The pointer to the PEI Services Table.
    105   @param[in, out] StructureSize              The pointer to the variable describing size of the input buffer.
    106   @param[out]     PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2.
    107 
    108   @retval EFI_SUCCESS                    The data was successfully returned.
    109   @retval EFI_BUFFER_TOO_SMALL           The buffer was too small. The current buffer size needed to
    110                                          hold the record is returned in StructureSize.
    111 
    112 **/
    113 EFI_STATUS
    114 EFIAPI
    115 SecPlatformInformation2Bist (
    116   IN CONST EFI_PEI_SERVICES                   **PeiServices,
    117   IN OUT UINT64                               *StructureSize,
    118      OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
    119   )
    120 {
    121   return GetBistFromHob (StructureSize, PlatformInformationRecord2);
    122 }
    123 
    124 /**
    125   Worker function to get CPUs' BIST by calling SecPlatformInformationPpi
    126   or SecPlatformInformation2Ppi.
    127 
    128   @param[in]  PeiServices         Pointer to PEI Services Table
    129   @param[in]  Guid                PPI Guid
    130   @param[out] PpiDescriptor       Return a pointer to instance of the
    131                                   EFI_PEI_PPI_DESCRIPTOR
    132   @param[out] BistInformationData Pointer to BIST information data
    133   @param[out] BistInformationSize Return the size in bytes of BIST information
    134 
    135   @retval EFI_SUCCESS         Retrieve of the BIST data successfully
    136   @retval EFI_NOT_FOUND       No sec platform information(2) ppi export
    137   @retval EFI_DEVICE_ERROR    Failed to get CPU Information
    138 
    139 **/
    140 EFI_STATUS
    141 GetBistInfoFromPpi (
    142   IN CONST EFI_PEI_SERVICES     **PeiServices,
    143   IN CONST EFI_GUID             *Guid,
    144      OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
    145      OUT VOID                   **BistInformationData,
    146      OUT UINT64                 *BistInformationSize OPTIONAL
    147   )
    148 {
    149   EFI_STATUS                            Status;
    150   EFI_SEC_PLATFORM_INFORMATION2_PPI     *SecPlatformInformation2Ppi;
    151   EFI_SEC_PLATFORM_INFORMATION_RECORD2  *SecPlatformInformation2;
    152   UINT64                                InformationSize;
    153 
    154   Status = PeiServicesLocatePpi (
    155              Guid,                                // GUID
    156              0,                                   // INSTANCE
    157              PpiDescriptor,                       // EFI_PEI_PPI_DESCRIPTOR
    158              (VOID **)&SecPlatformInformation2Ppi // PPI
    159              );
    160   if (Status == EFI_NOT_FOUND) {
    161     return EFI_NOT_FOUND;
    162   }
    163 
    164   if (Status == EFI_SUCCESS) {
    165     //
    166     // Get the size of the sec platform information2(BSP/APs' BIST data)
    167     //
    168     InformationSize         = 0;
    169     SecPlatformInformation2 = NULL;
    170     Status = SecPlatformInformation2Ppi->PlatformInformation2 (
    171                                            PeiServices,
    172                                            &InformationSize,
    173                                            SecPlatformInformation2
    174                                            );
    175     if (Status == EFI_BUFFER_TOO_SMALL) {
    176       Status = PeiServicesAllocatePool (
    177                  (UINTN) InformationSize,
    178                  (VOID **) &SecPlatformInformation2
    179                  );
    180       if (Status == EFI_SUCCESS) {
    181         //
    182         // Retrieve BIST data
    183         //
    184         Status = SecPlatformInformation2Ppi->PlatformInformation2 (
    185                                                PeiServices,
    186                                                &InformationSize,
    187                                                SecPlatformInformation2
    188                                                );
    189         if (Status == EFI_SUCCESS) {
    190           *BistInformationData = SecPlatformInformation2;
    191           if (BistInformationSize != NULL) {
    192             *BistInformationSize = InformationSize;
    193           }
    194           return EFI_SUCCESS;
    195         }
    196       }
    197     }
    198   }
    199 
    200   return EFI_DEVICE_ERROR;
    201 }
    202 
    203 /**
    204   Get CPUs' BIST by calling SecPlatformInformationPpi/SecPlatformInformation2Ppi.
    205 
    206 **/
    207 VOID
    208 RepublishSecPlatformInformationPpi (
    209   VOID
    210   )
    211 {
    212   EFI_STATUS                            Status;
    213   CONST EFI_PEI_SERVICES                **PeiServices;
    214   UINT64                                BistInformationSize;
    215   VOID                                  *BistInformationData;
    216   EFI_PEI_PPI_DESCRIPTOR                *SecInformationDescriptor;
    217 
    218   PeiServices = GetPeiServicesTablePointer ();
    219   Status = GetBistInfoFromPpi (
    220              PeiServices,
    221              &gEfiSecPlatformInformation2PpiGuid,
    222              &SecInformationDescriptor,
    223              &BistInformationData,
    224              &BistInformationSize
    225              );
    226   if (Status == EFI_SUCCESS) {
    227     BuildGuidDataHob (
    228       &gEfiCallerIdGuid,
    229       BistInformationData,
    230       (UINTN) BistInformationSize
    231       );
    232     //
    233     // The old SecPlatformInformation2 data is on temporary memory.
    234     // After memory discovered, we should never get it from temporary memory,
    235     // or the data will be crashed. So, we reinstall SecPlatformInformation2 PPI here.
    236     //
    237     Status = PeiServicesReInstallPpi (
    238                SecInformationDescriptor,
    239                &mPeiSecPlatformInformation2
    240                );
    241   } if (Status == EFI_NOT_FOUND) {
    242     Status = GetBistInfoFromPpi (
    243                PeiServices,
    244                &gEfiSecPlatformInformationPpiGuid,
    245                &SecInformationDescriptor,
    246                &BistInformationData,
    247                &BistInformationSize
    248                );
    249     if (Status == EFI_SUCCESS) {
    250       BuildGuidDataHob (
    251         &gEfiCallerIdGuid,
    252         BistInformationData,
    253         (UINTN) BistInformationSize
    254         );
    255       //
    256       // The old SecPlatformInformation data is on temporary memory.
    257       // After memory discovered, we should never get it from temporary memory,
    258       // or the data will be crashed. So, we reinstall SecPlatformInformation PPI here.
    259       //
    260       Status = PeiServicesReInstallPpi (
    261                  SecInformationDescriptor,
    262                  &mPeiSecPlatformInformation
    263                  );
    264     } else if (Status == EFI_NOT_FOUND) {
    265       return;
    266     }
    267   }
    268 
    269   ASSERT_EFI_ERROR(Status);
    270 }
    271