]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Drivers/CpuPei/CpuPei.c
e984f5f1bf020040acd50aaca835b58fa9595102
[mirror_edk2.git] / ArmPkg / Drivers / CpuPei / CpuPei.c
1 /**@file
2
3 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4 Copyright (c) 2011 Hewlett Packard Corporation. All rights reserved.<BR>
5 Copyright (c) 2011-2013, ARM Limited. All rights reserved.<BR>
6
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 Module Name:
16
17 MemoryInit.c
18
19 Abstract:
20
21 PEIM to provide fake memory init
22
23 **/
24
25
26
27 //
28 // The package level header files this module uses
29 //
30 #include <PiPei.h>
31 //
32 // The protocols, PPI and GUID defintions for this module
33 //
34 #include <Ppi/ArmMpCoreInfo.h>
35
36 //
37 // The Library classes this module consumes
38 //
39 #include <Library/DebugLib.h>
40 #include <Library/PeimEntryPoint.h>
41 #include <Library/PeiServicesLib.h>
42 #include <Library/PcdLib.h>
43 #include <Library/HobLib.h>
44 #include <Library/ArmLib.h>
45
46 //
47 // Module globals
48 //
49
50 #define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
51 #define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
52
53 EFI_STATUS
54 FindMainMemory (
55 OUT UINT32 *PhysicalBase,
56 OUT UINT32 *Length
57 )
58 {
59 EFI_PEI_HOB_POINTERS NextHob;
60
61 // Look at the resource descriptor hobs, choose the first system memory one
62 NextHob.Raw = GetHobList ();
63 while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
64 if(NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)
65 {
66 *PhysicalBase = (UINT32)NextHob.ResourceDescriptor->PhysicalStart;
67 *Length = (UINT32)NextHob.ResourceDescriptor->ResourceLength;
68 return EFI_SUCCESS;
69 }
70
71 NextHob.Raw = GET_NEXT_HOB (NextHob);
72 }
73
74 return EFI_NOT_FOUND;
75 }
76
77 VOID
78 ConfigureMmu (
79 VOID
80 )
81 {
82 EFI_STATUS Status;
83 UINTN Idx;
84 UINT32 CacheAttributes;
85 UINT32 SystemMemoryBase;
86 UINT32 SystemMemoryLength;
87 UINT32 SystemMemoryLastAddress;
88 ARM_MEMORY_REGION_DESCRIPTOR MemoryTable[4];
89 VOID *TranslationTableBase;
90 UINTN TranslationTableSize;
91
92 if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
93 CacheAttributes = DDR_ATTRIBUTES_CACHED;
94 } else {
95 CacheAttributes = DDR_ATTRIBUTES_UNCACHED;
96 }
97
98 Idx = 0;
99
100 // Main Memory
101 Status = FindMainMemory (&SystemMemoryBase, &SystemMemoryLength);
102 ASSERT_EFI_ERROR (Status);
103
104 SystemMemoryLastAddress = SystemMemoryBase + (SystemMemoryLength-1);
105
106 // If system memory does not begin at 0
107 if(SystemMemoryBase > 0) {
108 MemoryTable[Idx].PhysicalBase = 0;
109 MemoryTable[Idx].VirtualBase = 0;
110 MemoryTable[Idx].Length = SystemMemoryBase;
111 MemoryTable[Idx].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
112 Idx++;
113 }
114
115 MemoryTable[Idx].PhysicalBase = SystemMemoryBase;
116 MemoryTable[Idx].VirtualBase = SystemMemoryBase;
117 MemoryTable[Idx].Length = SystemMemoryLength;
118 MemoryTable[Idx].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
119 Idx++;
120
121 // If system memory does not go to the last address (0xFFFFFFFF)
122 if( SystemMemoryLastAddress < MAX_ADDRESS ) {
123 MemoryTable[Idx].PhysicalBase = SystemMemoryLastAddress + 1;
124 MemoryTable[Idx].VirtualBase = MemoryTable[Idx].PhysicalBase;
125 MemoryTable[Idx].Length = MAX_ADDRESS - MemoryTable[Idx].PhysicalBase + 1;
126 MemoryTable[Idx].Attributes = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
127 Idx++;
128 }
129
130 // End of Table
131 MemoryTable[Idx].PhysicalBase = 0;
132 MemoryTable[Idx].VirtualBase = 0;
133 MemoryTable[Idx].Length = 0;
134 MemoryTable[Idx].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
135
136 DEBUG ((EFI_D_INFO, "Enabling MMU, setting 0x%08x + %d MB to %a\n",
137 SystemMemoryBase, SystemMemoryLength/1024/1024,
138 (CacheAttributes == DDR_ATTRIBUTES_CACHED) ? "cacheable" : "uncacheable"));
139
140 Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
141 if (EFI_ERROR (Status)) {
142 DEBUG ((EFI_D_ERROR, "Error: Failed to enable MMU (error code: %r)\n", Status));
143 }
144
145 BuildMemoryAllocationHob((EFI_PHYSICAL_ADDRESS)(UINTN)TranslationTableBase, TranslationTableSize, EfiBootServicesData);
146 }
147
148 /*++
149
150 Routine Description:
151
152
153
154 Arguments:
155
156 FileHandle - Handle of the file being invoked.
157 PeiServices - Describes the list of possible PEI Services.
158
159 Returns:
160
161 Status - EFI_SUCCESS if the boot mode could be set
162
163 --*/
164 EFI_STATUS
165 EFIAPI
166 InitializeCpuPeim (
167 IN EFI_PEI_FILE_HANDLE FileHandle,
168 IN CONST EFI_PEI_SERVICES **PeiServices
169 )
170 {
171 EFI_STATUS Status;
172 ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
173 UINTN ArmCoreCount;
174 ARM_CORE_INFO *ArmCoreInfoTable;
175
176 // Enable program flow prediction, if supported.
177 ArmEnableBranchPrediction ();
178
179 // Publish the CPU memory and io spaces sizes
180 BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
181
182 //ConfigureMmu();
183
184 // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
185 Status = PeiServicesLocatePpi (&gArmMpCoreInfoPpiGuid, 0, NULL, (VOID**)&ArmMpCoreInfoPpi);
186 if (!EFI_ERROR(Status)) {
187 // Build the MP Core Info Table
188 ArmCoreCount = 0;
189 Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
190 if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {
191 // Build MPCore Info HOB
192 BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
193 }
194 }
195
196 return EFI_SUCCESS;
197 }