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