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