]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Library/ArmLib/ArmV7/ArmV7Mmu.c
ArmPkg/PL180MciDxe: Improve error handling
[mirror_edk2.git] / ArmPkg / Library / ArmLib / ArmV7 / ArmV7Mmu.c
CommitLineData
1bfda055 1/** @file\r
2* File managing the MMU for ARMv7 architecture\r
3*\r
4* Copyright (c) 2011, ARM Limited. All rights reserved.\r
5* \r
6* This program and the accompanying materials \r
7* are licensed and made available under the terms and conditions of the BSD License \r
8* which accompanies this distribution. The full text of the license may be found at \r
9* http://opensource.org/licenses/bsd-license.php \r
10*\r
11* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13*\r
14**/\r
15\r
16#include <Uefi.h> \r
17#include <Chipset/ArmV7.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/ArmLib.h>\r
21#include <Library/BaseLib.h>\r
22#include "ArmV7Lib.h"\r
23#include "ArmLibPrivate.h"\r
24\r
25VOID\r
26FillTranslationTable (\r
27 IN UINT32 *TranslationTable,\r
28 IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion\r
29 )\r
30{\r
31 UINT32 *Entry;\r
32 UINTN Sections;\r
33 UINTN Index;\r
34 UINT32 Attributes;\r
35 UINT32 PhysicalBase = MemoryRegion->PhysicalBase;\r
36 \r
37 switch (MemoryRegion->Attributes) {\r
38 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK:\r
39 Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(0);\r
40 break;\r
41 case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH:\r
42 Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(0);\r
43 break;\r
44 case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:\r
45 Attributes = TT_DESCRIPTOR_SECTION_DEVICE(0);\r
46 break;\r
47 case ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED:\r
48 Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);\r
49 break;\r
50 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK:\r
51 Attributes = TT_DESCRIPTOR_SECTION_WRITE_BACK(1);\r
52 break;\r
53 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH:\r
54 Attributes = TT_DESCRIPTOR_SECTION_WRITE_THROUGH(1);\r
55 break;\r
56 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_DEVICE:\r
57 Attributes = TT_DESCRIPTOR_SECTION_DEVICE(1);\r
58 break;\r
59 case ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED:\r
60 Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(1);\r
61 break;\r
62 default:\r
63 Attributes = TT_DESCRIPTOR_SECTION_UNCACHED(0);\r
64 break;\r
65 }\r
66 \r
67 Entry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase);\r
68 Sections = MemoryRegion->Length / TT_DESCRIPTOR_SECTION_SIZE;\r
69 \r
70 for (Index = 0; Index < Sections; Index++) {\r
71 *Entry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;\r
72 PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;\r
73 }\r
74}\r
75\r
76VOID\r
77EFIAPI\r
78ArmConfigureMmu (\r
79 IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,\r
80 OUT VOID **TranslationTableBase OPTIONAL,\r
81 OUT UINTN *TranslationTableSize OPTIONAL\r
82 )\r
83{\r
84 UINTN TranslationTable;\r
85 ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;\r
86 UINT32 TTBRAttributes;\r
87\r
88 // Allocate pages for translation table.\r
89 TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));\r
90 TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK;\r
91\r
92 if (TranslationTableBase != NULL) {\r
93 *TranslationTableBase = (VOID *)TranslationTable;\r
94 }\r
95 \r
96 if (TranslationTableBase != NULL) {\r
97 *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;\r
98 }\r
99\r
100 ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);\r
101\r
102 ArmCleanInvalidateDataCache();\r
103 ArmInvalidateInstructionCache();\r
104 ArmInvalidateTlb();\r
105\r
106 ArmDisableDataCache();\r
107 ArmDisableInstructionCache();\r
108 ArmDisableMmu();\r
109\r
110 // Make sure nothing sneaked into the cache\r
111 ArmCleanInvalidateDataCache();\r
112 ArmInvalidateInstructionCache();\r
113\r
114 TranslationTableAttribute = 0;\r
115 while (MemoryTable->Length != 0) {\r
116 // Find the memory attribute for the Translation Table\r
117 if ((TranslationTable >= MemoryTable->PhysicalBase) && (TranslationTable < MemoryTable->PhysicalBase + MemoryTable->Length)) {\r
118 TranslationTableAttribute = MemoryTable->Attributes;\r
119 }\r
120\r
121 FillTranslationTable ((VOID *)TranslationTable, MemoryTable);\r
122 MemoryTable++;\r
123 }\r
124\r
125 // Translate the Memory Attributes into Translation Table Register Attributes\r
126 if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED) || \r
127 (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_UNCACHED_UNBUFFERED)) {\r
128 TTBRAttributes = TTBR_NON_CACHEABLE;\r
129 } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) || \r
130 (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_BACK)) {\r
131 TTBRAttributes = TTBR_WRITE_BACK_ALLOC;\r
132 } else if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_THROUGH) || \r
133 (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_SECURE_WRITE_THROUGH)) {\r
134 TTBRAttributes = TTBR_WRITE_THROUGH_NO_ALLOC;\r
135 } else {\r
136 //TODO: We should raise an error here\r
137 TTBRAttributes = TTBR_NON_CACHEABLE;\r
138 }\r
139\r
140 ArmSetTTBR0 ((VOID *)(UINTN)((TranslationTable & 0xFFFFC000) | (TTBRAttributes & 0x7F)));\r
141 \r
142 ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) |\r
143 DOMAIN_ACCESS_CONTROL_NONE(14) |\r
144 DOMAIN_ACCESS_CONTROL_NONE(13) |\r
145 DOMAIN_ACCESS_CONTROL_NONE(12) |\r
146 DOMAIN_ACCESS_CONTROL_NONE(11) |\r
147 DOMAIN_ACCESS_CONTROL_NONE(10) |\r
148 DOMAIN_ACCESS_CONTROL_NONE( 9) |\r
149 DOMAIN_ACCESS_CONTROL_NONE( 8) |\r
150 DOMAIN_ACCESS_CONTROL_NONE( 7) |\r
151 DOMAIN_ACCESS_CONTROL_NONE( 6) |\r
152 DOMAIN_ACCESS_CONTROL_NONE( 5) |\r
153 DOMAIN_ACCESS_CONTROL_NONE( 4) |\r
154 DOMAIN_ACCESS_CONTROL_NONE( 3) |\r
155 DOMAIN_ACCESS_CONTROL_NONE( 2) |\r
156 DOMAIN_ACCESS_CONTROL_NONE( 1) |\r
157 DOMAIN_ACCESS_CONTROL_MANAGER(0));\r
158 \r
159 ArmEnableInstructionCache();\r
160 ArmEnableDataCache();\r
161 ArmEnableMmu();\r
162}\r