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