1 /*
2 * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5 /*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14 #ifndef __ARM_ARCH_MMU_H
15 #define __ARM_ARCH_MMU_H
16
17 #include <linux/types.h>
18 #ifdef CONFIG_ARCH_MMU
19 /*
20 * Translation Table Base Bit Masks
21 */
22 #define ARM_TRANSLATION_TABLE_MASK 0xFFFFC000
23
24 /*
25 * Domain Access Control Bit Masks
26 */
27 #define arm_access_type_no_access(domain_num) (0x0 << (domain_num)*2)
28 #define arm_access_type_client(domain_num) (0x1 << (domain_num)*2)
29 #define arm_access_type_manager(domain_num) (0x3 << (domain_num)*2)
30
31
32 #define ARM_MMU_FIRST_LEVEL_FAULT_ID 0x0
33
34 struct arm_mmu_first_level_fault {
35 unsigned int id: 2;
36 unsigned int sbz: 30;
37 };
38
39 #define ARM_MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1
40
41 struct arm_mmu_first_level_page_table {
42 unsigned int id: 2;
43 unsigned int sbz0: 1;
44 unsigned int ns: 1;
45 unsigned int sbz1: 1;
46 unsigned int domain: 4;
47 unsigned int imp: 1;
48 unsigned int base_address: 22;
49 };
50
51 #define ARM_MMU_FIRST_LEVEL_SECTION_ID 0x2
52
53 struct arm_mmu_first_level_section {
54 unsigned int id: 2;
55 unsigned int b: 1;
56 unsigned int c: 1;
57 unsigned int xn: 1;
58 unsigned int domain: 4;
59 unsigned int imp: 1;
60 unsigned int ap0: 2;
61 unsigned int tex: 3;
62 unsigned int ap1: 1;
63 unsigned int s: 1;
64 unsigned int ng: 1;
65 unsigned int reserved: 1;
66 unsigned int ns: 1;
67 unsigned int base_address: 12;
68 };
69
70 struct arm_mmu_first_level_reserved {
71 unsigned int id: 2;
72 unsigned int sbz: 30;
73 };
74
75 #define ARM_MMU_SECOND_LEVEL_FAULT_ID 0x0
76
77 struct arm_mmu_second_level_fault {
78 unsigned int id: 2;
79 unsigned int sbz: 30;
80 };
81
82 #define ARM_MMU_SECOND_LEVEL_SMALL_ID 0x2
83
84 struct arm_mmu_second_level_small {
85 unsigned int id: 2;
86 unsigned int b: 1;
87 unsigned int c: 1;
88 unsigned int ap0: 2;
89 unsigned int tex: 3;
90 unsigned int ap1: 1;
91 unsigned int s: 1;
92 unsigned int ng: 1;
93 unsigned int base_address: 20;
94 };
95
96 #define ARM_MMU_FIRST_LEVEL_RESERVED_ID 0x3
97
98 #define arm_mmu_first_level_descriptor_address(ttb_base, table_index) \
99 (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2))
100
101 #define ARM_FIRST_LEVEL_PAGE_TABLE_SIZE 0x4000
102
103 union arm_mmu_first_level_descriptor {
104 unsigned long word;
105 struct arm_mmu_first_level_fault fault;
106 struct arm_mmu_first_level_page_table page_table;
107 struct arm_mmu_first_level_section section;
108 struct arm_mmu_first_level_reserved reserved;
109 };
110
111 union arm_mmu_second_level_descriptor {
112 unsigned long word;
113 struct arm_mmu_second_level_fault fault;
114 struct arm_mmu_second_level_small small;
115 };
116
arm_mmu_section(int ttb_base,int actual_base,int virtual_base,unsigned int tex,unsigned int cacheable,unsigned int bufferable,unsigned int perm,unsigned int shareable)117 static inline void arm_mmu_section(int ttb_base, int actual_base,
118 int virtual_base, unsigned int tex, unsigned int cacheable,
119 unsigned int bufferable, unsigned int perm,
120 unsigned int shareable)
121 {
122 register union arm_mmu_first_level_descriptor desc;
123
124 desc.word = 0;
125 desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID;
126 desc.section.c = cacheable;
127 desc.section.b = bufferable;
128 desc.section.xn = 0;
129 desc.section.domain = 0;
130 desc.section.ap0 = perm;
131 desc.section.tex = tex;
132 desc.section.ap1 = 0;
133 desc.section.s = shareable;
134 desc.section.base_address = actual_base;
135 *arm_mmu_first_level_descriptor_address(ttb_base, (virtual_base))
136 = desc.word;
137 }
138
x_arm_mmu_section(int abase,int vbase,int size,unsigned int tex,unsigned int cache,unsigned int buff,unsigned int access,unsigned int shareable)139 static inline void x_arm_mmu_section(int abase, int vbase, int size,
140 unsigned int tex, unsigned int cache, unsigned int buff,
141 unsigned int access, unsigned int shareable)
142 {
143 int i;
144 int j = abase;
145 int k = vbase;
146 unsigned long ttb_base = CONFIG_TTB_ADDR;
147
148 for (i = size; i > 0 ; i--, j++, k++)
149 arm_mmu_section(ttb_base, j, k, tex, cache,
150 buff, access, shareable);
151 }
152
153 #define ARM_UNCACHEABLE 0
154 #define ARM_CACHEABLE 1
155 #define ARM_UNBUFFERABLE 0
156 #define ARM_BUFFERABLE 1
157
158 #define ARM_ACCESS_PERM_NONE_NONE 0
159 #define ARM_ACCESS_PERM_RW_NONE 1
160 #define ARM_ACCESS_PERM_RW_RO 2
161 #define ARM_ACCESS_PERM_RW_RW 3
162
163 #define ARM_NOSHAREABLE 0
164 #define ARM_SHAREABLE 1
165
166 #define ARM_MEMTYPE_STRONGORDER 0
167 #define ARM_MEMTYPE_DEVICE 1
168 #define ARM_MEMTYPE_NORMAL 2
169 #define ARM_MEMTYPE_RESERVED 3
170
171
172 #define ARM_CACHETYPE_NOCACHE 0
173 #define ARM_CACHETYPE_WRITEBACK 1
174 #define ARM_CACHETYPE_WRITETHROUGH 2
175 #define ARM_CACHETYPE_WRITEBACK_ONLY 3
176
177
178 /*
179 * Initialization for the Domain Access Control Register
180 */
181 #define ARM_ACCESS_DACR_DEFAULT ( \
182 arm_access_type_manager(0) | \
183 arm_access_type_no_access(1) | \
184 arm_access_type_no_access(2) | \
185 arm_access_type_no_access(3) | \
186 arm_access_type_no_access(4) | \
187 arm_access_type_no_access(5) | \
188 arm_access_type_no_access(6) | \
189 arm_access_type_no_access(7) | \
190 arm_access_type_no_access(8) | \
191 arm_access_type_no_access(9) | \
192 arm_access_type_no_access(10) | \
193 arm_access_type_no_access(11) | \
194 arm_access_type_no_access(12) | \
195 arm_access_type_no_access(13) | \
196 arm_access_type_no_access(14) | \
197 arm_access_type_no_access(15))
198
199 #endif
200 #endif
201