1/* $NetBSD: pte_coldfire.h,v 1.1.2.2 2013/07/23 21:07:34 riastradh Exp $ */ 2/*- 3 * Copyright (c) 2013 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Matt Thomas of 3am Software Foundry. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#ifndef _M68K_PTE_COLDFIRE_H_ 32#define _M68K_PTE_COLDFIRE_H_ 33 34#ifdef __ASSEMBLY__ 35#error use assym.h instead 36#endif 37 38#ifndef __BSD_PT_ENTRY_T 39#define __BSD_PT_ENTRY_T __uint32_t 40typedef __BSD_PT_ENTRY_T pt_entry_t; 41#endif 42 43#define MMUTR_VA __BITS(31,10) // Virtual Address 44#define MMUTR_ID __BITS(9,2) // ASID 45#define MMUTR_SG __BIT(1) // Shared Global 46#define MMUTR_V __BIT(0) // Valid 47 48#define MMUDR_PA __BITS(31,10) // Physical Address 49#define MMUDR_SZ __BITS(9,8) // Entry Size 50#define MMUDR_SZ_1MB 0 51#define MMUDR_SZ_4KB 1 52#define MMUDR_SZ_8KB 2 53#define MMUDR_SZ_16MB 3 54#define MMUDR_CM __BITS(7,6) // Cache Mode 55#define MMUDR_CM_WT 0 // Write-Through 56#define MMUDR_CM_WB 1 // Write-Back (Copy-Back) 57#define MMUDR_CM_NC 2 // Non-cacheable 58#define MMUDR_CM_NCP 2 // Non-cacheable Precise 59#define MMUDR_CM_NCI 3 // Non-cacheable Imprecise 60#define MMUDR_SP __BIT(5) // Supervisor Protect 61#define MMUDR_R __BIT(4) // Read Access 62#define MMUDR_W __BIT(3) // Write Access 63#define MMUDR_X __BIT(2) // Execute Access 64#define MMUDR_LK __BIT(1) // Lock Entry 65#define MMUDR_MBZ0 __BIT(0) // Must be zero 66 67/* 68 * The PTE basically the contents of MMUDR[31:2] | MMUAR[0]. 69 * We overload the meaning of MMUDR_LK for indicating wired. 70 * It will be cleared before writing to the TLB. 71 */ 72 73#ifdef _KERNEL 74 75static inline bool 76pte_cached_p(pt_entry_t pt_entry) 77{ 78 return (pt_entry & MMUDR_CM_NC) != MMUDR_CM_NC; 79} 80 81static inline bool 82pte_modified_p(pt_entry_t pt_entry) 83{ 84 return (pt_entry & MMUDR_W) == MMUDR_W; 85} 86 87static inline bool 88pte_valid_p(pt_entry_t pt_entry) 89{ 90 return (pt_entry & MMUAR_V) == MMUAR_V; 91} 92 93static inline bool 94pte_exec_p(pt_entry_t pt_entry) 95{ 96 return (pt_entry & MMUDR_X) == MMUDR_X; 97} 98 99static inline bool 100pte_deferred_exec_p(pt_entry_t pt_entry) 101{ 102 return !pte_exec_p(pt_entry); 103} 104 105static inline bool 106pte_wired_p(pt_entry_t pt_entry) 107{ 108 return (pt_entry & MMUDR_LK) == MMUDR_LK; 109} 110 111static inline pt_entry_t 112pte_nv_entry(bool kernel) 113{ 114 return 0; 115} 116 117static inline paddr_t 118pte_to_paddr(pt_entry_t pt_entry) 119{ 120 return (paddr_t)(pt_entry & MMUDR_PA); 121} 122 123static inline pt_entry_t 124pte_ionocached_bits(void) 125{ 126 return MMUDR_CM_NCP; 127} 128 129static inline pt_entry_t 130pte_iocached_bits(void) 131{ 132 return MMUDR_CM_NCP; 133} 134 135static inline pt_entry_t 136pte_nocached_bits(void) 137{ 138 return MMUDR_CM_NCP; 139} 140 141static inline pt_entry_t 142pte_cached_bits(void) 143{ 144 return MMUDR_CM_WB; 145} 146 147static inline pt_entry_t 148pte_cached_change(pt_entry_t pt_entry, bool cached) 149{ 150 return (pt_entry & ~MMUDR_CM) | (cached ? MMUDR_CM_WB : MMUDR_CM_NCP); 151} 152 153static inline pt_entry_t 154pte_wire_entry(pt_entry_t pt_entry) 155{ 156 return pt_entry | MMUDR_LK; 157} 158 159static inline pt_entry_t 160pte_unwire_entry(pt_entry_t pt_entry) 161{ 162 return pt_entry & ~MMUDR_LK; 163} 164 165static inline pt_entry_t 166pte_prot_nowrite(pt_entry_t pt_entry) 167{ 168 return pt_entry & ~MMUDR_W; 169} 170 171static inline pt_entry_t 172pte_prot_downgrade(pt_entry_t pt_entry, vm_prot_t newprot) 173{ 174 pt_entry &= ~MMUDR_W; 175 if ((newprot & VM_PROT_EXECUTE) == 0) 176 pt_entry &= ~MMUDR_X; 177 return pt_entry; 178} 179 180static inline pt_entry_t 181pte_prot_bits(struct vm_page_md *mdpg, vm_prot_t prot) 182{ 183 KASSERT(prot & VM_PROT_READ); 184 pt_entry_t pt_entry = MMUDR_R; 185 if (prot & VM_PROT_EXECUTE) { 186 /* Only allow exec for managed pages */ 187 if (mdpg != NULL && VM_PAGEMD_EXECPAGE_P(mdpg)) 188 pt_entry |= MMUDR_X; 189 } 190 if (prot & VM_PROT_WRITE) { 191 if (mdpg == NULL || VM_PAGEMD_MODIFIED_P(mdpg)) 192 pt_entry |= MMUDR_W; 193 } 194 return pt_entry; 195} 196 197static inline pt_entry_t 198pte_flag_bits(struct vm_page_md *mdpg, int flags) 199{ 200 if (__predict_false(flags & PMAP_NOCACHE)) { 201 if (__predict_true(mdpg != NULL)) { 202 return pte_nocached_bits(); 203 } else { 204 return pte_ionocached_bits(); 205 } 206 } else { 207 if (__predict_false(mdpg != NULL)) { 208 return pte_cached_bits(); 209 } else { 210 return pte_iocached_bits(); 211 } 212 } 213} 214 215static inline pt_entry_t 216pte_make_enter(paddr_t pa, struct vm_page_md *mdpg, vm_prot_t prot, 217 int flags, bool kernel) 218{ 219 pt_entry_t pt_entry = (pt_entry_t) pa & MMUDR_PA; 220 221 pt_entry |= pte_flag_bits(mdpg, flags); 222 pt_entry |= pte_prot_bits(mdpg, prot); 223 224 return pt_entry; 225} 226 227static inline pt_entry_t 228pte_make_kenter_pa(paddr_t pa, struct vm_page_md *mdpg, vm_prot_t prot, 229 int flags) 230{ 231 pt_entry_t pt_entry = (pt_entry_t) pa & MMUDR_PA; 232 233 pt_entry |= MMUDR_LK; 234 pt_entry |= pte_flag_bits(mdpg, flags); 235 pt_entry |= pte_prot_bits(NULL, prot); /* pretend unmanaged */ 236 237 return pt_entry; 238} 239#endif /* _KERNEL_ */ 240 241#endif /* _M68K_PTE_COLDFIRE_H_ */ 242