2 * File managing the MMU for ARMv7 architecture
4 * Copyright (c) 2011, ARM Limited. All rights reserved.
6 * This program and the accompanying materials
7 * are licensed and made available under the terms and conditions of the BSD License
8 * which accompanies this distribution. The full text of the license may be found at
9 * http://opensource.org/licenses/bsd-license.php
11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Chipset/ArmV7.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/ArmLib.h>
21 #include <Library/BaseLib.h>
23 #include "ArmLibPrivate.h"
26 FillTranslationTable (
27 IN UINT32
*TranslationTable
,
28 IN ARM_MEMORY_REGION_DESCRIPTOR
*MemoryRegion
35 UINT32 PhysicalBase
= MemoryRegion
->PhysicalBase
;
37 switch (MemoryRegion
->Attributes
) {
38 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
:
39 Attributes
= TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
41 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH
:
42 Attributes
= TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
44 case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
:
45 Attributes
= TT_DESCRIPTOR_SECTION_DEVICE(0);
47 case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
:
48 Attributes
= TT_DESCRIPTOR_SECTION_UNCACHED(0);
50 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK
:
51 Attributes
= TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
53 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH
:
54 Attributes
= TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
56 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE
:
57 Attributes
= TT_DESCRIPTOR_SECTION_DEVICE(1);
59 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED
:
60 Attributes
= TT_DESCRIPTOR_SECTION_UNCACHED(1);
63 Attributes
= TT_DESCRIPTOR_SECTION_UNCACHED(0);
67 Entry
= TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable
, MemoryRegion
->VirtualBase
);
68 Sections
= MemoryRegion
->Length
/ TT_DESCRIPTOR_SECTION_SIZE
;
70 for (Index
= 0; Index
< Sections
; Index
++) {
71 *Entry
++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase
) | Attributes
;
72 PhysicalBase
+= TT_DESCRIPTOR_SECTION_SIZE
;
79 IN ARM_MEMORY_REGION_DESCRIPTOR
*MemoryTable
,
80 OUT VOID
**TranslationTableBase OPTIONAL
,
81 OUT UINTN
*TranslationTableSize OPTIONAL
84 UINTN TranslationTable
;
85 ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute
;
86 UINT32 TTBRAttributes
;
88 // Allocate pages for translation table.
89 TranslationTable
= (UINTN
)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SECTION_SIZE
+ TRANSLATION_TABLE_SECTION_ALIGNMENT
));
90 TranslationTable
= ((UINTN
)TranslationTable
+ TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK
) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK
;
92 if (TranslationTableBase
!= NULL
) {
93 *TranslationTableBase
= (VOID
*)TranslationTable
;
96 if (TranslationTableBase
!= NULL
) {
97 *TranslationTableSize
= TRANSLATION_TABLE_SECTION_SIZE
;
100 ZeroMem ((VOID
*)TranslationTable
, TRANSLATION_TABLE_SECTION_SIZE
);
102 ArmCleanInvalidateDataCache();
103 ArmInvalidateInstructionCache();
106 ArmDisableDataCache();
107 ArmDisableInstructionCache();
110 // Make sure nothing sneaked into the cache
111 ArmCleanInvalidateDataCache();
112 ArmInvalidateInstructionCache();
114 TranslationTableAttribute
= 0;
115 while (MemoryTable
->Length
!= 0) {
116 // Find the memory attribute for the Translation Table
117 if ((TranslationTable
>= MemoryTable
->PhysicalBase
) && (TranslationTable
< MemoryTable
->PhysicalBase
+ MemoryTable
->Length
)) {
118 TranslationTableAttribute
= MemoryTable
->Attributes
;
121 FillTranslationTable ((VOID
*)TranslationTable
, MemoryTable
);
125 // Translate the Memory Attributes into Translation Table Register Attributes
126 if ((TranslationTableAttribute
== ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
) ||
127 (TranslationTableAttribute
== ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED
)) {
128 TTBRAttributes
= TTBR_NON_CACHEABLE
;
129 } else if ((TranslationTableAttribute
== ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
) ||
130 (TranslationTableAttribute
== ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK
)) {
131 TTBRAttributes
= TTBR_WRITE_BACK_ALLOC
;
132 } else if ((TranslationTableAttribute
== ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH
) ||
133 (TranslationTableAttribute
== ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH
)) {
134 TTBRAttributes
= TTBR_WRITE_THROUGH_NO_ALLOC
;
136 //TODO: We should raise an error here
137 TTBRAttributes
= TTBR_NON_CACHEABLE
;
140 ArmSetTTBR0 ((VOID
*)(UINTN
)((TranslationTable
& 0xFFFFC000) | (TTBRAttributes
& 0x7F)));
142 ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) |
143 DOMAIN_ACCESS_CONTROL_NONE(14) |
144 DOMAIN_ACCESS_CONTROL_NONE(13) |
145 DOMAIN_ACCESS_CONTROL_NONE(12) |
146 DOMAIN_ACCESS_CONTROL_NONE(11) |
147 DOMAIN_ACCESS_CONTROL_NONE(10) |
148 DOMAIN_ACCESS_CONTROL_NONE( 9) |
149 DOMAIN_ACCESS_CONTROL_NONE( 8) |
150 DOMAIN_ACCESS_CONTROL_NONE( 7) |
151 DOMAIN_ACCESS_CONTROL_NONE( 6) |
152 DOMAIN_ACCESS_CONTROL_NONE( 5) |
153 DOMAIN_ACCESS_CONTROL_NONE( 4) |
154 DOMAIN_ACCESS_CONTROL_NONE( 3) |
155 DOMAIN_ACCESS_CONTROL_NONE( 2) |
156 DOMAIN_ACCESS_CONTROL_NONE( 1) |
157 DOMAIN_ACCESS_CONTROL_MANAGER(0));
159 ArmEnableInstructionCache();
160 ArmEnableDataCache();