ArmPlatformPkg: Increase more ARM address Pcd entries to 64-bit.
[mirror_edk2.git] / ArmPlatformPkg / MemoryInitPei / MemoryInitPeiLib.c
1 /** @file
2 *
3 * Copyright (c) 2011-2014, 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 #include <Library/ArmPlatformLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/HobLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/PcdLib.h>
22
23 VOID
24 BuildMemoryTypeInformationHob (
25 VOID
26 );
27
28 VOID
29 InitMmu (
30 VOID
31 )
32 {
33 ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
34 VOID *TranslationTableBase;
35 UINTN TranslationTableSize;
36 RETURN_STATUS Status;
37
38 // Get Virtual Memory Map from the Platform Library
39 ArmPlatformGetVirtualMemoryMap (&MemoryTable);
40
41 //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
42 // DRAM (even at the top of DRAM as it is the first permanent memory allocation)
43 Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
44 if (EFI_ERROR (Status)) {
45 DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU\n"));
46 }
47 }
48
49 /*++
50
51 Routine Description:
52
53
54
55 Arguments:
56
57 FileHandle - Handle of the file being invoked.
58 PeiServices - Describes the list of possible PEI Services.
59
60 Returns:
61
62 Status - EFI_SUCCESS if the boot mode could be set
63
64 --*/
65 EFI_STATUS
66 EFIAPI
67 MemoryPeim (
68 IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
69 IN UINT64 UefiMemorySize
70 )
71 {
72 EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
73 UINT64 ResourceLength;
74 EFI_PEI_HOB_POINTERS NextHob;
75 EFI_PHYSICAL_ADDRESS FdTop;
76 EFI_PHYSICAL_ADDRESS SystemMemoryTop;
77 EFI_PHYSICAL_ADDRESS ResourceTop;
78 BOOLEAN Found;
79
80 // Ensure PcdSystemMemorySize has been set
81 ASSERT (PcdGet64 (PcdSystemMemorySize) != 0);
82
83 //
84 // Now, the permanent memory has been installed, we can call AllocatePages()
85 //
86 ResourceAttributes = (
87 EFI_RESOURCE_ATTRIBUTE_PRESENT |
88 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
89 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
90 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
91 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
92 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
93 EFI_RESOURCE_ATTRIBUTE_TESTED
94 );
95
96 // Reserved the memory space occupied by the firmware volume
97 BuildResourceDescriptorHob (
98 EFI_RESOURCE_SYSTEM_MEMORY,
99 ResourceAttributes,
100 PcdGet64 (PcdSystemMemoryBase),
101 PcdGet64 (PcdSystemMemorySize)
102 );
103
104 SystemMemoryTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemoryBase) + (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdSystemMemorySize);
105 FdTop = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdFdBaseAddress) + (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFdSize);
106
107 // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE
108 // core to overwrite this area we must mark the region with the attribute non-present
109 if ((PcdGet64 (PcdFdBaseAddress) >= PcdGet64 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {
110 Found = FALSE;
111
112 // Search for System Memory Hob that contains the firmware
113 NextHob.Raw = GetHobList ();
114 while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
115 if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
116 (PcdGet64 (PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&
117 (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
118 {
119 ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
120 ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
121 ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
122
123 if (PcdGet64 (PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {
124 if (SystemMemoryTop == FdTop) {
125 NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT;
126 } else {
127 // Create the System Memory HOB for the firmware with the non-present attribute
128 BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
129 ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
130 PcdGet64 (PcdFdBaseAddress),
131 PcdGet32 (PcdFdSize));
132
133 // Top of the FD is system memory available for UEFI
134 NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize);
135 NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize);
136 }
137 } else {
138 // Create the System Memory HOB for the firmware with the non-present attribute
139 BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
140 ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
141 PcdGet64 (PcdFdBaseAddress),
142 PcdGet32 (PcdFdSize));
143
144 // Update the HOB
145 NextHob.ResourceDescriptor->ResourceLength = PcdGet64 (PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;
146
147 // If there is some memory available on the top of the FD then create a HOB
148 if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {
149 // Create the System Memory HOB for the remaining region (top of the FD)
150 BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
151 ResourceAttributes,
152 FdTop,
153 ResourceTop - FdTop);
154 }
155 }
156 Found = TRUE;
157 break;
158 }
159 NextHob.Raw = GET_NEXT_HOB (NextHob);
160 }
161
162 ASSERT(Found);
163 }
164
165 // Build Memory Allocation Hob
166 InitMmu ();
167
168 if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
169 // Optional feature that helps prevent EFI memory map fragmentation.
170 BuildMemoryTypeInformationHob ();
171 }
172
173 return EFI_SUCCESS;
174 }