| 1 | /*	$NetBSD: mmu_40.h,v 1.4 2025/07/08 11:45:25 thorpej 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 | /* |
| 216 | * TT register value indices in the mmu_ttregs[] array. Note that asm |
| 217 | * code makes assumptions about these indices, to change them at your |
| 218 | * peril. |
| 219 | */ |
| 220 | extern uint32_t mmu_tt40[]; |
| 221 | #define	MMU_TTREG_ITT0	0	/* same order as CPU reg numbers */ |
| 222 | #define	MMU_TTREG_ITT1	1 |
| 223 | #define	MMU_TTREG_DTT0	2 |
| 224 | #define	MMU_TTREG_DTT1	3 |
| 225 | #define	MMU_NTTREGS40 |
| 226 | |
| 227 | void	mmu_load_urp40(paddr_t); |
| 228 | void	mmu_load_urp60(paddr_t); |
| 229 | void	mmu_load_tt40(uint32_t *); |
| 230 | #endif /* _KERNEL */ |
| 231 | |
| 232 | #endif /* _M68K_MMU_40_H_ */ |