• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 *
3 *  Copyright (c) 2011, ARM Limited. All rights reserved.
4 *
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 <PiPei.h>
16 
17 //
18 // The protocols, PPI and GUID defintions for this module
19 //
20 #include <Ppi/MasterBootMode.h>
21 #include <Ppi/BootInRecoveryMode.h>
22 #include <Guid/MemoryTypeInformation.h>
23 //
24 // The Library classes this module consumes
25 //
26 #include <Library/ArmPlatformLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/HobLib.h>
29 #include <Library/PeimEntryPoint.h>
30 #include <Library/PeiServicesLib.h>
31 #include <Library/PcdLib.h>
32 
33 EFI_STATUS
34 EFIAPI
35 MemoryPeim (
36   IN EFI_PHYSICAL_ADDRESS               UefiMemoryBase,
37   IN UINT64                             UefiMemorySize
38   );
39 
40 // May want to put this into a library so you only need the PCD settings if you are using the feature?
41 VOID
BuildMemoryTypeInformationHob(VOID)42 BuildMemoryTypeInformationHob (
43   VOID
44   )
45 {
46   EFI_MEMORY_TYPE_INFORMATION   Info[10];
47 
48   Info[0].Type          = EfiACPIReclaimMemory;
49   Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
50   Info[1].Type          = EfiACPIMemoryNVS;
51   Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
52   Info[2].Type          = EfiReservedMemoryType;
53   Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
54   Info[3].Type          = EfiRuntimeServicesData;
55   Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
56   Info[4].Type          = EfiRuntimeServicesCode;
57   Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
58   Info[5].Type          = EfiBootServicesCode;
59   Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
60   Info[6].Type          = EfiBootServicesData;
61   Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
62   Info[7].Type          = EfiLoaderCode;
63   Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
64   Info[8].Type          = EfiLoaderData;
65   Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
66 
67   // Terminator for the list
68   Info[9].Type          = EfiMaxMemoryType;
69   Info[9].NumberOfPages = 0;
70 
71   BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
72 }
73 
74 /*++
75 
76 Routine Description:
77 
78 
79 
80 Arguments:
81 
82   FileHandle  - Handle of the file being invoked.
83   PeiServices - Describes the list of possible PEI Services.
84 
85 Returns:
86 
87   Status -  EFI_SUCCESS if the boot mode could be set
88 
89 --*/
90 EFI_STATUS
91 EFIAPI
InitializeMemory(IN EFI_PEI_FILE_HANDLE FileHandle,IN CONST EFI_PEI_SERVICES ** PeiServices)92 InitializeMemory (
93   IN       EFI_PEI_FILE_HANDLE  FileHandle,
94   IN CONST EFI_PEI_SERVICES     **PeiServices
95   )
96 {
97   EFI_STATUS                            Status;
98   UINTN                                 SystemMemoryBase;
99   UINT64                                SystemMemoryTop;
100   UINTN                                 FdBase;
101   UINTN                                 FdTop;
102   UINTN                                 UefiMemoryBase;
103 
104   DEBUG ((EFI_D_LOAD | EFI_D_INFO, "Memory Init PEIM Loaded\n"));
105 
106   //
107   // Initialize the System Memory (DRAM)
108   //
109   if (!FeaturePcdGet (PcdSystemMemoryInitializeInSec)) {
110     // In case the DRAM has not been initialized by the secure firmware
111     ArmPlatformInitializeSystemMemory ();
112   }
113 
114   // Ensure PcdSystemMemorySize has been set
115   ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
116   ASSERT (PcdGet64 (PcdSystemMemoryBase) < (UINT64)MAX_ADDRESS);
117 
118   SystemMemoryBase = (UINTN)PcdGet64 (PcdSystemMemoryBase);
119   SystemMemoryTop = SystemMemoryBase + PcdGet64 (PcdSystemMemorySize);
120   if (SystemMemoryTop - 1 > MAX_ADDRESS) {
121     SystemMemoryTop = (UINT64)MAX_ADDRESS + 1;
122   }
123   FdBase = (UINTN)PcdGet64 (PcdFdBaseAddress);
124   FdTop = FdBase + (UINTN)PcdGet32 (PcdFdSize);
125 
126   //
127   // Declare the UEFI memory to PEI
128   //
129 
130   // In case the firmware has been shadowed in the System Memory
131   if ((FdBase >= SystemMemoryBase) && (FdTop <= SystemMemoryTop)) {
132     // Check if there is enough space between the top of the system memory and the top of the
133     // firmware to place the UEFI memory (for PEI & DXE phases)
134     if (SystemMemoryTop - FdTop >= FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
135       UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
136     } else {
137       // Check there is enough space for the UEFI memory
138       ASSERT (SystemMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) <= FdBase);
139 
140       UefiMemoryBase = FdBase - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
141     }
142   } else {
143     // Check the Firmware does not overlapped with the system memory
144     ASSERT ((FdBase < SystemMemoryBase) || (FdBase >= SystemMemoryTop));
145     ASSERT ((FdTop <= SystemMemoryBase) || (FdTop > SystemMemoryTop));
146 
147     UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
148   }
149 
150   Status = PeiServicesInstallPeiMemory (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
151   ASSERT_EFI_ERROR (Status);
152 
153   // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
154   Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
155   ASSERT_EFI_ERROR (Status);
156 
157   return Status;
158 }
159