]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.c
Update the copyright notice format
[mirror_edk2.git] / ArmPkg / Library / ArmLib / ArmV7 / ArmV7Lib.c
CommitLineData
2ef2b01e
A
1/** @file
2
d6ebcab7 3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
2ef2b01e 4
d6ebcab7 5 This program and the accompanying materials
2ef2b01e
A
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**/
98bc0c8c 14#include <Uefi.h>
5dea9bd6 15#include <Chipset/ArmV7.h>
2ef2b01e
A
16#include <Library/ArmLib.h>
17#include <Library/BaseLib.h>
18#include <Library/BaseMemoryLib.h>
19#include <Library/MemoryAllocationLib.h>
5dea9bd6 20#include "ArmV7Lib.h"
98bc0c8c 21#include "ArmLibPrivate.h"
2ef2b01e
A
22
23VOID
24FillTranslationTable (
25 IN UINT32 *TranslationTable,
26 IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
27 )
28{
29 UINT32 *Entry;
30 UINTN Sections;
31 UINTN Index;
32 UINT32 Attributes;
33 UINT32 PhysicalBase = MemoryRegion->PhysicalBase;
34
35 switch (MemoryRegion->Attributes) {
36 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
37 Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK;
38 break;
39 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
40 Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH;
41 break;
42 case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
43 Attributes = TT_DESCRIPTOR_SECTION_DEVICE;
44 break;
45 case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
46 default:
47 Attributes = TT_DESCRIPTOR_SECTION_UNCACHED;
48 break;
49 }
50
51 Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
52 Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;
53
c2b5ca8b 54 for (Index = 0; Index < Sections; Index++) {
2ef2b01e
A
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{
98bc0c8c 140 UINT32 CLIDR = ReadCLIDR ();
141
142 return CLIDR; // BugBug Fix Me
2ef2b01e
A
143}
144
145BOOLEAN
146EFIAPI
147ArmDataCachePresent (
148 VOID
149 )
150{
98bc0c8c 151 UINT32 CLIDR = ReadCLIDR ();
152
153 if ((CLIDR & 0x2) == 0x2) {
154 // Instruction cache exists
155 return TRUE;
156 }
157 if ((CLIDR & 0x7) == 0x4) {
158 // Unified cache
159 return TRUE;
160 }
161
162 return FALSE;
2ef2b01e
A
163}
164
165UINTN
166EFIAPI
167ArmDataCacheSize (
168 VOID
169 )
170{
98bc0c8c 171 UINT32 NumSets;
172 UINT32 Associativity;
173 UINT32 LineSize;
174 UINT32 CCSIDR = ReadCCSIDR (0);
175
176 LineSize = (1 << (CCSIDR + 2));
177 Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
178 NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
179
180 // LineSize is in words (4 byte chunks)
181 return NumSets * Associativity * LineSize * 4;
2ef2b01e
A
182}
183
184UINTN
185EFIAPI
186ArmDataCacheAssociativity (
187 VOID
188 )
189{
98bc0c8c 190 UINT32 CCSIDR = ReadCCSIDR (0);
191
192 return ((CCSIDR >> 3) & 0x3ff) + 1;
2ef2b01e
A
193}
194
195UINTN
196ArmDataCacheSets (
197 VOID
198 )
199{
98bc0c8c 200 UINT32 CCSIDR = ReadCCSIDR (0);
201
202 return ((CCSIDR >> 13) & 0x7fff) + 1;
2ef2b01e
A
203}
204
205UINTN
206EFIAPI
207ArmDataCacheLineLength (
208 VOID
209 )
210{
98bc0c8c 211 UINT32 CCSIDR = ReadCCSIDR (0) & 7;
212
213 // * 4 converts to bytes
214 return (1 << (CCSIDR + 2)) * 4;
2ef2b01e
A
215}
216
217BOOLEAN
218EFIAPI
219ArmInstructionCachePresent (
220 VOID
221 )
222{
98bc0c8c 223 UINT32 CLIDR = ReadCLIDR ();
224
225 if ((CLIDR & 1) == 1) {
226 // Instruction cache exists
227 return TRUE;
228 }
229 if ((CLIDR & 0x7) == 0x4) {
230 // Unified cache
231 return TRUE;
232 }
233
234 return FALSE;
2ef2b01e
A
235}
236
237UINTN
238EFIAPI
239ArmInstructionCacheSize (
240 VOID
241 )
242{
98bc0c8c 243 UINT32 NumSets;
244 UINT32 Associativity;
245 UINT32 LineSize;
246 UINT32 CCSIDR = ReadCCSIDR (1);
247
248 LineSize = (1 << (CCSIDR + 2));
249 Associativity = ((CCSIDR >> 3) & 0x3ff) + 1;
250 NumSets = ((CCSIDR >> 13) & 0x7fff) + 1;
251
252 // LineSize is in words (4 byte chunks)
253 return NumSets * Associativity * LineSize * 4;
2ef2b01e
A
254}
255
256UINTN
257EFIAPI
258ArmInstructionCacheAssociativity (
259 VOID
260 )
261{
98bc0c8c 262 UINT32 CCSIDR = ReadCCSIDR (1);
263
264 return ((CCSIDR >> 3) & 0x3ff) + 1;
265// return 4;
2ef2b01e
A
266}
267
98bc0c8c 268UINTN
269EFIAPI
270ArmInstructionCacheSets (
271 VOID
272 )
273{
274 UINT32 CCSIDR = ReadCCSIDR (1);
275
276 return ((CCSIDR >> 13) & 0x7fff) + 1;
277}
278
2ef2b01e
A
279UINTN
280EFIAPI
281ArmInstructionCacheLineLength (
282 VOID
283 )
284{
98bc0c8c 285 UINT32 CCSIDR = ReadCCSIDR (1) & 7;
286
287 // * 4 converts to bytes
288 return (1 << (CCSIDR + 2)) * 4;
289
290// return 64;
2ef2b01e
A
291}
292
98bc0c8c 293
2ef2b01e 294VOID
5dea9bd6 295ArmV7DataCacheOperation (
296 IN ARM_V7_CACHE_OPERATION DataCacheOperation
2ef2b01e
A
297 )
298{
2ef2b01e
A
299 UINTN SavedInterruptState;
300
98bc0c8c 301 SavedInterruptState = ArmGetInterruptState ();
2ef2b01e 302
98bc0c8c 303 ArmV7AllDataCachesOperation (DataCacheOperation);
2ef2b01e 304
98bc0c8c 305 ArmDrainWriteBuffer ();
2ef2b01e
A
306
307 if (SavedInterruptState) {
98bc0c8c 308 ArmEnableInterrupts ();
2ef2b01e
A
309 }
310}
311
312VOID
313EFIAPI
314ArmInvalidateDataCache (
315 VOID
316 )
317{
98bc0c8c 318 ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay);
2ef2b01e
A
319}
320
321VOID
322EFIAPI
323ArmCleanInvalidateDataCache (
324 VOID
325 )
326{
98bc0c8c 327 ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay);
2ef2b01e
A
328}
329
330VOID
331EFIAPI
332ArmCleanDataCache (
333 VOID
334 )
335{
98bc0c8c 336 ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay);
2ef2b01e 337}