Home | History | Annotate | Download | only in WinNtAutoScanPei
      1 /**@file
      2 
      3 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
      4 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<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 Module Name:
     14   WinNtAutoscan.c
     15 
     16 Abstract:
     17   This PEIM to abstract memory auto-scan in a Windows NT environment.
     18 
     19 Revision History
     20 
     21 **/
     22 
     23 //
     24 // The package level header files this module uses
     25 //
     26 #include <PiPei.h>
     27 #include <WinNtPeim.h>
     28 //
     29 // The protocols, PPI and GUID defintions for this module
     30 //
     31 #include <Ppi/NtAutoscan.h>
     32 #include <Ppi/ReadOnlyVariable2.h>
     33 
     34 #include <Guid/MemoryTypeInformation.h>
     35 
     36 //
     37 // The Library classes this module consumes
     38 //
     39 #include <Library/DebugLib.h>
     40 #include <Library/PeimEntryPoint.h>
     41 #include <Library/HobLib.h>
     42 #include <Library/PeiServicesLib.h>
     43 
     44 EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
     45   { EfiReservedMemoryType,  0x0004 },
     46   { EfiRuntimeServicesCode, 0x0040 },
     47   { EfiRuntimeServicesData, 0x0040 },
     48   { EfiBootServicesCode,    0x0300 },
     49   { EfiBootServicesData,    0x1000 },
     50   { EfiMaxMemoryType,       0      }
     51 };
     52 
     53 /**
     54    Validate variable data for the MemoryTypeInformation.
     55 
     56    @param MemoryData       Variable data.
     57    @param MemoryDataSize   Variable data length.
     58 
     59    @return TRUE            The variable data is valid.
     60    @return FALSE           The variable data is invalid.
     61 
     62 **/
     63 BOOLEAN
     64 ValidateMemoryTypeInfoVariable (
     65   IN EFI_MEMORY_TYPE_INFORMATION      *MemoryData,
     66   IN UINTN                            MemoryDataSize
     67   )
     68 {
     69   UINTN                       Count;
     70   UINTN                       Index;
     71 
     72   // Check the input parameter.
     73   if (MemoryData == NULL) {
     74     return FALSE;
     75   }
     76 
     77   // Get Count
     78   Count = MemoryDataSize / sizeof (*MemoryData);
     79 
     80   // Check Size
     81   if (Count * sizeof(*MemoryData) != MemoryDataSize) {
     82     return FALSE;
     83   }
     84 
     85   // Check last entry type filed.
     86   if (MemoryData[Count - 1].Type != EfiMaxMemoryType) {
     87     return FALSE;
     88   }
     89 
     90   // Check the type filed.
     91   for (Index = 0; Index < Count - 1; Index++) {
     92     if (MemoryData[Index].Type >= EfiMaxMemoryType) {
     93       return FALSE;
     94     }
     95   }
     96 
     97   return TRUE;
     98 }
     99 
    100 EFI_STATUS
    101 EFIAPI
    102 PeimInitializeWinNtAutoScan (
    103   IN       EFI_PEI_FILE_HANDLE       FileHandle,
    104   IN CONST EFI_PEI_SERVICES          **PeiServices
    105   )
    106 /*++
    107 
    108 Routine Description:
    109   Perform a call-back into the SEC simulator to get a memory value
    110 
    111 Arguments:
    112   FfsHeader   - General purpose data available to every PEIM
    113   PeiServices - General purpose services available to every PEIM.
    114 
    115 Returns:
    116   None
    117 
    118 --*/
    119 {
    120   EFI_STATUS                  Status;
    121   EFI_PEI_PPI_DESCRIPTOR      *PpiDescriptor;
    122   PEI_NT_AUTOSCAN_PPI         *PeiNtService;
    123   UINT64                      MemorySize;
    124   EFI_PHYSICAL_ADDRESS        MemoryBase;
    125   UINTN                       Index;
    126   EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
    127   EFI_PEI_READ_ONLY_VARIABLE2_PPI       *Variable;
    128   UINTN                                 DataSize;
    129   EFI_MEMORY_TYPE_INFORMATION           MemoryData [EfiMaxMemoryType + 1];
    130 
    131 
    132   DEBUG ((EFI_D_ERROR, "NT 32 Autoscan PEIM Loaded\n"));
    133 
    134   //
    135   // Get the PEI NT Autoscan PPI
    136   //
    137   Status = PeiServicesLocatePpi (
    138              &gPeiNtAutoScanPpiGuid, // GUID
    139              0,                      // INSTANCE
    140              &PpiDescriptor,         // EFI_PEI_PPI_DESCRIPTOR
    141              (VOID**)&PeiNtService           // PPI
    142              );
    143   ASSERT_EFI_ERROR (Status);
    144 
    145   Index = 0;
    146   do {
    147     Status = PeiNtService->NtAutoScan (Index, &MemoryBase, &MemorySize);
    148     if (!EFI_ERROR (Status)) {
    149       Attributes =
    150         (
    151           EFI_RESOURCE_ATTRIBUTE_PRESENT |
    152           EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    153           EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    154           EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    155           EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    156           EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    157         );
    158 
    159       if (Index == 0) {
    160         //
    161         // Register the memory with the PEI Core
    162         //
    163         Status = PeiServicesInstallPeiMemory (MemoryBase, MemorySize);
    164         ASSERT_EFI_ERROR (Status);
    165 
    166         Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED;
    167       }
    168 
    169       BuildResourceDescriptorHob (
    170         EFI_RESOURCE_SYSTEM_MEMORY,
    171         Attributes,
    172         MemoryBase,
    173         MemorySize
    174         );
    175     }
    176     Index++;
    177   } while (!EFI_ERROR (Status));
    178 
    179   //
    180   // Build the CPU hob with 52-bit addressing and 16-bits of IO space.
    181   //
    182   BuildCpuHob (52, 16);
    183 
    184   //
    185   // Build GUIDed Hob that contains the Memory Type Information array
    186   //
    187   Status = PeiServicesLocatePpi (
    188              &gEfiPeiReadOnlyVariable2PpiGuid,
    189              0,
    190              NULL,
    191              (VOID **)&Variable
    192              );
    193   ASSERT_EFI_ERROR (Status);
    194 
    195   DataSize = sizeof (MemoryData);
    196   Status = Variable->GetVariable (
    197                        Variable,
    198                        EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
    199                        &gEfiMemoryTypeInformationGuid,
    200                        NULL,
    201                        &DataSize,
    202                        &MemoryData
    203                        );
    204   if (EFI_ERROR (Status) || !ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {
    205     //
    206     // Create Memory Type Information HOB
    207     //
    208     BuildGuidDataHob (
    209       &gEfiMemoryTypeInformationGuid,
    210       mDefaultMemoryTypeInformation,
    211       sizeof(mDefaultMemoryTypeInformation)
    212       );
    213   } else {
    214     //
    215     // Create Memory Type Information HOB
    216     //
    217     BuildGuidDataHob (
    218       &gEfiMemoryTypeInformationGuid,
    219       MemoryData,
    220       DataSize
    221       );
    222   }
    223 
    224   return Status;
    225 }
    226