1/*-
2 * Copyright 2014 Svatopluk Kraus <onwahe@gmail.com>
3 * Copyright 2014 Michal Meloun <meloun@miracle.cz>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD$
28 */
29
30#ifndef _MACHINE_PTE_V6_H_
31#define _MACHINE_PTE_V6_H_
32
33/*
34 * Domain Types	for the	Domain Access Control Register.
35 */
36#define	DOMAIN_FAULT	0x00	/* no access */
37#define	DOMAIN_CLIENT	0x01	/* client */
38#define	DOMAIN_RESERVED	0x02	/* reserved */
39#define	DOMAIN_MANAGER	0x03	/* manager */
40
41/*
42 * TEX remap registers attributes
43 */
44#define	PRRR_SO		0	/* Strongly ordered memory */
45#define	PRRR_DEV	1	/* Device memory */
46#define	PRRR_MEM	2	/* Normal memory */
47#define	PRRR_DS0	(1 << 16) /* Shared bit for Device, S = 0 */
48#define	PRRR_DS1	(1 << 17) /* Shared bit for Device, S = 1 */
49#define	PRRR_NS0	(1 << 18) /* Shared bit for Normal, S = 0 */
50#define	PRRR_NS1	(1 << 19) /* Shared bit for Normal, S = 1 */
51#define	PRRR_NOS_SHIFT	24 	/* base shif for Not Outer Shared bits */
52
53#define	NMRR_NC		0	/* Noncachable*/
54#define	NMRR_WB_WA	1	/* Write Back, Write Allocate */
55#define	NMRR_WT		2	/* Write Through, Non-Write Allocate */
56#define	NMRR_WB		3	/* Write Back, Non-Write Allocate */
57
58/*
59 *
60 * The ARM MMU is capable of mapping memory in the following chunks:
61 *
62 *	16M	Supersections (L1 table)
63 *
64 *	1M	Sections (L1 table)
65 *
66 *	64K	Large Pages (L2	table)
67 *
68 *	4K	Small Pages (L2	table)
69 *
70 *
71 * Coarse Tables can map Large and Small Pages.
72 * Coarse Tables are 1K in length.
73 *
74 * The Translation Table Base register holds the pointer to the
75 * L1 Table.  The L1 Table is a 16K contiguous chunk of memory
76 * aligned to a 16K boundary.  Each entry in the L1 Table maps
77 * 1M of virtual address space, either via a Section mapping or
78 * via an L2 Table.
79 *
80 */
81#define	L1_TABLE_SIZE	0x4000		/* 16K */
82#define	L1_ENTRIES	0x1000		/*  4K */
83#define	L2_TABLE_SIZE	0x0400		/*  1K */
84#define	L2_ENTRIES	0x0100		/* 256 */
85
86/* ARMv6 super-sections. */
87#define	L1_SUP_SIZE	0x01000000	/* 16M */
88#define	L1_SUP_OFFSET	(L1_SUP_SIZE - 1)
89#define	L1_SUP_FRAME	(~L1_SUP_OFFSET)
90#define	L1_SUP_SHIFT	24
91
92#define	L1_S_SIZE	0x00100000	/* 1M */
93#define	L1_S_OFFSET	(L1_S_SIZE - 1)
94#define	L1_S_FRAME	(~L1_S_OFFSET)
95#define	L1_S_SHIFT	20
96
97#define	L2_L_SIZE	0x00010000	/* 64K */
98#define	L2_L_OFFSET	(L2_L_SIZE - 1)
99#define	L2_L_FRAME	(~L2_L_OFFSET)
100#define	L2_L_SHIFT	16
101
102#define	L2_S_SIZE	0x00001000	/* 4K */
103#define	L2_S_OFFSET	(L2_S_SIZE - 1)
104#define	L2_S_FRAME	(~L2_S_OFFSET)
105#define	L2_S_SHIFT	12
106
107/*
108 * ARM MMU L1 Descriptors
109 */
110#define	L1_TYPE_INV	0x00		/* Invalid (fault) */
111#define	L1_TYPE_C	0x01		/* Coarse L2 */
112#define	L1_TYPE_S	0x02		/* Section */
113#define	L1_TYPE_MASK	0x03		/* Mask	of type	bits */
114
115/* L1 Section Descriptor */
116#define	L1_S_B		0x00000004	/* bufferable Section */
117#define	L1_S_C		0x00000008	/* cacheable Section */
118#define	L1_S_NX		0x00000010	/* not executeable */
119#define	L1_S_DOM(x)	((x) <<	5)	/* domain */
120#define	L1_S_DOM_MASK	L1_S_DOM(0xf)
121#define	L1_S_P		0x00000200	/* ECC enable for this section */
122#define	L1_S_AP(x)	((x) <<	10)	/* access permissions */
123#define	L1_S_AP0	0x00000400	/* access permissions bit 0 */
124#define	L1_S_AP1	0x00000800	/* access permissions bit 1 */
125#define	L1_S_TEX(x)	((x) <<	12)	/* type	extension */
126#define	L1_S_TEX0	0x00001000	/* type	extension bit 0	*/
127#define	L1_S_TEX1	0x00002000	/* type	extension bit 1	*/
128#define	L1_S_TEX2	0x00004000	/* type	extension bit 2	*/
129#define	L1_S_AP2	0x00008000	/* access permissions bit 2 */
130#define	L1_S_SHARED	0x00010000	/* shared */
131#define	L1_S_NG		0x00020000	/* not global */
132#define	L1_S_SUPERSEC	0x00040000	/* Section is a	super-section. */
133#define	L1_S_ADDR_MASK	0xfff00000	/* phys	address	of section */
134
135/* L1 Coarse Descriptor	*/
136#define	L1_C_DOM(x)	((x) <<	5)	/* domain */
137#define	L1_C_DOM_MASK	L1_C_DOM(0xf)
138#define	L1_C_P		0x00000200	/* ECC enable for this section */
139#define	L1_C_ADDR_MASK	0xfffffc00	/* phys	address	of L2 Table */
140
141/*
142 * ARM MMU L2 Descriptors
143 */
144#define	L2_TYPE_INV	0x00		/* Invalid (fault) */
145#define	L2_TYPE_L	0x01		/* Large Page  - 64k - not used yet*/
146#define	L2_TYPE_S	0x02		/* Small Page  - 4 */
147#define	L2_TYPE_MASK	0x03
148
149#define	L2_NX		0x00000001	/* Not executable */
150#define	L2_B		0x00000004	/* Bufferable page */
151#define	L2_C		0x00000008	/* Cacheable page */
152#define	L2_AP(x)	((x) <<	4)
153#define	L2_AP0		0x00000010	/* access permissions bit 0*/
154#define	L2_AP1		0x00000020	/* access permissions bit 1*/
155#define	L2_TEX(x)	((x) <<	6)	/* type	extension */
156#define	L2_TEX0		0x00000040	/* type	extension bit 0	*/
157#define	L2_TEX1		0x00000080	/* type	extension bit 1	*/
158#define	L2_TEX2		0x00000100	/* type	extension bit 2	*/
159#define	L2_AP2		0x00000200	/* access permissions  bit 2*/
160#define	L2_SHARED	0x00000400	/* shared */
161#define	L2_NG		0x00000800	/* not global */
162
163/*
164 * TEX classes encoding
165 */
166#define	TEX1_CLASS_0	 (			    0)
167#define	TEX1_CLASS_1	 (		       L1_S_B)
168#define	TEX1_CLASS_2	 (	      L1_S_C	     )
169#define	TEX1_CLASS_3	 (	      L1_S_C | L1_S_B)
170#define	TEX1_CLASS_4	 (L1_S_TEX0		     )
171#define	TEX1_CLASS_5	 (L1_S_TEX0 |	       L1_S_B)
172#define	TEX1_CLASS_6	 (L1_S_TEX0 | L1_S_C	     )	/* Reserved for	ARM11 */
173#define	TEX1_CLASS_7	 (L1_S_TEX0 | L1_S_C | L1_S_B)
174
175#define	TEX2_CLASS_0	 (		      0)
176#define	TEX2_CLASS_1	 (		   L2_B)
177#define	TEX2_CLASS_2	 (	    L2_C       )
178#define	TEX2_CLASS_3	 (	    L2_C | L2_B)
179#define	TEX2_CLASS_4	 (L2_TEX0	       )
180#define	TEX2_CLASS_5	 (L2_TEX0 |	   L2_B)
181#define	TEX2_CLASS_6	 (L2_TEX0 | L2_C       )	/* Reserved for	ARM11 */
182#define	TEX2_CLASS_7	 (L2_TEX0 | L2_C | L2_B)
183
184/* L1 table definitions. */
185#define	NB_IN_PT1	L1_TABLE_SIZE
186#define	NPTE1_IN_PT1	L1_ENTRIES
187
188/* L2 table definitions. */
189#define	NB_IN_PT2	L2_TABLE_SIZE
190#define	NPTE2_IN_PT2	L2_ENTRIES
191
192/*
193 * Map memory attributes to TEX	classes
194 */
195#define	PTE2_ATTR_WB_WA		TEX2_CLASS_0
196#define	PTE2_ATTR_NOCACHE	TEX2_CLASS_1
197#define	PTE2_ATTR_DEVICE	TEX2_CLASS_2
198#define	PTE2_ATTR_SO		TEX2_CLASS_3
199#define	PTE2_ATTR_WT		TEX2_CLASS_4
200/*
201 * Software defined bits for L1	descriptors
202 *  - L1_AP0 is	used as	page accessed bit
203 *  - L1_AP2 (RO / not RW) is used as page not modified	bit
204 *  - L1_TEX0 is used as software emulated RO bit
205 */
206#define	PTE1_V		L1_TYPE_S	/* Valid bit */
207#define	PTE1_A		L1_S_AP0	/* Accessed - software emulated	*/
208#define	PTE1_NM		L1_S_AP2	/* not modified	bit - software emulated
209					 * used	as real	write enable bit */
210#define	PTE1_M		0		/* Modified (dummy) */
211#define	PTE1_S		L1_S_SHARED	/* Shared */
212#define	PTE1_NG		L1_S_NG		/* Not global */
213#define	PTE1_G		0		/* Global (dummy) */
214#define	PTE1_NX		L1_S_NX		/* Not executable */
215#define	PTE1_X		0		/* Executable (dummy) */
216#define	PTE1_RO		L1_S_TEX1	/* Read	Only */
217#define	PTE1_RW		0		/* Read-Write (dummy) */
218#define	PTE1_U		L1_S_AP1	/* User	*/
219#define	PTE1_NU		0		/* Not user (kernel only) (dummy) */
220#define	PTE1_W		L1_S_TEX2	/* Wired */
221
222#define	PTE1_SHIFT	L1_S_SHIFT
223#define	PTE1_SIZE	L1_S_SIZE
224#define	PTE1_OFFSET	L1_S_OFFSET
225#define	PTE1_FRAME	L1_S_FRAME
226
227#define	PTE1_ATTR_MASK	(L1_S_TEX0 | L1_S_C | L1_S_B)
228
229#define	PTE1_AP_KR	(PTE1_RO | PTE1_NM)
230#define	PTE1_AP_KRW	0
231#define	PTE1_AP_KRUR	(PTE1_RO | PTE1_NM | PTE1_U)
232#define	PTE1_AP_KRWURW	PTE1_U
233
234/*
235 * PTE1	descriptors creation macros.
236 */
237#define	PTE1_PA(pa)	((pa) &	PTE1_FRAME)
238#define	PTE1_AP_COMMON	(PTE1_V	| PTE1_S)
239
240#define	PTE1(pa, ap, attr)	(PTE1_PA(pa) | (ap) | (attr) | PTE1_AP_COMMON)
241
242#define	PTE1_KERN(pa, ap, attr)		PTE1(pa, (ap) |	PTE1_A | PTE1_G, attr)
243#define	PTE1_KERN_NG(pa, ap, attr)	PTE1(pa, (ap) |	PTE1_A | PTE1_NG, attr)
244
245#define	PTE1_LINK(pa)	(((pa) & L1_C_ADDR_MASK) | L1_TYPE_C)
246
247/*
248 * Software defined bits for L2	descriptors
249 *  - L2_AP0 is	used as	page accessed bit
250 *  - L2_AP2 (RO / not RW) is used as page not modified	bit
251 *  - L2_TEX0 is used as software emulated RO bit
252 */
253#define	PTE2_V		L2_TYPE_S	/* Valid bit */
254#define	PTE2_A		L2_AP0		/* Accessed - software emulated	*/
255#define	PTE2_NM		L2_AP2		/* not modified	bit - software emulated
256					 * used	as real	write enable bit */
257#define	PTE2_M		0		/* Modified (dummy) */
258#define	PTE2_S		L2_SHARED	/* Shared */
259#define	PTE2_NG		L2_NG		/* Not global */
260#define	PTE2_G		0		/* Global (dummy) */
261#define	PTE2_NX		L2_NX		/* Not executable */
262#define	PTE2_X		0		/* Not executable (dummy) */
263#define	PTE2_RO		L2_TEX1		/* Read	Only */
264#define	PTE2_U		L2_AP1		/* User	*/
265#define	PTE2_NU		0		/* Not user (kernel only) (dummy) */
266#define	PTE2_W		L2_TEX2		/* Wired */
267
268#define	PTE2_SHIFT	L2_S_SHIFT
269#define	PTE2_SIZE	L2_S_SIZE
270#define	PTE2_OFFSET	L2_S_OFFSET
271#define	PTE2_FRAME	L2_S_FRAME
272
273#define	PTE2_ATTR_MASK		(L2_TEX0 | L2_C | L2_B)
274
275#define	PTE2_AP_KR	(PTE2_RO | PTE2_NM)
276#define	PTE2_AP_KRW	0
277#define	PTE2_AP_KRUR	(PTE2_RO | PTE2_NM | PTE2_U)
278#define	PTE2_AP_KRWURW	PTE2_U
279
280/*
281 * PTE2	descriptors creation macros.
282 */
283#define	PTE2_PA(pa)	((pa) &	PTE2_FRAME)
284#define	PTE2_AP_COMMON	(PTE2_V	| PTE2_S)
285
286#define	PTE2(pa, ap, attr)	(PTE2_PA(pa) | (ap) | (attr) | PTE2_AP_COMMON)
287
288#define	PTE2_KERN(pa, ap, attr)		PTE2(pa, (ap) |	PTE2_A | PTE2_G, attr)
289#define	PTE2_KERN_NG(pa, ap, attr)	PTE2(pa, (ap) |	PTE2_A | PTE2_NG, attr)
290
291#endif /* !_MACHINE_PTE_V6_H_ */
292