1 /*        $NetBSD: mmu_40.h,v 1.3 2024/02/09 22:08:32 andvar Exp $    */
2 
3 /*-
4  * Copyright (c) 2023 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _M68K_MMU_40_H_
33 #define   _M68K_MMU_40_H_
34 
35 /*
36  * Translation table structures for the 68040 MMU.
37  *
38  * The 68040 MMU uses a 3-level tree structure.  The root (L1) and
39  * and pointer (L2) tables contain the base addresses of the tables
40  * at the lext level, and the page (L3) tables contain the addresses
41  * of the page descriptors, which may either contain the address of
42  * a physical page (4K or 8K) directly, or point to an indirect
43  * descriptor which points to the physical page.
44  *
45  * The L1 and L2 tables contain 128 4-byte descriptors, and are thus 512
46  * bytes in size.  Each of the 128 L1 descriptors corresponds to a 32MB
47  * region of address space.  Each of the 128 L2 descriptors corresponds
48  * to a 256KB region of address space.
49  *
50  * For 8K pages, the L3 tables contain 32 4-byte descriptors, and are
51  * thus 128 bytes in size.
52  *
53  *  31          25 24          18 17      13 12                       0
54  * |              |              |          |                          |
55  *  11111111111111 22222222222222 3333333333 ..........................
56  *       Root         Pointer        Page               Page
57  *       Index         Index         Index             Offset
58  *
59  * For 4K pages, the L3 tables contain 64 4-byte descriptors, and are
60  * thus 256 bytes in size.
61  *
62  *  31          25 24          18 17        12 11                     0
63  * |              |              |            |                        |
64  *  11111111111111 22222222222222 333333333333 ........................
65  *       Root         Pointer         Page              Page
66  *       Index         Index          Index            Offset
67  *
68  *                       Logical Address Format
69  */
70 
71 #define   LA40_L1_NBITS       7U
72 #define   LA40_L1_SHIFT       25
73 #define   LA40_L2_NBITS       7U
74 #define   LA40_L2_SHIFT       18
75 #define   LA40_L3_NBITS       (32U - LA40_L1_NBITS - LA40_L2_NBITS - PGSHIFT)
76 #define   LA40_L3_SHIFT       PGSHIFT
77 
78 #define   LA40_L1_COUNT       __BIT(LA40_L1_NBITS)
79 #define   LA40_L2_COUNT       __BIT(LA40_L2_NBITS)
80 #define   LA40_L3_COUNT       __BIT(LA40_L3_NBITS)
81 
82 #define   LA40_L1_MASK        (__BITS(0,(LA40_L1_NBITS - 1)) << LA40_L1_SHIFT)
83 #define   LA40_L2_MASK        (__BITS(0,(LA40_L2_NBITS - 1)) << LA40_L2_SHIFT)
84 #define   LA40_L3_MASK        (__BITS(0,(LA40_L3_NBITS - 1)) << LA40_L3_SHIFT)
85 
86 /* N.B. all tables must be aligned to their size */
87 #define   TBL40_L1_SIZE       (LA40_L1_COUNT * sizeof(uint32_t))
88 #define   TBL40_L2_SIZE       (LA40_L2_COUNT * sizeof(uint32_t))
89 #define   TBL40_L3_SIZE       (LA40_L3_COUNT * sizeof(uint32_t))
90 
91 #define   LA40_RI(va)         __SHIFTOUT((va), LA40_L1_MASK)          /* root index */
92 #define   LA40_PI(va)         __SHIFTOUT((va), LA40_L2_MASK)          /* pointer index */
93 #define   LA40_PGI(va)        __SHIFTOUT((va), LA40_L3_MASK)          /* page index */
94 
95 #define   LA40_TRUNC_L1(va) (((vaddr_t)(va)) & LA40_L1_MASK)
96 #define   LA40_TRUNC_L2(va) (((vaddr_t)(va)) & (LA40_L1_MASK | LA40_L2_MASK))
97 
98 /*
99  * The PTE format for L1 and L2 tables (Upper Tables).
100  */
101 #define   UTE40_PTA __BITS(9,31)        /* Pointer Table Address (L1 PTE) */
102                                                   /* Page Table Address (L2 PTE) */
103 #define   UTE40_PGTA          __BITS(8 - (13 - PGSHIFT),31)
104 #define   UTE40_U             __BIT(3)  /* Used (referenced) */
105 #define   UTE40_W             __BIT(2)  /* Write Protected */
106 #define   UTE40_UDT __BITS(0,1)         /* Upper Descriptor Type */
107                                                   /* 00 or 01 -- Invalid */
108                                                   /* 10 or 11 -- Resident */
109 
110 #define   UTE40_INVALID       __SHIFTIN(0, UTE_UDT)
111 #define   UTE40_RESIDENT      __SHIFTIN(2, UTE_UDT)
112 
113 /*
114  * The PTE format for L3 tables.
115  *
116  * Some notes:
117  *
118  * - PFLUSH variants that specify non-global entries do not invalidate
119  *   global entries.  If these PFLUSH variants are not used, then the G
120  *   bit can be used as a software-defined bit.
121  *
122  * - The UR bits are "reserved for use by the user", so can be
123  *   used as software-defined bits.
124  *
125  * - The U0 and U1 "User Page Attribute" bits should *not* be used
126  *   as software-defined bits; they are reflected on the UPA0 and UPA1
127  *   CPU signals if an external bus transfer results from the access,
128  *   meaning that they may have system-specific side-effects.
129  */
130 #define   PTE40_PGA __BITS(PGSHIFT,31) /* Page Physical Address */
131 #define   PTE40_UR_x          __BIT(12) /* User Reserved (extra avail if 8K) */
132 #define   PTE40_UR  __BIT(11) /* User Reserved */
133 #define   PTE40_G             __BIT(10) /* Global */
134 #define   PTE40_U1  __BIT(9)  /* User Page Attribute 1 */
135 #define   PTE40_U0  __BIT(8)  /* User Page Attribute 0 */
136 #define   PTE40_S             __BIT(7)  /* Supervisor Protected */
137 #define   PTE40_CM  __BITS(5,6)         /* Cache Mode */
138                                                   /* 00 -- write-through */
139                                                   /* 01 -- copy-back */
140                                                   /* 10 -- non-cacheable, serialized */
141                                                   /* 11 -- non-cacheable */
142 #define   PTE40_M             __BIT(4)  /* Modified */
143 #define   PTE40_U             __BIT(3)  /* Used (referenced) */
144 #define   PTE40_W             __BIT(2)  /* Write Protected */
145 #define   PTE40_PDT __BITS(0,1)         /* Page Descriptor Type */
146                                                   /* 00       -- Invalid */
147                                                   /* 01 or 11 -- Resident */
148                                                   /* 10       -- Indirect */
149 
150 #define   PTE40_CM_WT         __SHIFTIN(0, PTE40_CM)
151 #define   PTE40_CM_CB         __SHIFTIN(1, PTE40_CM)
152 #define   PTE40_CM_NC_SER     __SHIFTIN(2, PTE40_CM)
153 #define   PTE40_CM_NC         __SHIFTIN(3, PTE40_CM)
154 
155 #define   PTE40_INVALID       __SHIFTIN(0, PTE40_PDT)
156 #define   PTE40_RESIDENT      __SHIFTIN(1, PTE40_PDT)
157 #define   PTE40_INDIRECT      __SHIFTIN(2, PTE40_PDT)
158 
159 /*
160  * MMU registers (and the sections in the 68040 manual that
161  * describe them).
162  */
163 
164 /*
165  * 3.1.1 -- User and Supervisor Root Pointer Registers (32-bit)
166  *
167  * URP and SRP contain the physical address of the L1 table for
168  * user and supervisor space, respectively.  Bits 8-0 of the address
169  * must be 0.
170  */
171 
172 /*
173  * 3.1.2 -- Translation Control Register (16-bit)
174  */
175 #define   TCR40_E             __BIT(15) /* enable translation */
176 #define   TCR40_P             __BIT(14) /* page size: 0=4K 1=8K */
177 
178 /*
179  * 3.1.3 -- Transparent Translation Registers (32-bit)
180  *
181  * There are 2 data translation registers (DTTR0, DTTR1) and 2
182  * instruction translation registers (ITTR0, ITTR1).
183  */
184 #define   TTR40_LAB __BITS(24,31)       /* logical address base */
185 #define   TTR40_LAM __BITS(16,23)       /* logical address mask */
186 #define   TTR40_E             __BIT(15) /* enable TTR */
187 #define   TTR40_SFIELD        __BITS(13,14)       /* Supervisor Mode field (see below) */
188 #define   TTR40_U1  PTE40_U1
189 #define   TTR40_U0  PTE40_U0
190 #define   TTR40_CM  PTE40_CM
191 #define   TTR40_W             PTE40_W
192 
193 #define   TTR40_USER          __SHIFTIN(0, TTR40_SFIELD)
194 #define   TTR40_SUPER         __SHIFTIN(1, TTR40_SFIELD)
195 #define   TTR40_BOTH          __SHIFTIN(2, TTR40_SFIELD)
196 
197 /*
198  * 3.1.4 -- MMU Status Register
199  *
200  * N.B. If 8K pages are in use, bit 12 of the PA field is **undefined**.
201  */
202 #define   MMUSR40_PA          PTE40_PGA
203 #define   MMUSR40_B __BIT(11) /* bus error */
204 #define   MMUSR40_G PTE40_G
205 #define   MMUSR40_U1          PTE40_U1
206 #define   MMUSR40_U0          PTE40_U0
207 #define   MMUSR40_S PTE40_S
208 #define   MMUSR40_CM          PTE40_CM
209 #define   MMUSR40_M PTE40_M
210 #define   MMUSR40_W PTE40_W
211 #define   MMUSR40_T __BIT(1)  /* Transparent Translation hit */
212 #define   MMUSR40_R PTE40_RESIDENT
213 
214 #ifdef _KERNEL
215 void      mmu_load_urp40(paddr_t);
216 void      mmu_load_urp60(paddr_t);
217 #endif /* _KERNEL */
218 
219 #endif /* _M68K_MMU_40_H_ */
220