3 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
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
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.
15 #include <Chipset/ArmV7.h>
16 #include <Library/ArmLib.h>
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
21 #include "ArmLibPrivate.h"
24 FillTranslationTable (
25 IN UINT32
*TranslationTable
,
26 IN ARM_MEMORY_REGION_DESCRIPTOR
*MemoryRegion
33 UINT32 PhysicalBase
= MemoryRegion
->PhysicalBase
;
35 switch (MemoryRegion
->Attributes
) {
36 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
:
37 Attributes
= TT_DESCRIPTOR_SECTION_WRITE_BACK
;
39 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH
:
40 Attributes
= TT_DESCRIPTOR_SECTION_WRITE_THROUGH
;
42 case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
:
43 Attributes
= TT_DESCRIPTOR_SECTION_DEVICE
;
45 case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
:
47 Attributes
= TT_DESCRIPTOR_SECTION_UNCACHED
;
51 Entry
= TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable
, MemoryRegion
->VirtualBase
);
52 Sections
= MemoryRegion
->Length
/ TT_DESCRIPTOR_SECTION_SIZE
;
54 for (Index
= 0; Index
< Sections
; Index
++) {
55 *Entry
++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase
) | Attributes
;
56 PhysicalBase
+= TT_DESCRIPTOR_SECTION_SIZE
;
63 IN ARM_MEMORY_REGION_DESCRIPTOR
*MemoryTable
,
64 OUT VOID
**TranslationTableBase OPTIONAL
,
65 OUT UINTN
*TranslationTableSize OPTIONAL
68 VOID
*TranslationTable
;
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
);
74 if (TranslationTableBase
!= NULL
) {
75 *TranslationTableBase
= TranslationTable
;
78 if (TranslationTableBase
!= NULL
) {
79 *TranslationTableSize
= TRANSLATION_TABLE_SIZE
;
82 ZeroMem(TranslationTable
, TRANSLATION_TABLE_SIZE
);
84 ArmCleanInvalidateDataCache();
85 ArmInvalidateInstructionCache();
88 ArmDisableDataCache();
89 ArmDisableInstructionCache();
92 // Make sure nothing sneaked into the cache
93 ArmCleanInvalidateDataCache();
94 ArmInvalidateInstructionCache();
96 while (MemoryTable
->Length
!= 0) {
97 FillTranslationTable(TranslationTable
, MemoryTable
);
101 ArmSetTranslationTableBaseAddress(TranslationTable
);
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));
120 ArmEnableInstructionCache();
121 ArmEnableDataCache();
131 return ARM_CACHE_TYPE_WRITE_BACK
;
134 ARM_CACHE_ARCHITECTURE
136 ArmCacheArchitecture (
140 UINT32 CLIDR
= ReadCLIDR ();
142 return CLIDR
; // BugBug Fix Me
147 ArmDataCachePresent (
151 UINT32 CLIDR
= ReadCLIDR ();
153 if ((CLIDR
& 0x2) == 0x2) {
154 // Instruction cache exists
157 if ((CLIDR
& 0x7) == 0x4) {
172 UINT32 Associativity
;
174 UINT32 CCSIDR
= ReadCCSIDR (0);
176 LineSize
= (1 << (CCSIDR
+ 2));
177 Associativity
= ((CCSIDR
>> 3) & 0x3ff) + 1;
178 NumSets
= ((CCSIDR
>> 13) & 0x7fff) + 1;
180 // LineSize is in words (4 byte chunks)
181 return NumSets
* Associativity
* LineSize
* 4;
186 ArmDataCacheAssociativity (
190 UINT32 CCSIDR
= ReadCCSIDR (0);
192 return ((CCSIDR
>> 3) & 0x3ff) + 1;
200 UINT32 CCSIDR
= ReadCCSIDR (0);
202 return ((CCSIDR
>> 13) & 0x7fff) + 1;
207 ArmDataCacheLineLength (
211 UINT32 CCSIDR
= ReadCCSIDR (0) & 7;
213 // * 4 converts to bytes
214 return (1 << (CCSIDR
+ 2)) * 4;
219 ArmInstructionCachePresent (
223 UINT32 CLIDR
= ReadCLIDR ();
225 if ((CLIDR
& 1) == 1) {
226 // Instruction cache exists
229 if ((CLIDR
& 0x7) == 0x4) {
239 ArmInstructionCacheSize (
244 UINT32 Associativity
;
246 UINT32 CCSIDR
= ReadCCSIDR (1);
248 LineSize
= (1 << (CCSIDR
+ 2));
249 Associativity
= ((CCSIDR
>> 3) & 0x3ff) + 1;
250 NumSets
= ((CCSIDR
>> 13) & 0x7fff) + 1;
252 // LineSize is in words (4 byte chunks)
253 return NumSets
* Associativity
* LineSize
* 4;
258 ArmInstructionCacheAssociativity (
262 UINT32 CCSIDR
= ReadCCSIDR (1);
264 return ((CCSIDR
>> 3) & 0x3ff) + 1;
270 ArmInstructionCacheSets (
274 UINT32 CCSIDR
= ReadCCSIDR (1);
276 return ((CCSIDR
>> 13) & 0x7fff) + 1;
281 ArmInstructionCacheLineLength (
285 UINT32 CCSIDR
= ReadCCSIDR (1) & 7;
287 // * 4 converts to bytes
288 return (1 << (CCSIDR
+ 2)) * 4;
295 ArmV7DataCacheOperation (
296 IN ARM_V7_CACHE_OPERATION DataCacheOperation
299 UINTN SavedInterruptState
;
301 SavedInterruptState
= ArmGetInterruptState ();
303 ArmV7AllDataCachesOperation (DataCacheOperation
);
305 ArmDrainWriteBuffer ();
307 if (SavedInterruptState
) {
308 ArmEnableInterrupts ();
314 ArmInvalidateDataCache (
318 ArmV7DataCacheOperation (ArmInvalidateDataCacheEntryBySetWay
);
323 ArmCleanInvalidateDataCache (
327 ArmV7DataCacheOperation (ArmCleanInvalidateDataCacheEntryBySetWay
);
336 ArmV7DataCacheOperation (ArmCleanDataCacheEntryBySetWay
);