]>
Commit | Line | Data |
---|---|---|
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 | ||
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 | } |