1 1.41 skrll /* $NetBSD: pmap.h,v 1.41 2022/05/26 05:34:04 skrll Exp $ */ 2 1.1 fredette 3 1.18 skrll /* $OpenBSD: pmap.h,v 1.35 2007/12/14 18:32:23 deraadt Exp $ */ 4 1.1 fredette 5 1.1 fredette /* 6 1.18 skrll * Copyright (c) 2002-2004 Michael Shalayeff 7 1.1 fredette * All rights reserved. 8 1.1 fredette * 9 1.1 fredette * Redistribution and use in source and binary forms, with or without 10 1.1 fredette * modification, are permitted provided that the following conditions 11 1.1 fredette * are met: 12 1.1 fredette * 1. Redistributions of source code must retain the above copyright 13 1.1 fredette * notice, this list of conditions and the following disclaimer. 14 1.1 fredette * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 fredette * notice, this list of conditions and the following disclaimer in the 16 1.1 fredette * documentation and/or other materials provided with the distribution. 17 1.1 fredette * 18 1.1 fredette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 1.1 fredette * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 1.1 fredette * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 1.18 skrll * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 1.18 skrll * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 1.18 skrll * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 1.18 skrll * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 1.18 skrll * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 1.18 skrll * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 1.18 skrll * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 1.18 skrll * THE POSSIBILITY OF SUCH DAMAGE. 29 1.1 fredette */ 30 1.1 fredette 31 1.1 fredette /* 32 1.1 fredette * Pmap header for hppa. 33 1.1 fredette */ 34 1.1 fredette 35 1.1 fredette #ifndef _HPPA_PMAP_H_ 36 1.1 fredette #define _HPPA_PMAP_H_ 37 1.1 fredette 38 1.25 skrll #ifdef _KERNEL_OPT 39 1.25 skrll #include "opt_cputype.h" 40 1.25 skrll #endif 41 1.25 skrll 42 1.39 ad #include <sys/rwlock.h> 43 1.1 fredette #include <machine/pte.h> 44 1.18 skrll #include <machine/cpufunc.h> 45 1.18 skrll 46 1.18 skrll #include <uvm/uvm_pglist.h> 47 1.18 skrll #include <uvm/uvm_object.h> 48 1.18 skrll 49 1.18 skrll #ifdef _KERNEL 50 1.1 fredette 51 1.33 skrll #define PMAP_NEED_PROCWR 52 1.33 skrll 53 1.1 fredette struct pmap { 54 1.18 skrll struct uvm_object pm_obj; /* object (lck by object lock) */ 55 1.18 skrll #define pm_lock pm_obj.vmobjlock 56 1.39 ad krwlock_t pm_obj_lock; /* lock for pm_obj */ 57 1.18 skrll struct vm_page *pm_ptphint; 58 1.18 skrll struct vm_page *pm_pdir_pg; /* vm_page for pdir */ 59 1.21 skrll volatile uint32_t *pm_pdir; /* page dir (read-only after create) */ 60 1.18 skrll pa_space_t pm_space; /* space id (read-only after create) */ 61 1.18 skrll u_int pm_pid; /* prot id (read-only after create) */ 62 1.18 skrll 63 1.18 skrll struct pmap_statistics pm_stats; 64 1.18 skrll }; 65 1.18 skrll 66 1.18 skrll #define PVF_MOD PTE_PROT(TLB_DIRTY) /* pg/mp is modified */ 67 1.18 skrll #define PVF_REF PTE_PROT(TLB_REFTRAP) /* pg/mp (inv) is referenced */ 68 1.18 skrll #define PVF_WRITE PTE_PROT(TLB_WRITE) /* pg/mp is writable */ 69 1.36 skrll #define PVF_EXEC PTE_PROT(TLB_EXECUTE) /* pg/mp is executable */ 70 1.27 skrll #define PVF_UNCACHEABLE PTE_PROT(TLB_UNCACHEABLE) /* pg/mp is uncacheable */ 71 1.18 skrll 72 1.18 skrll #define HPPA_MAX_PID 0xfffa 73 1.18 skrll #define HPPA_SID_MAX 0x7ffd 74 1.19 skrll 75 1.41 skrll #define PMAP_DIRECTMAP 0x10000000 /* kenter_pa */ 76 1.41 skrll 77 1.19 skrll /* 78 1.19 skrll * DON'T CHANGE THIS - this is assumed in lots of places. 79 1.19 skrll */ 80 1.18 skrll #define HPPA_SID_KERNEL 0 81 1.18 skrll #define HPPA_PID_KERNEL 2 82 1.18 skrll 83 1.18 skrll struct pv_entry { /* locked by its list's pvh_lock */ 84 1.18 skrll struct pv_entry *pv_next; 85 1.18 skrll struct pmap *pv_pmap; /* the pmap */ 86 1.18 skrll vaddr_t pv_va; /* the virtual address + flags */ 87 1.18 skrll #define PV_VAMASK (~(PAGE_SIZE - 1)) 88 1.38 skrll #define PV_KENTER __BIT(0) 89 1.18 skrll 90 1.18 skrll struct vm_page *pv_ptp; /* the vm_page of the PTP */ 91 1.17 pooka }; 92 1.1 fredette 93 1.18 skrll extern int pmap_hptsize; 94 1.18 skrll extern struct pdc_hwtlb pdc_hwtlb; 95 1.18 skrll 96 1.18 skrll /* 97 1.18 skrll * pool quickmaps 98 1.18 skrll */ 99 1.18 skrll static inline vaddr_t hppa_map_poolpage(paddr_t pa) 100 1.18 skrll { 101 1.18 skrll return (vaddr_t)pa; 102 1.18 skrll } 103 1.5 chs 104 1.18 skrll static inline paddr_t hppa_unmap_poolpage(vaddr_t va) 105 1.18 skrll { 106 1.18 skrll pdcache(HPPA_SID_KERNEL, va, PAGE_SIZE); 107 1.26 skrll 108 1.24 skrll #if defined(HP8000_CPU) || defined(HP8200_CPU) || \ 109 1.24 skrll defined(HP8500_CPU) || defined(HP8600_CPU) 110 1.24 skrll pdtlb(HPPA_SID_KERNEL, va); 111 1.24 skrll #endif 112 1.5 chs 113 1.18 skrll return (paddr_t)va; 114 1.18 skrll } 115 1.1 fredette 116 1.18 skrll #define PMAP_MAP_POOLPAGE(pa) hppa_map_poolpage(pa) 117 1.18 skrll #define PMAP_UNMAP_POOLPAGE(va) hppa_unmap_poolpage(va) 118 1.1 fredette 119 1.1 fredette /* 120 1.1 fredette * according to the parisc manual aliased va's should be 121 1.1 fredette * different by high 12 bits only. 122 1.1 fredette */ 123 1.37 chs #define PMAP_PREFER(o,h,s,td) pmap_prefer((o), (h), (td)) 124 1.37 chs 125 1.37 chs static inline void 126 1.37 chs pmap_prefer(vaddr_t fo, vaddr_t *va, int td) 127 1.37 chs { 128 1.37 chs vaddr_t newva; 129 1.37 chs 130 1.37 chs newva = (*va & HPPA_PGAMASK) | (fo & HPPA_PGAOFF); 131 1.37 chs if (td) { 132 1.37 chs if (newva > *va) 133 1.37 chs newva -= HPPA_PGALIAS; 134 1.37 chs } else { 135 1.37 chs if (newva < *va) 136 1.37 chs newva += HPPA_PGALIAS; 137 1.37 chs } 138 1.37 chs *va = newva; 139 1.37 chs } 140 1.1 fredette 141 1.18 skrll #define pmap_sid2pid(s) (((s) + 1) << 1) 142 1.18 skrll #define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) 143 1.18 skrll #define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count) 144 1.18 skrll #define pmap_update(p) 145 1.18 skrll 146 1.18 skrll #define pmap_copy(dpmap,spmap,da,len,sa) 147 1.18 skrll 148 1.18 skrll #define pmap_clear_modify(pg) pmap_changebit(pg, 0, PTE_PROT(TLB_DIRTY)) 149 1.18 skrll #define pmap_clear_reference(pg) \ 150 1.18 skrll pmap_changebit(pg, PTE_PROT(TLB_REFTRAP), 0) 151 1.18 skrll #define pmap_is_modified(pg) pmap_testbit(pg, PTE_PROT(TLB_DIRTY)) 152 1.18 skrll #define pmap_is_referenced(pg) pmap_testbit(pg, PTE_PROT(TLB_REFTRAP)) 153 1.18 skrll #define pmap_phys_address(ppn) ((ppn) << PAGE_SHIFT) 154 1.1 fredette 155 1.12 skrll void pmap_activate(struct lwp *); 156 1.6 chs 157 1.18 skrll void pmap_bootstrap(vaddr_t); 158 1.18 skrll bool pmap_changebit(struct vm_page *, u_int, u_int); 159 1.18 skrll bool pmap_testbit(struct vm_page *, u_int); 160 1.18 skrll void pmap_write_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t); 161 1.18 skrll void pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t eva); 162 1.18 skrll void pmap_page_remove(struct vm_page *pg); 163 1.18 skrll 164 1.33 skrll void pmap_procwr(struct proc *, vaddr_t, size_t); 165 1.33 skrll 166 1.18 skrll static inline void 167 1.12 skrll pmap_deactivate(struct lwp *l) 168 1.6 chs { 169 1.18 skrll /* Nothing. */ 170 1.6 chs } 171 1.1 fredette 172 1.40 ad static inline bool 173 1.3 chs pmap_remove_all(struct pmap *pmap) 174 1.2 chs { 175 1.2 chs /* Nothing. */ 176 1.40 ad return false; 177 1.2 chs } 178 1.1 fredette 179 1.18 skrll static inline int 180 1.18 skrll pmap_prot(struct pmap *pmap, int prot) 181 1.1 fredette { 182 1.18 skrll extern u_int hppa_prot[]; 183 1.32 skrll return (hppa_prot[prot] | (pmap == pmap_kernel() ? 0 : TLB_USER)); 184 1.18 skrll } 185 1.5 chs 186 1.18 skrll static inline void 187 1.18 skrll pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 188 1.18 skrll { 189 1.18 skrll if ((prot & UVM_PROT_WRITE) == 0) { 190 1.18 skrll if (prot & (UVM_PROT_RX)) 191 1.18 skrll pmap_changebit(pg, 0, PTE_PROT(TLB_WRITE)); 192 1.18 skrll else 193 1.18 skrll pmap_page_remove(pg); 194 1.18 skrll } 195 1.18 skrll } 196 1.18 skrll 197 1.18 skrll static inline void 198 1.18 skrll pmap_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 199 1.18 skrll { 200 1.18 skrll if ((prot & UVM_PROT_WRITE) == 0) { 201 1.18 skrll if (prot & (UVM_PROT_RX)) 202 1.18 skrll pmap_write_protect(pmap, sva, eva, prot); 203 1.18 skrll else 204 1.18 skrll pmap_remove(pmap, sva, eva); 205 1.18 skrll } 206 1.1 fredette } 207 1.1 fredette 208 1.7 chs #define pmap_sid(pmap, va) \ 209 1.7 chs ((((va) & 0xc0000000) != 0xc0000000) ? \ 210 1.18 skrll (pmap)->pm_space : HPPA_SID_KERNEL) 211 1.7 chs 212 1.29 uebayasi #define __HAVE_VM_PAGE_MD 213 1.29 uebayasi 214 1.29 uebayasi struct pv_entry; 215 1.29 uebayasi 216 1.29 uebayasi struct vm_page_md { 217 1.35 skrll struct pv_entry *pvh_list; /* head of list */ 218 1.29 uebayasi u_int pvh_attrs; /* to preserve ref/mod */ 219 1.29 uebayasi }; 220 1.29 uebayasi 221 1.29 uebayasi #define VM_MDPAGE_INIT(pg) \ 222 1.29 uebayasi do { \ 223 1.29 uebayasi (pg)->mdpage.pvh_list = NULL; \ 224 1.29 uebayasi (pg)->mdpage.pvh_attrs = 0; \ 225 1.29 uebayasi } while (0) 226 1.29 uebayasi 227 1.1 fredette #endif /* _KERNEL */ 228 1.1 fredette 229 1.1 fredette #endif /* _HPPA_PMAP_H_ */ 230