]> git.proxmox.com Git - mirror_edk2.git/blame - 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
CommitLineData
2ef2b01e
A
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
22VOID
23FillTranslationTable (
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
c2b5ca8b 53 for (Index = 0; Index < Sections; Index++) {
2ef2b01e
A
54 *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
55 PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
56 }
57}
58
59VOID
60EFIAPI
61ArmConfigureMmu (
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
124ARM_CACHE_TYPE
125EFIAPI
126ArmCacheType (
127 VOID
128 )
129{
130 return ARM_CACHE_TYPE_WRITE_BACK;
131}
132
133ARM_CACHE_ARCHITECTURE
134EFIAPI
135ArmCacheArchitecture (
136 VOID
137 )
138{
139 return ARM_CACHE_ARCHITECTURE_SEPARATE;
140}
141
142BOOLEAN
143EFIAPI
144ArmDataCachePresent (
145 VOID
146 )
147{
148 return TRUE;
149}
150
151UINTN
152EFIAPI
153ArmDataCacheSize (
154 VOID
155 )
156{
157 return 16 * 1024;
158}
159
160UINTN
161EFIAPI
162ArmDataCacheAssociativity (
163 VOID
164 )
165{
166 return 4;
167}
168
169UINTN
170ArmDataCacheSets (
171 VOID
172 )
173{
174 return 64;
175}
176
177UINTN
178EFIAPI
179ArmDataCacheLineLength (
180 VOID
181 )
182{
183 return 64;
184}
185
186BOOLEAN
187EFIAPI
188ArmInstructionCachePresent (
189 VOID
190 )
191{
192 return TRUE;
193}
194
195UINTN
196EFIAPI
197ArmInstructionCacheSize (
198 VOID
199 )
200{
201 return 16 * 1024;
202}
203
204UINTN
205EFIAPI
206ArmInstructionCacheAssociativity (
207 VOID
208 )
209{
210 return 4;
211}
212
213UINTN
214EFIAPI
215ArmInstructionCacheLineLength (
216 VOID
217 )
218{
219 return 64;
220}
221
222VOID
223ArmCortexADataCacheOperation (
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
262VOID
263EFIAPI
264ArmInvalidateDataCache (
265 VOID
266 )
267{
268 ArmCortexADataCacheOperation(ArmInvalidateDataCacheEntryBySetWay);
269}
270
271VOID
272EFIAPI
273ArmCleanInvalidateDataCache (
274 VOID
275 )
276{
277 ArmCortexADataCacheOperation(ArmCleanInvalidateDataCacheEntryBySetWay);
278}
279
280VOID
281EFIAPI
282ArmCleanDataCache (
283 VOID
284 )
285{
286 ArmCortexADataCacheOperation(ArmCleanDataCacheEntryBySetWay);
287}