]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
Sync up ArmPkg with patch from mailing list. Changed name of BdsLib.h to BdsUnixLib...
[mirror_edk2.git] / ArmPkg / Library / ArmLib / ArmV7 / ArmV7Mmu.c
1 /** @file
2 * File managing the MMU for ARMv7 architecture
3 *
4 * Copyright (c) 2011, ARM Limited. All rights reserved.
5 *
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
10 *
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.
13 *
14 **/
15
16 #include <Uefi.h>
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>
22 #include "ArmV7Lib.h"
23 #include "ArmLibPrivate.h"
24
25 VOID
26 FillTranslationTable (
27 IN UINT32 *TranslationTable,
28 IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
29 )
30 {
31 UINT32 *Entry;
32 UINTN Sections;
33 UINTN Index;
34 UINT32 Attributes;
35 UINT32 PhysicalBase = MemoryRegion->PhysicalBase;
36
37 switch (MemoryRegion->Attributes) {
38 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:
39 Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);
40 break;
41 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:
42 Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);
43 break;
44 case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
45 Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);
46 break;
47 case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:
48 Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
49 break;
50 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK:
51 Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);
52 break;
53 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH:
54 Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);
55 break;
56 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE:
57 Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);
58 break;
59 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED:
60 Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);
61 break;
62 default:
63 Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);
64 break;
65 }
66
67 Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);
68 Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;
69
70 for (Index = 0; Index < Sections; Index++) {
71 *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
72 PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
73 }
74 }
75
76 VOID
77 EFIAPI
78 ArmConfigureMmu (
79 IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
80 OUT VOID **TranslationTableBase OPTIONAL,
81 OUT UINTN *TranslationTableSize OPTIONAL
82 )
83 {
84 UINTN TranslationTable;
85 ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;
86 UINT32 TTBRAttributes;
87
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;
91
92 if (TranslationTableBase != NULL) {
93 *TranslationTableBase = (VOID *)TranslationTable;
94 }
95
96 if (TranslationTableBase != NULL) {
97 *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
98 }
99
100 ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
101
102 ArmCleanInvalidateDataCache();
103 ArmInvalidateInstructionCache();
104 ArmInvalidateTlb();
105
106 ArmDisableDataCache();
107 ArmDisableInstructionCache();
108 ArmDisableMmu();
109
110 // Make sure nothing sneaked into the cache
111 ArmCleanInvalidateDataCache();
112 ArmInvalidateInstructionCache();
113
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;
119 }
120
121 FillTranslationTable ((VOID *)TranslationTable, MemoryTable);
122 MemoryTable++;
123 }
124
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;
135 } else {
136 //TODO: We should raise an error here
137 TTBRAttributes = TTBR_NON_CACHEABLE;
138 }
139
140 ArmSetTTBR0 ((VOID *)(UINTN)((TranslationTable & 0xFFFFC000) | (TTBRAttributes & 0x7F)));
141
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));
158
159 ArmEnableInstructionCache();
160 ArmEnableDataCache();
161 ArmEnableMmu();
162 }