| @@ -1,221 +1,223 @@ | | | @@ -1,221 +1,223 @@ |
1 | /* $NetBSD: mem.c,v 1.26 2008/11/19 06:24:04 matt Exp $ */ | | 1 | /* $NetBSD: mem.c,v 1.27 2010/10/30 18:35:38 uebayasi Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1982, 1986, 1990, 1993 | | 4 | * Copyright (c) 1982, 1986, 1990, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * the Systems Programming Group of the University of Utah Computer | | 8 | * the Systems Programming Group of the University of Utah Computer |
9 | * Science Department. | | 9 | * Science Department. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions and the following disclaimer. | | 15 | * notice, this list of conditions and the following disclaimer. |
16 | * 2. Redistributions in binary form must reproduce the above copyright | | 16 | * 2. Redistributions in binary form must reproduce the above copyright |
17 | * notice, this list of conditions and the following disclaimer in the | | 17 | * notice, this list of conditions and the following disclaimer in the |
18 | * documentation and/or other materials provided with the distribution. | | 18 | * documentation and/or other materials provided with the distribution. |
19 | * 3. Neither the name of the University nor the names of its contributors | | 19 | * 3. Neither the name of the University nor the names of its contributors |
20 | * may be used to endorse or promote products derived from this software | | 20 | * may be used to endorse or promote products derived from this software |
21 | * without specific prior written permission. | | 21 | * without specific prior written permission. |
22 | * | | 22 | * |
23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
33 | * SUCH DAMAGE. | | 33 | * SUCH DAMAGE. |
34 | */ | | 34 | */ |
35 | /* | | 35 | /* |
36 | * Copyright (c) 1988 University of Utah. | | 36 | * Copyright (c) 1988 University of Utah. |
37 | * | | 37 | * |
38 | * This code is derived from software contributed to Berkeley by | | 38 | * This code is derived from software contributed to Berkeley by |
39 | * the Systems Programming Group of the University of Utah Computer | | 39 | * the Systems Programming Group of the University of Utah Computer |
40 | * Science Department. | | 40 | * Science Department. |
41 | * | | 41 | * |
42 | * Redistribution and use in source and binary forms, with or without | | 42 | * Redistribution and use in source and binary forms, with or without |
43 | * modification, are permitted provided that the following conditions | | 43 | * modification, are permitted provided that the following conditions |
44 | * are met: | | 44 | * are met: |
45 | * 1. Redistributions of source code must retain the above copyright | | 45 | * 1. Redistributions of source code must retain the above copyright |
46 | * notice, this list of conditions and the following disclaimer. | | 46 | * notice, this list of conditions and the following disclaimer. |
47 | * 2. Redistributions in binary form must reproduce the above copyright | | 47 | * 2. Redistributions in binary form must reproduce the above copyright |
48 | * notice, this list of conditions and the following disclaimer in the | | 48 | * notice, this list of conditions and the following disclaimer in the |
49 | * documentation and/or other materials provided with the distribution. | | 49 | * documentation and/or other materials provided with the distribution. |
50 | * 3. All advertising materials mentioning features or use of this software | | 50 | * 3. All advertising materials mentioning features or use of this software |
51 | * must display the following acknowledgement: | | 51 | * must display the following acknowledgement: |
52 | * This product includes software developed by the University of | | 52 | * This product includes software developed by the University of |
53 | * California, Berkeley and its contributors. | | 53 | * California, Berkeley and its contributors. |
54 | * 4. Neither the name of the University nor the names of its contributors | | 54 | * 4. Neither the name of the University nor the names of its contributors |
55 | * may be used to endorse or promote products derived from this software | | 55 | * may be used to endorse or promote products derived from this software |
56 | * without specific prior written permission. | | 56 | * without specific prior written permission. |
57 | * | | 57 | * |
58 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 58 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
68 | * SUCH DAMAGE. | | 68 | * SUCH DAMAGE. |
69 | */ | | 69 | */ |
70 | | | 70 | |
71 | /* | | 71 | /* |
72 | * Memory special file | | 72 | * Memory special file |
73 | */ | | 73 | */ |
74 | | | 74 | |
75 | #include "opt_arm32_pmap.h" | | 75 | #include "opt_arm32_pmap.h" |
76 | #include "opt_compat_netbsd.h" | | 76 | #include "opt_compat_netbsd.h" |
77 | | | 77 | |
78 | #include <sys/cdefs.h> | | 78 | #include <sys/cdefs.h> |
79 | __KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.26 2008/11/19 06:24:04 matt Exp $"); | | 79 | __KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.27 2010/10/30 18:35:38 uebayasi Exp $"); |
80 | | | 80 | |
81 | #include <sys/param.h> | | 81 | #include <sys/param.h> |
82 | #include <sys/conf.h> | | 82 | #include <sys/conf.h> |
83 | #include <sys/buf.h> | | 83 | #include <sys/buf.h> |
84 | #include <sys/systm.h> | | 84 | #include <sys/systm.h> |
85 | #include <sys/uio.h> | | 85 | #include <sys/uio.h> |
86 | #include <sys/malloc.h> | | 86 | #include <sys/malloc.h> |
87 | #include <sys/proc.h> | | 87 | #include <sys/proc.h> |
88 | #include <sys/fcntl.h> | | 88 | #include <sys/fcntl.h> |
89 | #include <sys/kauth.h> | | 89 | #include <sys/kauth.h> |
90 | | | 90 | |
91 | #include <machine/cpu.h> | | 91 | #include <machine/cpu.h> |
92 | | | 92 | |
93 | #include <uvm/uvm_extern.h> | | 93 | #include <uvm/uvm_extern.h> |
94 | | | 94 | |
| | | 95 | #define VM_PAGE_TO_MD(pg) (&(pg)->mdpage) |
| | | 96 | |
95 | extern vaddr_t memhook; /* in pmap.c (poor name!) */ | | 97 | extern vaddr_t memhook; /* in pmap.c (poor name!) */ |
96 | extern kmutex_t memlock; /* in pmap.c */ | | 98 | extern kmutex_t memlock; /* in pmap.c */ |
97 | extern void *zeropage; /* in pmap.c */ | | 99 | extern void *zeropage; /* in pmap.c */ |
98 | | | 100 | |
99 | dev_type_read(mmrw); | | 101 | dev_type_read(mmrw); |
100 | dev_type_ioctl(mmioctl); | | 102 | dev_type_ioctl(mmioctl); |
101 | dev_type_mmap(mmmmap); | | 103 | dev_type_mmap(mmmmap); |
102 | | | 104 | |
103 | const struct cdevsw mem_cdevsw = { | | 105 | const struct cdevsw mem_cdevsw = { |
104 | .d_open = nullopen, | | 106 | .d_open = nullopen, |
105 | .d_close = nullclose, | | 107 | .d_close = nullclose, |
106 | .d_read = mmrw, | | 108 | .d_read = mmrw, |
107 | .d_write = mmrw, | | 109 | .d_write = mmrw, |
108 | .d_ioctl = mmioctl, | | 110 | .d_ioctl = mmioctl, |
109 | .d_stop = nostop, | | 111 | .d_stop = nostop, |
110 | .d_tty = notty, | | 112 | .d_tty = notty, |
111 | .d_poll = nopoll, | | 113 | .d_poll = nopoll, |
112 | .d_mmap = mmmmap, | | 114 | .d_mmap = mmmmap, |
113 | .d_kqfilter = nokqfilter, | | 115 | .d_kqfilter = nokqfilter, |
114 | .d_flag = D_MPSAFE | | 116 | .d_flag = D_MPSAFE |
115 | }; | | 117 | }; |
116 | | | 118 | |
117 | /*ARGSUSED*/ | | 119 | /*ARGSUSED*/ |
118 | int | | 120 | int |
119 | mmrw(dev_t dev, struct uio *uio, int flags) | | 121 | mmrw(dev_t dev, struct uio *uio, int flags) |
120 | { | | 122 | { |
121 | vaddr_t o, v, m; | | 123 | vaddr_t o, v, m; |
122 | int c; | | 124 | int c; |
123 | struct iovec *iov; | | 125 | struct iovec *iov; |
124 | int error = 0; | | 126 | int error = 0; |
125 | vm_prot_t prot; | | 127 | vm_prot_t prot; |
126 | | | 128 | |
127 | while (uio->uio_resid > 0 && error == 0) { | | 129 | while (uio->uio_resid > 0 && error == 0) { |
128 | iov = uio->uio_iov; | | 130 | iov = uio->uio_iov; |
129 | if (iov->iov_len == 0) { | | 131 | if (iov->iov_len == 0) { |
130 | uio->uio_iov++; | | 132 | uio->uio_iov++; |
131 | uio->uio_iovcnt--; | | 133 | uio->uio_iovcnt--; |
132 | if (uio->uio_iovcnt < 0) | | 134 | if (uio->uio_iovcnt < 0) |
133 | panic("mmrw"); | | 135 | panic("mmrw"); |
134 | continue; | | 136 | continue; |
135 | } | | 137 | } |
136 | switch (minor(dev)) { | | 138 | switch (minor(dev)) { |
137 | | | 139 | |
138 | case DEV_MEM: | | 140 | case DEV_MEM: |
139 | v = uio->uio_offset; | | 141 | v = uio->uio_offset; |
140 | prot = uio->uio_rw == UIO_READ ? VM_PROT_READ : | | 142 | prot = uio->uio_rw == UIO_READ ? VM_PROT_READ : |
141 | VM_PROT_WRITE; | | 143 | VM_PROT_WRITE; |
142 | m = memhook; | | 144 | m = memhook; |
143 | #ifdef PMAP_CACHE_VIPT | | 145 | #ifdef PMAP_CACHE_VIPT |
144 | { | | 146 | { |
145 | struct vm_page *pg; | | 147 | struct vm_page *pg; |
146 | pg = PHYS_TO_VM_PAGE(trunc_page(v)); | | 148 | pg = PHYS_TO_VM_PAGE(trunc_page(v)); |
147 | if (pg != NULL && pmap_is_page_colored_p(pg)) | | 149 | if (pg != NULL && pmap_is_page_colored_p(pg)) |
148 | o = pg->mdpage.pvh_attrs; | | 150 | o = VM_PAGE_TO_MD(pg)->pvh_attrs; |
149 | else | | 151 | else |
150 | o = v; | | 152 | o = v; |
151 | m += o & arm_cache_prefer_mask; | | 153 | m += o & arm_cache_prefer_mask; |
152 | } | | 154 | } |
153 | #endif | | 155 | #endif |
154 | mutex_enter(&memlock); | | 156 | mutex_enter(&memlock); |
155 | pmap_enter(pmap_kernel(), m, | | 157 | pmap_enter(pmap_kernel(), m, |
156 | trunc_page(v), prot, prot|PMAP_WIRED); | | 158 | trunc_page(v), prot, prot|PMAP_WIRED); |
157 | pmap_update(pmap_kernel()); | | 159 | pmap_update(pmap_kernel()); |
158 | o = uio->uio_offset & PGOFSET; | | 160 | o = uio->uio_offset & PGOFSET; |
159 | c = min(uio->uio_resid, (int)(PAGE_SIZE - o)); | | 161 | c = min(uio->uio_resid, (int)(PAGE_SIZE - o)); |
160 | error = uiomove((char *)m + o, c, uio); | | 162 | error = uiomove((char *)m + o, c, uio); |
161 | pmap_remove(pmap_kernel(), m, m + PAGE_SIZE); | | 163 | pmap_remove(pmap_kernel(), m, m + PAGE_SIZE); |
162 | pmap_update(pmap_kernel()); | | 164 | pmap_update(pmap_kernel()); |
163 | mutex_exit(&memlock); | | 165 | mutex_exit(&memlock); |
164 | break; | | 166 | break; |
165 | | | 167 | |
166 | case DEV_KMEM: | | 168 | case DEV_KMEM: |
167 | v = uio->uio_offset; | | 169 | v = uio->uio_offset; |
168 | c = min(iov->iov_len, MAXPHYS); | | 170 | c = min(iov->iov_len, MAXPHYS); |
169 | if (!uvm_kernacc((void *)v, c, | | 171 | if (!uvm_kernacc((void *)v, c, |
170 | uio->uio_rw == UIO_READ ? B_READ : B_WRITE)) | | 172 | uio->uio_rw == UIO_READ ? B_READ : B_WRITE)) |
171 | return (EFAULT); | | 173 | return (EFAULT); |
172 | error = uiomove((void *)v, c, uio); | | 174 | error = uiomove((void *)v, c, uio); |
173 | break; | | 175 | break; |
174 | | | 176 | |
175 | case DEV_NULL: | | 177 | case DEV_NULL: |
176 | if (uio->uio_rw == UIO_WRITE) | | 178 | if (uio->uio_rw == UIO_WRITE) |
177 | uio->uio_resid = 0; | | 179 | uio->uio_resid = 0; |
178 | return (0); | | 180 | return (0); |
179 | | | 181 | |
180 | #ifdef COMPAT_16 | | 182 | #ifdef COMPAT_16 |
181 | case _DEV_ZERO_oARM: | | 183 | case _DEV_ZERO_oARM: |
182 | #endif | | 184 | #endif |
183 | case DEV_ZERO: | | 185 | case DEV_ZERO: |
184 | if (uio->uio_rw == UIO_WRITE) { | | 186 | if (uio->uio_rw == UIO_WRITE) { |
185 | uio->uio_resid = 0; | | 187 | uio->uio_resid = 0; |
186 | return (0); | | 188 | return (0); |
187 | } | | 189 | } |
188 | c = min(iov->iov_len, PAGE_SIZE); | | 190 | c = min(iov->iov_len, PAGE_SIZE); |
189 | error = uiomove(zeropage, c, uio); | | 191 | error = uiomove(zeropage, c, uio); |
190 | break; | | 192 | break; |
191 | | | 193 | |
192 | default: | | 194 | default: |
193 | return (ENXIO); | | 195 | return (ENXIO); |
194 | } | | 196 | } |
195 | } | | 197 | } |
196 | return (error); | | 198 | return (error); |
197 | } | | 199 | } |
198 | | | 200 | |
199 | paddr_t | | 201 | paddr_t |
200 | mmmmap(dev_t dev, off_t off, int prot) | | 202 | mmmmap(dev_t dev, off_t off, int prot) |
201 | { | | 203 | { |
202 | struct lwp *l = curlwp; /* XXX */ | | 204 | struct lwp *l = curlwp; /* XXX */ |
203 | | | 205 | |
204 | /* | | 206 | /* |
205 | * /dev/mem is the only one that makes sense through this | | 207 | * /dev/mem is the only one that makes sense through this |
206 | * interface. For /dev/kmem any physaddr we return here | | 208 | * interface. For /dev/kmem any physaddr we return here |
207 | * could be transient and hence incorrect or invalid at | | 209 | * could be transient and hence incorrect or invalid at |
208 | * a later time. /dev/null just doesn't make any sense | | 210 | * a later time. /dev/null just doesn't make any sense |
209 | * and /dev/zero is a hack that is handled via the default | | 211 | * and /dev/zero is a hack that is handled via the default |
210 | * pager in mmap(). | | 212 | * pager in mmap(). |
211 | */ | | 213 | */ |
212 | if (minor(dev) != DEV_MEM) | | 214 | if (minor(dev) != DEV_MEM) |
213 | return (-1); | | 215 | return (-1); |
214 | | | 216 | |
215 | /* minor device 0 is physical memory */ | | 217 | /* minor device 0 is physical memory */ |
216 | | | 218 | |
217 | if (off >= ctob(physmem) && kauth_authorize_machdep(l->l_cred, | | 219 | if (off >= ctob(physmem) && kauth_authorize_machdep(l->l_cred, |
218 | KAUTH_MACHDEP_UNMANAGEDMEM, NULL, NULL, NULL, NULL) != 0) | | 220 | KAUTH_MACHDEP_UNMANAGEDMEM, NULL, NULL, NULL, NULL) != 0) |
219 | return -1; | | 221 | return -1; |
220 | return arm_btop(off); | | 222 | return arm_btop(off); |
221 | } | | 223 | } |