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