]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexALib.c
Need to add some extra functions to the libraries to support paging in the CpuDxe...
[mirror_edk2.git] / ArmPkg / Library / ArmLib / ArmCortexA / ArmCortexALib.c
1 /** @file
2
3 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
4
5 All rights reserved. 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 <Chipset/Cortex-A8.h>
16 #include <Library/ArmLib.h>
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include "ArmCortexALib.h"
21
22 VOID
23 FillTranslationTable (
24 IN UINT32 *TranslationTable,
25 IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
26 )
27 {
28 UINT32 *Entry;
29 UINTN Sections;
30 UINTN Index;
31 UINT32 Attributes;
32 UINT32 PhysicalBase = MemoryRegion->PhysicalBase;
33
34 switch (MemoryRegion->Attributes) {
35 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
36 Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
37 break;
38 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
39 Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
40 break;
41 case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
42 Attributes = TT_DESCRIPTOR_SECTION_DEVICE;
43 break;
44 case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
45 default:
46 Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
47 break;
48 }
49
50 Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
51 Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;
52
53 for (Index = 0; Index < Sections; Index++) {
54 *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
55 PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
56 }
57 }
58
59 VOID
60 EFIAPI
61 ArmConfigureMmu (
62 IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
63 OUT VOID **TranslationTableBase OPTIONAL,
64 OUT UINTN *TranslationTableSize OPTIONAL
65 )
66 {
67 VOID *TranslationTable;
68
69 // Allocate pages for translation table.
70 TranslationTable = AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SIZE + TRANSLATION_TABLE_ALIGNMENT));
71 TranslationTable = (VOID *)(((UINTN)TranslationTable + TRANSLATION_TABLE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_ALIGNMENT_MASK);
72
73 if (TranslationTableBase != NULL) {
74 *TranslationTableBase = TranslationTable;
75 }
76
77 if (TranslationTableBase != NULL) {
78 *TranslationTableSize = TRANSLATION_TABLE_SIZE;
79 }
80
81 ZeroMem(TranslationTable, TRANSLATION_TABLE_SIZE);
82
83 ArmCleanInvalidateDataCache();
84 ArmInvalidateInstructionCache();
85 ArmInvalidateTlb();
86
87 ArmDisableDataCache();
88 ArmDisableInstructionCache();
89 ArmDisableMmu();
90
91 // Make sure nothing sneaked into the cache
92 ArmCleanInvalidateDataCache();
93 ArmInvalidateInstructionCache();
94
95 while (MemoryTable->Length != 0) {
96 FillTranslationTable(TranslationTable, MemoryTable);
97 MemoryTable++;
98 }
99
100 ArmSetTranslationTableBaseAddress(TranslationTable);
101
102 ArmSetDomainAccessControl(DOMAIN_ACCESS_CONTROL_NONE(15) |
103 DOMAIN_ACCESS_CONTROL_NONE(14) |
104 DOMAIN_ACCESS_CONTROL_NONE(13) |
105 DOMAIN_ACCESS_CONTROL_NONE(12) |
106 DOMAIN_ACCESS_CONTROL_NONE(11) |
107 DOMAIN_ACCESS_CONTROL_NONE(10) |
108 DOMAIN_ACCESS_CONTROL_NONE( 9) |
109 DOMAIN_ACCESS_CONTROL_NONE( 8) |
110 DOMAIN_ACCESS_CONTROL_NONE( 7) |
111 DOMAIN_ACCESS_CONTROL_NONE( 6) |
112 DOMAIN_ACCESS_CONTROL_NONE( 5) |
113 DOMAIN_ACCESS_CONTROL_NONE( 4) |
114 DOMAIN_ACCESS_CONTROL_NONE( 3) |
115 DOMAIN_ACCESS_CONTROL_NONE( 2) |
116 DOMAIN_ACCESS_CONTROL_NONE( 1) |
117 DOMAIN_ACCESS_CONTROL_MANAGER(0));
118
119 ArmEnableInstructionCache();
120 ArmEnableDataCache();
121 ArmEnableMmu();
122 }
123
124 ARM_CACHE_TYPE
125 EFIAPI
126 ArmCacheType (
127 VOID
128 )
129 {
130 return ARM_CACHE_TYPE_WRITE_BACK;
131 }
132
133 ARM_CACHE_ARCHITECTURE
134 EFIAPI
135 ArmCacheArchitecture (
136 VOID
137 )
138 {
139 return ARM_CACHE_ARCHITECTURE_SEPARATE;
140 }
141
142 BOOLEAN
143 EFIAPI
144 ArmDataCachePresent (
145 VOID
146 )
147 {
148 return TRUE;
149 }
150
151 UINTN
152 EFIAPI
153 ArmDataCacheSize (
154 VOID
155 )
156 {
157 return 16 * 1024;
158 }
159
160 UINTN
161 EFIAPI
162 ArmDataCacheAssociativity (
163 VOID
164 )
165 {
166 return 4;
167 }
168
169 UINTN
170 ArmDataCacheSets (
171 VOID
172 )
173 {
174 return 64;
175 }
176
177 UINTN
178 EFIAPI
179 ArmDataCacheLineLength (
180 VOID
181 )
182 {
183 return 64;
184 }
185
186 BOOLEAN
187 EFIAPI
188 ArmInstructionCachePresent (
189 VOID
190 )
191 {
192 return TRUE;
193 }
194
195 UINTN
196 EFIAPI
197 ArmInstructionCacheSize (
198 VOID
199 )
200 {
201 return 16 * 1024;
202 }
203
204 UINTN
205 EFIAPI
206 ArmInstructionCacheAssociativity (
207 VOID
208 )
209 {
210 return 4;
211 }
212
213 UINTN
214 EFIAPI
215 ArmInstructionCacheLineLength (
216 VOID
217 )
218 {
219 return 64;
220 }
221
222 VOID
223 ArmCortexADataCacheOperation (
224 IN ARM_CORTEX_A_CACHE_OPERATION DataCacheOperation
225 )
226 {
227 UINTN Set;
228 UINTN SetCount;
229 UINTN SetShift;
230 UINTN Way;
231 UINTN WayCount;
232 UINTN WayShift;
233 UINT32 SetWayFormat;
234 UINTN SavedInterruptState;
235
236 SetCount = ArmDataCacheSets();
237 WayCount = ArmDataCacheAssociativity();
238
239 // Cortex-A8 Manual, System Control Coprocessor chapter
240 SetShift = 6;
241 WayShift = 32 - LowBitSet32 ((UINT32)WayCount);
242
243 SavedInterruptState = ArmDisableInterrupts();
244
245 for (Way = 0; Way < WayCount; Way++) {
246 for (Set = 0; Set < SetCount; Set++) {
247 // Build the format that the CP15 instruction can understand
248 SetWayFormat = (Way << WayShift) | (Set << SetShift);
249
250 // Pass it through
251 (*DataCacheOperation)(SetWayFormat);
252 }
253 }
254
255 ArmDrainWriteBuffer();
256
257 if (SavedInterruptState) {
258 ArmEnableInterrupts();
259 }
260 }
261
262 VOID
263 EFIAPI
264 ArmInvalidateDataCache (
265 VOID
266 )
267 {
268 ArmCortexADataCacheOperation(ArmInvalidateDataCacheEntryBySetWay);
269 }
270
271 VOID
272 EFIAPI
273 ArmCleanInvalidateDataCache (
274 VOID
275 )
276 {
277 ArmCortexADataCacheOperation(ArmCleanInvalidateDataCacheEntryBySetWay);
278 }
279
280 VOID
281 EFIAPI
282 ArmCleanDataCache (
283 VOID
284 )
285 {
286 ArmCortexADataCacheOperation(ArmCleanDataCacheEntryBySetWay);
287 }