| @@ -1,1169 +1,1169 @@ | | | @@ -1,1169 +1,1169 @@ |
1 | /* $NetBSD: machdep.c,v 1.80 2019/12/31 13:07:12 ad Exp $ */ | | 1 | /* $NetBSD: machdep.c,v 1.81 2020/03/08 06:05:05 rin 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 | * from: Utah Hdr: machdep.c 1.74 92/12/20 | | 35 | * from: Utah Hdr: machdep.c 1.74 92/12/20 |
36 | * from: @(#)machdep.c 8.10 (Berkeley) 4/20/94 | | 36 | * from: @(#)machdep.c 8.10 (Berkeley) 4/20/94 |
37 | */ | | 37 | */ |
38 | | | 38 | |
39 | /* | | 39 | /* |
40 | * Copyright (c) 2001 Matthew Fredette. | | 40 | * Copyright (c) 2001 Matthew Fredette. |
41 | * Copyright (c) 1994, 1995 Gordon W. Ross | | 41 | * Copyright (c) 1994, 1995 Gordon W. Ross |
42 | * Copyright (c) 1993 Adam Glass | | 42 | * Copyright (c) 1993 Adam Glass |
43 | * Copyright (c) 1988 University of Utah. | | 43 | * Copyright (c) 1988 University of Utah. |
44 | * | | 44 | * |
45 | * This code is derived from software contributed to Berkeley by | | 45 | * This code is derived from software contributed to Berkeley by |
46 | * the Systems Programming Group of the University of Utah Computer | | 46 | * the Systems Programming Group of the University of Utah Computer |
47 | * Science Department. | | 47 | * Science Department. |
48 | * | | 48 | * |
49 | * Redistribution and use in source and binary forms, with or without | | 49 | * Redistribution and use in source and binary forms, with or without |
50 | * modification, are permitted provided that the following conditions | | 50 | * modification, are permitted provided that the following conditions |
51 | * are met: | | 51 | * are met: |
52 | * 1. Redistributions of source code must retain the above copyright | | 52 | * 1. Redistributions of source code must retain the above copyright |
53 | * notice, this list of conditions and the following disclaimer. | | 53 | * notice, this list of conditions and the following disclaimer. |
54 | * 2. Redistributions in binary form must reproduce the above copyright | | 54 | * 2. Redistributions in binary form must reproduce the above copyright |
55 | * notice, this list of conditions and the following disclaimer in the | | 55 | * notice, this list of conditions and the following disclaimer in the |
56 | * documentation and/or other materials provided with the distribution. | | 56 | * documentation and/or other materials provided with the distribution. |
57 | * 3. All advertising materials mentioning features or use of this software | | 57 | * 3. All advertising materials mentioning features or use of this software |
58 | * must display the following acknowledgement: | | 58 | * must display the following acknowledgement: |
59 | * This product includes software developed by the University of | | 59 | * This product includes software developed by the University of |
60 | * California, Berkeley and its contributors. | | 60 | * California, Berkeley and its contributors. |
61 | * 4. Neither the name of the University nor the names of its contributors | | 61 | * 4. Neither the name of the University nor the names of its contributors |
62 | * may be used to endorse or promote products derived from this software | | 62 | * may be used to endorse or promote products derived from this software |
63 | * without specific prior written permission. | | 63 | * without specific prior written permission. |
64 | * | | 64 | * |
65 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 65 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
66 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 66 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
67 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 67 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
68 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 68 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
69 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 69 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
70 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 70 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
71 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 71 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
72 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 72 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
73 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 73 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
74 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 74 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
75 | * SUCH DAMAGE. | | 75 | * SUCH DAMAGE. |
76 | * | | 76 | * |
77 | * from: Utah Hdr: machdep.c 1.74 92/12/20 | | 77 | * from: Utah Hdr: machdep.c 1.74 92/12/20 |
78 | * from: @(#)machdep.c 8.10 (Berkeley) 4/20/94 | | 78 | * from: @(#)machdep.c 8.10 (Berkeley) 4/20/94 |
79 | */ | | 79 | */ |
80 | | | 80 | |
81 | /*- | | 81 | /*- |
82 | * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. | | 82 | * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. |
83 | * All rights reserved. | | 83 | * All rights reserved. |
84 | * | | 84 | * |
85 | * This code is derived from software contributed to The NetBSD Foundation | | 85 | * This code is derived from software contributed to The NetBSD Foundation |
86 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | | 86 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, |
87 | * NASA Ames Research Center. | | 87 | * NASA Ames Research Center. |
88 | * | | 88 | * |
89 | * Redistribution and use in source and binary forms, with or without | | 89 | * Redistribution and use in source and binary forms, with or without |
90 | * modification, are permitted provided that the following conditions | | 90 | * modification, are permitted provided that the following conditions |
91 | * are met: | | 91 | * are met: |
92 | * 1. Redistributions of source code must retain the above copyright | | 92 | * 1. Redistributions of source code must retain the above copyright |
93 | * notice, this list of conditions and the following disclaimer. | | 93 | * notice, this list of conditions and the following disclaimer. |
94 | * 2. Redistributions in binary form must reproduce the above copyright | | 94 | * 2. Redistributions in binary form must reproduce the above copyright |
95 | * notice, this list of conditions and the following disclaimer in the | | 95 | * notice, this list of conditions and the following disclaimer in the |
96 | * documentation and/or other materials provided with the distribution. | | 96 | * documentation and/or other materials provided with the distribution. |
97 | * | | 97 | * |
98 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 98 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
99 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 99 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
100 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 100 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
101 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 101 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
102 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 102 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
103 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 103 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
104 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 104 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
105 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 105 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
106 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 106 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
107 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 107 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
108 | * POSSIBILITY OF SUCH DAMAGE. | | 108 | * POSSIBILITY OF SUCH DAMAGE. |
109 | */ | | 109 | */ |
110 | | | 110 | |
111 | /* | | 111 | /* |
112 | * Copyright (c) 1992, 1993 | | 112 | * Copyright (c) 1992, 1993 |
113 | * The Regents of the University of California. All rights reserved. | | 113 | * The Regents of the University of California. All rights reserved. |
114 | * | | 114 | * |
115 | * This software was developed by the Computer Systems Engineering group | | 115 | * This software was developed by the Computer Systems Engineering group |
116 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and | | 116 | * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and |
117 | * contributed to Berkeley. | | 117 | * contributed to Berkeley. |
118 | * | | 118 | * |
119 | * All advertising materials mentioning features or use of this software | | 119 | * All advertising materials mentioning features or use of this software |
120 | * must display the following acknowledgement: | | 120 | * must display the following acknowledgement: |
121 | * This product includes software developed by the University of | | 121 | * This product includes software developed by the University of |
122 | * California, Lawrence Berkeley Laboratory. | | 122 | * California, Lawrence Berkeley Laboratory. |
123 | * | | 123 | * |
124 | * Redistribution and use in source and binary forms, with or without | | 124 | * Redistribution and use in source and binary forms, with or without |
125 | * modification, are permitted provided that the following conditions | | 125 | * modification, are permitted provided that the following conditions |
126 | * are met: | | 126 | * are met: |
127 | * 1. Redistributions of source code must retain the above copyright | | 127 | * 1. Redistributions of source code must retain the above copyright |
128 | * notice, this list of conditions and the following disclaimer. | | 128 | * notice, this list of conditions and the following disclaimer. |
129 | * 2. Redistributions in binary form must reproduce the above copyright | | 129 | * 2. Redistributions in binary form must reproduce the above copyright |
130 | * notice, this list of conditions and the following disclaimer in the | | 130 | * notice, this list of conditions and the following disclaimer in the |
131 | * documentation and/or other materials provided with the distribution. | | 131 | * documentation and/or other materials provided with the distribution. |
132 | * 3. Neither the name of the University nor the names of its contributors | | 132 | * 3. Neither the name of the University nor the names of its contributors |
133 | * may be used to endorse or promote products derived from this software | | 133 | * may be used to endorse or promote products derived from this software |
134 | * without specific prior written permission. | | 134 | * without specific prior written permission. |
135 | * | | 135 | * |
136 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 136 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
137 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 137 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
138 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 138 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
139 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 139 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
140 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 140 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
141 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 141 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
142 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 142 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
143 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 143 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
144 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 144 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
145 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 145 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
146 | * SUCH DAMAGE. | | 146 | * SUCH DAMAGE. |
147 | * | | 147 | * |
148 | * @(#)machdep.c 8.6 (Berkeley) 1/14/94 | | 148 | * @(#)machdep.c 8.6 (Berkeley) 1/14/94 |
149 | */ | | 149 | */ |
150 | | | 150 | |
151 | #include <sys/cdefs.h> | | 151 | #include <sys/cdefs.h> |
152 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.80 2019/12/31 13:07:12 ad Exp $"); | | 152 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.81 2020/03/08 06:05:05 rin Exp $"); |
153 | | | 153 | |
154 | #include "opt_ddb.h" | | 154 | #include "opt_ddb.h" |
155 | #include "opt_kgdb.h" | | | |
156 | #include "opt_fpu_emulate.h" | | 155 | #include "opt_fpu_emulate.h" |
| | | 156 | #include "opt_kgdb.h" |
157 | #include "opt_modular.h" | | 157 | #include "opt_modular.h" |
158 | | | 158 | |
159 | #include <sys/param.h> | | 159 | #include <sys/param.h> |
160 | #include <sys/systm.h> | | | |
161 | #include <sys/kernel.h> | | | |
162 | #include <sys/proc.h> | | | |
163 | #include <sys/buf.h> | | 160 | #include <sys/buf.h> |
164 | #include <sys/reboot.h> | | | |
165 | #include <sys/conf.h> | | 161 | #include <sys/conf.h> |
166 | #include <sys/file.h> | | 162 | #include <sys/core.h> |
| | | 163 | #include <sys/cpu.h> |
167 | #include <sys/device.h> | | 164 | #include <sys/device.h> |
168 | #include <sys/malloc.h> | | 165 | #include <sys/exec.h> |
| | | 166 | #include <sys/exec_aout.h> /* for MID_* */ |
169 | #include <sys/extent.h> | | 167 | #include <sys/extent.h> |
| | | 168 | #include <sys/file.h> |
| | | 169 | #include <sys/ioctl.h> |
| | | 170 | #include <sys/kcore.h> |
| | | 171 | #include <sys/kernel.h> |
| | | 172 | #include <sys/ksyms.h> |
| | | 173 | #include <sys/malloc.h> |
170 | #include <sys/mbuf.h> | | 174 | #include <sys/mbuf.h> |
| | | 175 | #include <sys/mount.h> |
171 | #include <sys/msgbuf.h> | | 176 | #include <sys/msgbuf.h> |
172 | #include <sys/ioctl.h> | | 177 | #include <sys/proc.h> |
| | | 178 | #include <sys/reboot.h> |
| | | 179 | #include <sys/syscallargs.h> |
| | | 180 | #include <sys/sysctl.h> |
| | | 181 | #include <sys/systm.h> |
173 | #include <sys/tty.h> | | 182 | #include <sys/tty.h> |
174 | #include <sys/mount.h> | | | |
175 | #include <sys/exec.h> | | | |
176 | #include <sys/exec_aout.h> /* for MID_* */ | | | |
177 | #include <sys/core.h> | | | |
178 | #include <sys/kcore.h> | | | |
179 | #include <sys/vnode.h> | | 183 | #include <sys/vnode.h> |
180 | #include <sys/syscallargs.h> | | 184 | |
181 | #include <sys/ksyms.h> | | | |
182 | #include <sys/cpu.h> | | | |
183 | #ifdef KGDB | | 185 | #ifdef KGDB |
184 | #include <sys/kgdb.h> | | 186 | #include <sys/kgdb.h> |
185 | #endif | | 187 | #endif |
186 | | | 188 | |
187 | #include <uvm/uvm.h> /* XXX: not _extern ... need vm_map_create */ | | 189 | #include <uvm/uvm.h> /* XXX: not _extern ... need vm_map_create */ |
188 | | | 190 | |
189 | #include <sys/sysctl.h> | | | |
190 | | | | |
191 | #include <dev/cons.h> | | 191 | #include <dev/cons.h> |
192 | #include <dev/mm.h> | | 192 | #include <dev/mm.h> |
193 | | | 193 | |
194 | #include <machine/promlib.h> | | 194 | #define _SUN68K_BUS_DMA_PRIVATE |
| | | 195 | #include <machine/autoconf.h> |
| | | 196 | #include <machine/bus.h> |
195 | #include <machine/cpu.h> | | 197 | #include <machine/cpu.h> |
196 | #include <machine/dvma.h> | | 198 | #include <machine/dvma.h> |
197 | #include <machine/idprom.h> | | 199 | #include <machine/idprom.h> |
| | | 200 | #include <machine/intr.h> |
198 | #include <machine/kcore.h> | | 201 | #include <machine/kcore.h> |
199 | #include <machine/reg.h> | | | |
200 | #include <machine/pcb.h> | | 202 | #include <machine/pcb.h> |
| | | 203 | #include <machine/pmap.h> |
| | | 204 | #include <machine/promlib.h> |
201 | #include <machine/psl.h> | | 205 | #include <machine/psl.h> |
202 | #include <machine/pte.h> | | 206 | #include <machine/pte.h> |
203 | #define _SUN68K_BUS_DMA_PRIVATE | | 207 | #include <machine/reg.h> |
204 | #include <machine/autoconf.h> | | | |
205 | #include <machine/bus.h> | | | |
206 | #include <machine/intr.h> | | | |
207 | #include <machine/pmap.h> | | | |
208 | | | 208 | |
209 | #if defined(DDB) | | 209 | #if defined(DDB) |
210 | #include <machine/db_machdep.h> | | 210 | #include <machine/db_machdep.h> |
211 | #include <ddb/db_sym.h> | | | |
212 | #include <ddb/db_extern.h> | | 211 | #include <ddb/db_extern.h> |
| | | 212 | #include <ddb/db_sym.h> |
213 | #endif | | 213 | #endif |
214 | | | 214 | |
215 | #include <dev/vme/vmereg.h> | | 215 | #include <dev/vme/vmereg.h> |
216 | #include <dev/vme/vmevar.h> | | 216 | #include <dev/vme/vmevar.h> |
217 | | | 217 | |
218 | #include <sun2/sun2/control.h> | | 218 | #include <sun2/sun2/control.h> |
219 | #include <sun2/sun2/enable.h> | | 219 | #include <sun2/sun2/enable.h> |
220 | #include <sun2/sun2/machdep.h> | | 220 | #include <sun2/sun2/machdep.h> |
221 | | | 221 | |
222 | #include <sun68k/sun68k/vme_sun68k.h> | | 222 | #include <sun68k/sun68k/vme_sun68k.h> |
223 | | | 223 | |
224 | #include "ksyms.h" | | 224 | #include "ksyms.h" |
225 | | | 225 | |
226 | /* Defined in locore.s */ | | 226 | /* Defined in locore.s */ |
227 | extern char kernel_text[]; | | 227 | extern char kernel_text[]; |
228 | /* Defined by the linker */ | | 228 | /* Defined by the linker */ |
229 | extern char etext[]; | | 229 | extern char etext[]; |
230 | /* Defined in vfs_bio.c */ | | 230 | /* Defined in vfs_bio.c */ |
231 | extern u_int bufpages; | | 231 | extern u_int bufpages; |
232 | | | 232 | |
233 | /* Our exported CPU info; we can have only one. */ | | 233 | /* Our exported CPU info; we can have only one. */ |
234 | struct cpu_info cpu_info_store; | | 234 | struct cpu_info cpu_info_store; |
235 | | | 235 | |
236 | struct vm_map *phys_map = NULL; | | 236 | struct vm_map *phys_map = NULL; |
237 | | | 237 | |
238 | int fputype; | | 238 | int fputype; |
239 | void * msgbufaddr; | | 239 | void * msgbufaddr; |
240 | | | 240 | |
241 | /* Virtual page frame for /dev/mem (see mem.c) */ | | 241 | /* Virtual page frame for /dev/mem (see mem.c) */ |
242 | vaddr_t vmmap; | | 242 | vaddr_t vmmap; |
243 | | | 243 | |
244 | /* Soft copy of the enable register. */ | | 244 | /* Soft copy of the enable register. */ |
245 | volatile u_short enable_reg_soft = ENABLE_REG_SOFT_UNDEF; | | 245 | volatile u_short enable_reg_soft = ENABLE_REG_SOFT_UNDEF; |
246 | | | 246 | |
247 | /* | | 247 | /* |
248 | * Our no-fault fault handler. | | 248 | * Our no-fault fault handler. |
249 | */ | | 249 | */ |
250 | label_t *nofault; | | 250 | label_t *nofault; |
251 | | | 251 | |
252 | /* | | 252 | /* |
253 | * dvmamap is used to manage DVMA memory. | | 253 | * dvmamap is used to manage DVMA memory. |
254 | */ | | 254 | */ |
255 | static struct extent *dvmamap; | | 255 | static struct extent *dvmamap; |
256 | | | 256 | |
257 | /* Our private scratch page for dumping the MMU. */ | | 257 | /* Our private scratch page for dumping the MMU. */ |
258 | static vaddr_t dumppage; | | 258 | static vaddr_t dumppage; |
259 | | | 259 | |
260 | static void identifycpu(void); | | 260 | static void identifycpu(void); |
261 | static void initcpu(void); | | 261 | static void initcpu(void); |
262 | | | 262 | |
263 | /* | | 263 | /* |
264 | * cpu_startup: allocate memory for variable-sized tables, | | 264 | * cpu_startup: allocate memory for variable-sized tables, |
265 | * initialize CPU, and do autoconfiguration. | | 265 | * initialize CPU, and do autoconfiguration. |
266 | * | | 266 | * |
267 | * This is called early in init_main.c:main(), after the | | 267 | * This is called early in init_main.c:main(), after the |
268 | * kernel memory allocator is ready for use, but before | | 268 | * kernel memory allocator is ready for use, but before |
269 | * the creation of processes 1,2, and mountroot, etc. | | 269 | * the creation of processes 1,2, and mountroot, etc. |
270 | */ | | 270 | */ |
271 | void | | 271 | void |
272 | cpu_startup(void) | | 272 | cpu_startup(void) |
273 | { | | 273 | { |
274 | void *v; | | 274 | void *v; |
275 | vaddr_t minaddr, maxaddr; | | 275 | vaddr_t minaddr, maxaddr; |
276 | char pbuf[9]; | | 276 | char pbuf[9]; |
277 | | | 277 | |
278 | /* | | 278 | /* |
279 | * Initialize message buffer (for kernel printf). | | 279 | * Initialize message buffer (for kernel printf). |
280 | * This is put in physical pages four through seven | | 280 | * This is put in physical pages four through seven |
281 | * so it will always be in the same place after a | | 281 | * so it will always be in the same place after a |
282 | * reboot. (physical pages 0-3 are reserved by the PROM | | 282 | * reboot. (physical pages 0-3 are reserved by the PROM |
283 | * for its vector table and other stuff.) | | 283 | * for its vector table and other stuff.) |
284 | * Its mapping was prepared in pmap_bootstrap(). | | 284 | * Its mapping was prepared in pmap_bootstrap(). |
285 | * Also, offset some to avoid PROM scribbles. | | 285 | * Also, offset some to avoid PROM scribbles. |
286 | */ | | 286 | */ |
287 | v = (void *) (PAGE_SIZE * 4); | | 287 | v = (void *) (PAGE_SIZE * 4); |
288 | msgbufaddr = (void *)((char *)v + MSGBUFOFF); | | 288 | msgbufaddr = (void *)((char *)v + MSGBUFOFF); |
289 | initmsgbuf(msgbufaddr, MSGBUFSIZE); | | 289 | initmsgbuf(msgbufaddr, MSGBUFSIZE); |
290 | | | 290 | |
291 | #if NKSYMS || defined(DDB) || defined(MODULAR) | | 291 | #if NKSYMS || defined(DDB) || defined(MODULAR) |
292 | { | | 292 | { |
293 | extern int nsym; | | 293 | extern int nsym; |
294 | extern char *ssym, *esym; | | 294 | extern char *ssym, *esym; |
295 | | | 295 | |
296 | ksyms_addsyms_elf(nsym, ssym, esym); | | 296 | ksyms_addsyms_elf(nsym, ssym, esym); |
297 | } | | 297 | } |
298 | #endif /* DDB */ | | 298 | #endif /* DDB */ |
299 | | | 299 | |
300 | /* | | 300 | /* |
301 | * Good {morning,afternoon,evening,night}. | | 301 | * Good {morning,afternoon,evening,night}. |
302 | */ | | 302 | */ |
303 | printf("%s%s", copyright, version); | | 303 | printf("%s%s", copyright, version); |
304 | identifycpu(); | | 304 | identifycpu(); |
305 | fputype = FPU_NONE; | | 305 | fputype = FPU_NONE; |
306 | #ifdef FPU_EMULATE | | 306 | #ifdef FPU_EMULATE |
307 | printf("fpu: emulator\n"); | | 307 | printf("fpu: emulator\n"); |
308 | #else | | 308 | #else |
309 | printf("fpu: no math support\n"); | | 309 | printf("fpu: no math support\n"); |
310 | #endif | | 310 | #endif |
311 | | | 311 | |
312 | format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); | | 312 | format_bytes(pbuf, sizeof(pbuf), ctob(physmem)); |
313 | printf("total memory = %s\n", pbuf); | | 313 | printf("total memory = %s\n", pbuf); |
314 | | | 314 | |
315 | /* | | 315 | /* |
316 | * XXX fredette - we force a small number of buffers | | 316 | * XXX fredette - we force a small number of buffers |
317 | * to help me debug this on my low-memory machine. | | 317 | * to help me debug this on my low-memory machine. |
318 | * this should go away at some point, allowing the | | 318 | * this should go away at some point, allowing the |
319 | * normal automatic buffer-sizing to happen. | | 319 | * normal automatic buffer-sizing to happen. |
320 | */ | | 320 | */ |
321 | bufpages = 37; | | 321 | bufpages = 37; |
322 | | | 322 | |
323 | /* | | 323 | /* |
324 | * Get scratch page for dumpsys(). | | 324 | * Get scratch page for dumpsys(). |
325 | */ | | 325 | */ |
326 | if ((dumppage = uvm_km_alloc(kernel_map, PAGE_SIZE,0, UVM_KMF_WIRED)) | | 326 | if ((dumppage = uvm_km_alloc(kernel_map, PAGE_SIZE,0, UVM_KMF_WIRED)) |
327 | == 0) | | 327 | == 0) |
328 | panic("startup: alloc dumppage"); | | 328 | panic("startup: alloc dumppage"); |
329 | | | 329 | |
330 | | | 330 | |
331 | minaddr = 0; | | 331 | minaddr = 0; |
332 | | | 332 | |
333 | /* | | 333 | /* |
334 | * Allocate a submap for physio | | 334 | * Allocate a submap for physio |
335 | */ | | 335 | */ |
336 | phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, | | 336 | phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, |
337 | VM_PHYS_SIZE, 0, false, NULL); | | 337 | VM_PHYS_SIZE, 0, false, NULL); |
338 | | | 338 | |
339 | format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem())); | | 339 | format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem())); |
340 | printf("avail memory = %s\n", pbuf); | | 340 | printf("avail memory = %s\n", pbuf); |
341 | | | 341 | |
342 | /* | | 342 | /* |
343 | * Allocate a virtual page (for use by /dev/mem) | | 343 | * Allocate a virtual page (for use by /dev/mem) |
344 | * This page is handed to pmap_enter() therefore | | 344 | * This page is handed to pmap_enter() therefore |
345 | * it has to be in the normal kernel VA range. | | 345 | * it has to be in the normal kernel VA range. |
346 | */ | | 346 | */ |
347 | vmmap = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, | | 347 | vmmap = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, |
348 | UVM_KMF_VAONLY | UVM_KMF_WAITVA); | | 348 | UVM_KMF_VAONLY | UVM_KMF_WAITVA); |
349 | | | 349 | |
350 | /* | | 350 | /* |
351 | * Allocate DMA map for devices on the bus. | | 351 | * Allocate DMA map for devices on the bus. |
352 | */ | | 352 | */ |
353 | dvmamap = extent_create("dvmamap", | | 353 | dvmamap = extent_create("dvmamap", |
354 | DVMA_MAP_BASE, DVMA_MAP_BASE + DVMA_MAP_AVAIL, | | 354 | DVMA_MAP_BASE, DVMA_MAP_BASE + DVMA_MAP_AVAIL, |
355 | 0, 0, EX_NOWAIT); | | 355 | 0, 0, EX_NOWAIT); |
356 | if (dvmamap == NULL) | | 356 | if (dvmamap == NULL) |
357 | panic("unable to allocate DVMA map"); | | 357 | panic("unable to allocate DVMA map"); |
358 | | | 358 | |
359 | /* | | 359 | /* |
360 | * Set up CPU-specific registers, cache, etc. | | 360 | * Set up CPU-specific registers, cache, etc. |
361 | */ | | 361 | */ |
362 | initcpu(); | | 362 | initcpu(); |
363 | } | | 363 | } |
364 | | | 364 | |
365 | /* | | 365 | /* |
366 | * Info for CTL_HW | | 366 | * Info for CTL_HW |
367 | */ | | 367 | */ |
368 | char machine[16] = MACHINE; /* from <machine/param.h> */ | | 368 | char machine[16] = MACHINE; /* from <machine/param.h> */ |
369 | char kernel_arch[16] = "sun2"; /* XXX needs a sysctl node */ | | 369 | char kernel_arch[16] = "sun2"; /* XXX needs a sysctl node */ |
370 | | | 370 | |
371 | /* | | 371 | /* |
372 | * Determine which Sun2 model we are running on. | | 372 | * Determine which Sun2 model we are running on. |
373 | */ | | 373 | */ |
374 | void | | 374 | void |
375 | identifycpu(void) | | 375 | identifycpu(void) |
376 | { | | 376 | { |
377 | extern char *cpu_string; /* XXX */ | | 377 | extern char *cpu_string; /* XXX */ |
378 | | | 378 | |
379 | /* Other stuff? (VAC, mc6888x version, etc.) */ | | 379 | /* Other stuff? (VAC, mc6888x version, etc.) */ |
380 | /* Note: miniroot cares about the kernel_arch part. */ | | 380 | /* Note: miniroot cares about the kernel_arch part. */ |
381 | cpu_setmodel("%s %s", kernel_arch, cpu_string); | | 381 | cpu_setmodel("%s %s", kernel_arch, cpu_string); |
382 | | | 382 | |
383 | printf("Model: %s\n", cpu_getmodel()); | | 383 | printf("Model: %s\n", cpu_getmodel()); |
384 | } | | 384 | } |
385 | | | 385 | |
386 | /* | | 386 | /* |
387 | * machine dependent system variables. | | 387 | * machine dependent system variables. |
388 | */ | | 388 | */ |
389 | #if 0 /* XXX - Not yet... */ | | 389 | #if 0 /* XXX - Not yet... */ |
390 | static int | | 390 | static int |
391 | sysctl_machdep_root_device(SYSCTLFN_ARGS) | | 391 | sysctl_machdep_root_device(SYSCTLFN_ARGS) |
392 | { | | 392 | { |
393 | struct sysctlnode node = *rnode; | | 393 | struct sysctlnode node = *rnode; |
394 | | | 394 | |
395 | node.sysctl_data = some permutation on root_device; | | 395 | node.sysctl_data = some permutation on root_device; |
396 | node.sysctl_size = strlen(root_device) + 1; | | 396 | node.sysctl_size = strlen(root_device) + 1; |
397 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); | | 397 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); |
398 | } | | 398 | } |
399 | #endif | | 399 | #endif |
400 | | | 400 | |
401 | static int | | 401 | static int |
402 | sysctl_machdep_booted_kernel(SYSCTLFN_ARGS) | | 402 | sysctl_machdep_booted_kernel(SYSCTLFN_ARGS) |
403 | { | | 403 | { |
404 | struct sysctlnode node = *rnode; | | 404 | struct sysctlnode node = *rnode; |
405 | char *cp; | | 405 | char *cp; |
406 | | | 406 | |
407 | cp = prom_getbootfile(); | | 407 | cp = prom_getbootfile(); |
408 | if (cp == NULL || cp[0] == '\0') | | 408 | if (cp == NULL || cp[0] == '\0') |
409 | return (ENOENT); | | 409 | return (ENOENT); |
410 | | | 410 | |
411 | node.sysctl_data = cp; | | 411 | node.sysctl_data = cp; |
412 | node.sysctl_size = strlen(cp) + 1; | | 412 | node.sysctl_size = strlen(cp) + 1; |
413 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); | | 413 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); |
414 | } | | 414 | } |
415 | | | 415 | |
416 | SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") | | 416 | SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") |
417 | { | | 417 | { |
418 | | | 418 | |
419 | sysctl_createv(clog, 0, NULL, NULL, | | 419 | sysctl_createv(clog, 0, NULL, NULL, |
420 | CTLFLAG_PERMANENT, | | 420 | CTLFLAG_PERMANENT, |
421 | CTLTYPE_NODE, "machdep", NULL, | | 421 | CTLTYPE_NODE, "machdep", NULL, |
422 | NULL, 0, NULL, 0, | | 422 | NULL, 0, NULL, 0, |
423 | CTL_MACHDEP, CTL_EOL); | | 423 | CTL_MACHDEP, CTL_EOL); |
424 | | | 424 | |
425 | sysctl_createv(clog, 0, NULL, NULL, | | 425 | sysctl_createv(clog, 0, NULL, NULL, |
426 | CTLFLAG_PERMANENT, | | 426 | CTLFLAG_PERMANENT, |
427 | CTLTYPE_STRUCT, "console_device", NULL, | | 427 | CTLTYPE_STRUCT, "console_device", NULL, |
428 | sysctl_consdev, 0, NULL, sizeof(dev_t), | | 428 | sysctl_consdev, 0, NULL, sizeof(dev_t), |
429 | CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); | | 429 | CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); |
430 | #if 0 /* XXX - Not yet... */ | | 430 | #if 0 /* XXX - Not yet... */ |
431 | sysctl_createv(clog, 0, NULL, NULL, | | 431 | sysctl_createv(clog, 0, NULL, NULL, |
432 | CTLFLAG_PERMANENT, | | 432 | CTLFLAG_PERMANENT, |
433 | CTLTYPE_STRING, "root_device", NULL, | | 433 | CTLTYPE_STRING, "root_device", NULL, |
434 | sysctl_machdep_root_device, 0, NULL, 0, | | 434 | sysctl_machdep_root_device, 0, NULL, 0, |
435 | CTL_MACHDEP, CPU_ROOT_DEVICE, CTL_EOL); | | 435 | CTL_MACHDEP, CPU_ROOT_DEVICE, CTL_EOL); |
436 | #endif | | 436 | #endif |
437 | sysctl_createv(clog, 0, NULL, NULL, | | 437 | sysctl_createv(clog, 0, NULL, NULL, |
438 | CTLFLAG_PERMANENT, | | 438 | CTLFLAG_PERMANENT, |
439 | CTLTYPE_STRING, "booted_kernel", NULL, | | 439 | CTLTYPE_STRING, "booted_kernel", NULL, |
440 | sysctl_machdep_booted_kernel, 0, NULL, 0, | | 440 | sysctl_machdep_booted_kernel, 0, NULL, 0, |
441 | CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL); | | 441 | CTL_MACHDEP, CPU_BOOTED_KERNEL, CTL_EOL); |
442 | } | | 442 | } |
443 | | | 443 | |
444 | /* See: sig_machdep.c */ | | 444 | /* See: sig_machdep.c */ |
445 | | | 445 | |
446 | /* | | 446 | /* |
447 | * Do a sync in preparation for a reboot. | | 447 | * Do a sync in preparation for a reboot. |
448 | * XXX - This could probably be common code. | | 448 | * XXX - This could probably be common code. |
449 | * XXX - And now, most of it is in vfs_shutdown() | | 449 | * XXX - And now, most of it is in vfs_shutdown() |
450 | * XXX - Put waittime checks in there too? | | 450 | * XXX - Put waittime checks in there too? |
451 | */ | | 451 | */ |
452 | int waittime = -1; /* XXX - Who else looks at this? -gwr */ | | 452 | int waittime = -1; /* XXX - Who else looks at this? -gwr */ |
453 | static void | | 453 | static void |
454 | reboot_sync(void) | | 454 | reboot_sync(void) |
455 | { | | 455 | { |
456 | | | 456 | |
457 | /* Check waittime here to localize its use to this function. */ | | 457 | /* Check waittime here to localize its use to this function. */ |
458 | if (waittime >= 0) | | 458 | if (waittime >= 0) |
459 | return; | | 459 | return; |
460 | waittime = 0; | | 460 | waittime = 0; |
461 | vfs_shutdown(); | | 461 | vfs_shutdown(); |
462 | } | | 462 | } |
463 | | | 463 | |
464 | /* | | 464 | /* |
465 | * Common part of the BSD and SunOS reboot system calls. | | 465 | * Common part of the BSD and SunOS reboot system calls. |
466 | */ | | 466 | */ |
467 | __dead void | | 467 | __dead void |
468 | cpu_reboot(int howto, char *user_boot_string) | | 468 | cpu_reboot(int howto, char *user_boot_string) |
469 | { | | 469 | { |
470 | char *bs, *p; | | 470 | char *bs, *p; |
471 | char default_boot_string[8]; | | 471 | char default_boot_string[8]; |
472 | | | 472 | |
473 | /* If system is cold, just halt. (early panic?) */ | | 473 | /* If system is cold, just halt. (early panic?) */ |
474 | if (cold) | | 474 | if (cold) |
475 | goto haltsys; | | 475 | goto haltsys; |
476 | | | 476 | |
477 | /* Un-blank the screen if appropriate. */ | | 477 | /* Un-blank the screen if appropriate. */ |
478 | cnpollc(1); | | 478 | cnpollc(1); |
479 | | | 479 | |
480 | if ((howto & RB_NOSYNC) == 0) { | | 480 | if ((howto & RB_NOSYNC) == 0) { |
481 | reboot_sync(); | | 481 | reboot_sync(); |
482 | /* | | 482 | /* |
483 | * If we've been adjusting the clock, the todr | | 483 | * If we've been adjusting the clock, the todr |
484 | * will be out of synch; adjust it now. | | 484 | * will be out of synch; adjust it now. |
485 | * | | 485 | * |
486 | * XXX - However, if the kernel has been sitting in ddb, | | 486 | * XXX - However, if the kernel has been sitting in ddb, |
487 | * the time will be way off, so don't set the HW clock! | | 487 | * the time will be way off, so don't set the HW clock! |
488 | * XXX - Should do sanity check against HW clock. -gwr | | 488 | * XXX - Should do sanity check against HW clock. -gwr |
489 | */ | | 489 | */ |
490 | /* resettodr(); */ | | 490 | /* resettodr(); */ |
491 | } | | 491 | } |
492 | | | 492 | |
493 | /* Disable interrupts. */ | | 493 | /* Disable interrupts. */ |
494 | splhigh(); | | 494 | splhigh(); |
495 | | | 495 | |
496 | /* Write out a crash dump if asked. */ | | 496 | /* Write out a crash dump if asked. */ |
497 | if (howto & RB_DUMP) | | 497 | if (howto & RB_DUMP) |
498 | dumpsys(); | | 498 | dumpsys(); |
499 | | | 499 | |
500 | /* run any shutdown hooks */ | | 500 | /* run any shutdown hooks */ |
501 | doshutdownhooks(); | | 501 | doshutdownhooks(); |
502 | | | 502 | |
503 | pmf_system_shutdown(boothowto); | | 503 | pmf_system_shutdown(boothowto); |
504 | | | 504 | |
505 | if (howto & RB_HALT) { | | 505 | if (howto & RB_HALT) { |
506 | haltsys: | | 506 | haltsys: |
507 | printf("halted.\n"); | | 507 | printf("halted.\n"); |
508 | prom_halt(); | | 508 | prom_halt(); |
509 | } | | 509 | } |
510 | | | 510 | |
511 | /* | | 511 | /* |
512 | * Automatic reboot. | | 512 | * Automatic reboot. |
513 | */ | | 513 | */ |
514 | bs = user_boot_string; | | 514 | bs = user_boot_string; |
515 | if (bs == NULL) { | | 515 | if (bs == NULL) { |
516 | /* | | 516 | /* |
517 | * Build our own boot string with an empty | | 517 | * Build our own boot string with an empty |
518 | * boot device/file and (maybe) some flags. | | 518 | * boot device/file and (maybe) some flags. |
519 | * The PROM will supply the device/file name. | | 519 | * The PROM will supply the device/file name. |
520 | */ | | 520 | */ |
521 | bs = default_boot_string; | | 521 | bs = default_boot_string; |
522 | *bs = '\0'; | | 522 | *bs = '\0'; |
523 | if (howto & (RB_KDB|RB_ASKNAME|RB_SINGLE)) { | | 523 | if (howto & (RB_KDB|RB_ASKNAME|RB_SINGLE)) { |
524 | /* Append the boot flags. */ | | 524 | /* Append the boot flags. */ |
525 | p = bs; | | 525 | p = bs; |
526 | *p++ = ' '; | | 526 | *p++ = ' '; |
527 | *p++ = '-'; | | 527 | *p++ = '-'; |
528 | if (howto & RB_KDB) | | 528 | if (howto & RB_KDB) |
529 | *p++ = 'd'; | | 529 | *p++ = 'd'; |
530 | if (howto & RB_ASKNAME) | | 530 | if (howto & RB_ASKNAME) |
531 | *p++ = 'a'; | | 531 | *p++ = 'a'; |
532 | if (howto & RB_SINGLE) | | 532 | if (howto & RB_SINGLE) |
533 | *p++ = 's'; | | 533 | *p++ = 's'; |
534 | *p = '\0'; | | 534 | *p = '\0'; |
535 | } | | 535 | } |
536 | } | | 536 | } |
537 | printf("rebooting...\n"); | | 537 | printf("rebooting...\n"); |
538 | prom_boot(bs); | | 538 | prom_boot(bs); |
539 | for (;;) ; | | 539 | for (;;) ; |
540 | /*NOTREACHED*/ | | 540 | /*NOTREACHED*/ |
541 | } | | 541 | } |
542 | | | 542 | |
543 | /* | | 543 | /* |
544 | * These variables are needed by /sbin/savecore | | 544 | * These variables are needed by /sbin/savecore |
545 | */ | | 545 | */ |
546 | uint32_t dumpmag = 0x8fca0101; /* magic number */ | | 546 | uint32_t dumpmag = 0x8fca0101; /* magic number */ |
547 | int dumpsize = 0; /* pages */ | | 547 | int dumpsize = 0; /* pages */ |
548 | long dumplo = 0; /* blocks */ | | 548 | long dumplo = 0; /* blocks */ |
549 | | | 549 | |
550 | #define DUMP_EXTRA 3 /* CPU-dependent extra pages */ | | 550 | #define DUMP_EXTRA 3 /* CPU-dependent extra pages */ |
551 | | | 551 | |
552 | /* | | 552 | /* |
553 | * This is called by main to set dumplo, dumpsize. | | 553 | * This is called by main to set dumplo, dumpsize. |
554 | * Dumps always skip the first PAGE_SIZE of disk space | | 554 | * Dumps always skip the first PAGE_SIZE of disk space |
555 | * in case there might be a disk label stored there. | | 555 | * in case there might be a disk label stored there. |
556 | * If there is extra space, put dump at the end to | | 556 | * If there is extra space, put dump at the end to |
557 | * reduce the chance that swapping trashes it. | | 557 | * reduce the chance that swapping trashes it. |
558 | */ | | 558 | */ |
559 | void | | 559 | void |
560 | cpu_dumpconf(void) | | 560 | cpu_dumpconf(void) |
561 | { | | 561 | { |
562 | int devblks; /* size of dump device in blocks */ | | 562 | int devblks; /* size of dump device in blocks */ |
563 | int dumpblks; /* size of dump image in blocks */ | | 563 | int dumpblks; /* size of dump image in blocks */ |
564 | | | 564 | |
565 | if (dumpdev == NODEV) | | 565 | if (dumpdev == NODEV) |
566 | return; | | 566 | return; |
567 | | | 567 | |
568 | devblks = bdev_size(dumpdev); | | 568 | devblks = bdev_size(dumpdev); |
569 | if (devblks <= ctod(1)) | | 569 | if (devblks <= ctod(1)) |
570 | return; | | 570 | return; |
571 | devblks &= ~(ctod(1)-1); | | 571 | devblks &= ~(ctod(1)-1); |
572 | | | 572 | |
573 | /* | | 573 | /* |
574 | * Note: savecore expects dumpsize to be the | | 574 | * Note: savecore expects dumpsize to be the |
575 | * number of pages AFTER the dump header. | | 575 | * number of pages AFTER the dump header. |
576 | */ | | 576 | */ |
577 | dumpsize = physmem; | | 577 | dumpsize = physmem; |
578 | | | 578 | |
579 | /* Position dump image near end of space, page aligned. */ | | 579 | /* Position dump image near end of space, page aligned. */ |
580 | dumpblks = ctod(physmem + DUMP_EXTRA); | | 580 | dumpblks = ctod(physmem + DUMP_EXTRA); |
581 | dumplo = devblks - dumpblks; | | 581 | dumplo = devblks - dumpblks; |
582 | | | 582 | |
583 | /* If it does not fit, truncate it by moving dumplo. */ | | 583 | /* If it does not fit, truncate it by moving dumplo. */ |
584 | /* Note: Must force signed comparison. */ | | 584 | /* Note: Must force signed comparison. */ |
585 | if (dumplo < ((long)ctod(1))) { | | 585 | if (dumplo < ((long)ctod(1))) { |
586 | dumplo = ctod(1); | | 586 | dumplo = ctod(1); |
587 | dumpsize = dtoc(devblks - dumplo) - DUMP_EXTRA; | | 587 | dumpsize = dtoc(devblks - dumplo) - DUMP_EXTRA; |
588 | } | | 588 | } |
589 | } | | 589 | } |
590 | | | 590 | |
591 | /* Note: gdb looks for "dumppcb" in a kernel crash dump. */ | | 591 | /* Note: gdb looks for "dumppcb" in a kernel crash dump. */ |
592 | struct pcb dumppcb; | | 592 | struct pcb dumppcb; |
593 | extern paddr_t avail_start; | | 593 | extern paddr_t avail_start; |
594 | | | 594 | |
595 | /* | | 595 | /* |
596 | * Write a crash dump. The format while in swap is: | | 596 | * Write a crash dump. The format while in swap is: |
597 | * kcore_seg_t cpu_hdr; | | 597 | * kcore_seg_t cpu_hdr; |
598 | * cpu_kcore_hdr_t cpu_data; | | 598 | * cpu_kcore_hdr_t cpu_data; |
599 | * padding (PAGE_SIZE-sizeof(kcore_seg_t)) | | 599 | * padding (PAGE_SIZE-sizeof(kcore_seg_t)) |
600 | * pagemap (2*PAGE_SIZE) | | 600 | * pagemap (2*PAGE_SIZE) |
601 | * physical memory... | | 601 | * physical memory... |
602 | */ | | 602 | */ |
603 | void | | 603 | void |
604 | dumpsys(void) | | 604 | dumpsys(void) |
605 | { | | 605 | { |
606 | const struct bdevsw *dsw; | | 606 | const struct bdevsw *dsw; |
607 | kcore_seg_t *kseg_p; | | 607 | kcore_seg_t *kseg_p; |
608 | cpu_kcore_hdr_t *chdr_p; | | 608 | cpu_kcore_hdr_t *chdr_p; |
609 | struct sun2_kcore_hdr *sh; | | 609 | struct sun2_kcore_hdr *sh; |
610 | char *vaddr; | | 610 | char *vaddr; |
611 | paddr_t paddr; | | 611 | paddr_t paddr; |
612 | int psize, todo, chunk; | | 612 | int psize, todo, chunk; |
613 | daddr_t blkno; | | 613 | daddr_t blkno; |
614 | int error = 0; | | 614 | int error = 0; |
615 | | | 615 | |
616 | if (dumpdev == NODEV) | | 616 | if (dumpdev == NODEV) |
617 | return; | | 617 | return; |
618 | dsw = bdevsw_lookup(dumpdev); | | 618 | dsw = bdevsw_lookup(dumpdev); |
619 | if (dsw == NULL || dsw->d_psize == NULL) | | 619 | if (dsw == NULL || dsw->d_psize == NULL) |
620 | return; | | 620 | return; |
621 | if (dumppage == 0) | | 621 | if (dumppage == 0) |
622 | return; | | 622 | return; |
623 | | | 623 | |
624 | /* | | 624 | /* |
625 | * For dumps during autoconfiguration, | | 625 | * For dumps during autoconfiguration, |
626 | * if dump device has already configured... | | 626 | * if dump device has already configured... |
627 | */ | | 627 | */ |
628 | if (dumpsize == 0) | | 628 | if (dumpsize == 0) |
629 | cpu_dumpconf(); | | 629 | cpu_dumpconf(); |
630 | if (dumplo <= 0) { | | 630 | if (dumplo <= 0) { |
631 | printf("\ndump to dev %u,%u not possible\n", | | 631 | printf("\ndump to dev %u,%u not possible\n", |
632 | major(dumpdev), minor(dumpdev)); | | 632 | major(dumpdev), minor(dumpdev)); |
633 | return; | | 633 | return; |
634 | } | | 634 | } |
635 | savectx(&dumppcb); | | 635 | savectx(&dumppcb); |
636 | | | 636 | |
637 | psize = bdev_size(dumpdev); | | 637 | psize = bdev_size(dumpdev); |
638 | if (psize == -1) { | | 638 | if (psize == -1) { |
639 | printf("dump area unavailable\n"); | | 639 | printf("dump area unavailable\n"); |
640 | return; | | 640 | return; |
641 | } | | 641 | } |
642 | | | 642 | |
643 | printf("\ndumping to dev %u,%u offset %ld\n", | | 643 | printf("\ndumping to dev %u,%u offset %ld\n", |
644 | major(dumpdev), minor(dumpdev), dumplo); | | 644 | major(dumpdev), minor(dumpdev), dumplo); |
645 | | | 645 | |
646 | /* | | 646 | /* |
647 | * Prepare the dump header, including MMU state. | | 647 | * Prepare the dump header, including MMU state. |
648 | */ | | 648 | */ |
649 | blkno = dumplo; | | 649 | blkno = dumplo; |
650 | todo = dumpsize; /* pages */ | | 650 | todo = dumpsize; /* pages */ |
651 | vaddr = (char*)dumppage; | | 651 | vaddr = (char*)dumppage; |
652 | memset(vaddr, 0, PAGE_SIZE); | | 652 | memset(vaddr, 0, PAGE_SIZE); |
653 | | | 653 | |
654 | /* Set pointers to all three parts. */ | | 654 | /* Set pointers to all three parts. */ |
655 | kseg_p = (kcore_seg_t *)vaddr; | | 655 | kseg_p = (kcore_seg_t *)vaddr; |
656 | chdr_p = (cpu_kcore_hdr_t *) (kseg_p + 1); | | 656 | chdr_p = (cpu_kcore_hdr_t *) (kseg_p + 1); |
657 | sh = &chdr_p->un._sun2; | | 657 | sh = &chdr_p->un._sun2; |
658 | | | 658 | |
659 | /* Fill in kcore_seg_t part. */ | | 659 | /* Fill in kcore_seg_t part. */ |
660 | CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); | | 660 | CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU); |
661 | kseg_p->c_size = (ctob(DUMP_EXTRA) - sizeof(*kseg_p)); | | 661 | kseg_p->c_size = (ctob(DUMP_EXTRA) - sizeof(*kseg_p)); |
662 | | | 662 | |
663 | /* Fill in cpu_kcore_hdr_t part. */ | | 663 | /* Fill in cpu_kcore_hdr_t part. */ |
664 | strncpy(chdr_p->name, kernel_arch, sizeof(chdr_p->name)); | | 664 | strncpy(chdr_p->name, kernel_arch, sizeof(chdr_p->name)); |
665 | chdr_p->page_size = PAGE_SIZE; | | 665 | chdr_p->page_size = PAGE_SIZE; |
666 | chdr_p->kernbase = KERNBASE; | | 666 | chdr_p->kernbase = KERNBASE; |
667 | | | 667 | |
668 | /* Fill in the sun2_kcore_hdr part (MMU state). */ | | 668 | /* Fill in the sun2_kcore_hdr part (MMU state). */ |
669 | pmap_kcore_hdr(sh); | | 669 | pmap_kcore_hdr(sh); |
670 | | | 670 | |
671 | /* Write out the dump header. */ | | 671 | /* Write out the dump header. */ |
672 | error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); | | 672 | error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); |
673 | if (error) | | 673 | if (error) |
674 | goto fail; | | 674 | goto fail; |
675 | blkno += btodb(PAGE_SIZE); | | 675 | blkno += btodb(PAGE_SIZE); |
676 | | | 676 | |
677 | /* translation RAM (pages zero through seven) */ | | 677 | /* translation RAM (pages zero through seven) */ |
678 | for(chunk = 0; chunk < (PAGE_SIZE * 8); chunk += PAGE_SIZE) { | | 678 | for(chunk = 0; chunk < (PAGE_SIZE * 8); chunk += PAGE_SIZE) { |
679 | pmap_get_pagemap((int*)vaddr, chunk); | | 679 | pmap_get_pagemap((int*)vaddr, chunk); |
680 | error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); | | 680 | error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); |
681 | if (error) | | 681 | if (error) |
682 | goto fail; | | 682 | goto fail; |
683 | blkno += btodb(PAGE_SIZE); | | 683 | blkno += btodb(PAGE_SIZE); |
684 | } | | 684 | } |
685 | | | 685 | |
686 | /* | | 686 | /* |
687 | * Now dump physical memory. Have to do it in two chunks. | | 687 | * Now dump physical memory. Have to do it in two chunks. |
688 | * The first chunk is "unmanaged" (by the VM code) and its | | 688 | * The first chunk is "unmanaged" (by the VM code) and its |
689 | * range of physical addresses is not allow in pmap_enter. | | 689 | * range of physical addresses is not allow in pmap_enter. |
690 | * However, that segment is mapped linearly, so we can just | | 690 | * However, that segment is mapped linearly, so we can just |
691 | * use the virtual mappings already in place. The second | | 691 | * use the virtual mappings already in place. The second |
692 | * chunk is done the normal way, using pmap_enter. | | 692 | * chunk is done the normal way, using pmap_enter. |
693 | * | | 693 | * |
694 | * Note that vaddr==(paddr+KERNBASE) for paddr=0 through etext. | | 694 | * Note that vaddr==(paddr+KERNBASE) for paddr=0 through etext. |
695 | */ | | 695 | */ |
696 | | | 696 | |
697 | /* Do the first chunk (0 <= PA < avail_start) */ | | 697 | /* Do the first chunk (0 <= PA < avail_start) */ |
698 | paddr = 0; | | 698 | paddr = 0; |
699 | chunk = btoc(avail_start); | | 699 | chunk = btoc(avail_start); |
700 | if (chunk > todo) | | 700 | if (chunk > todo) |
701 | chunk = todo; | | 701 | chunk = todo; |
702 | do { | | 702 | do { |
703 | if ((todo & 0xf) == 0) | | 703 | if ((todo & 0xf) == 0) |
704 | printf_nolog("\r%4d", todo); | | 704 | printf_nolog("\r%4d", todo); |
705 | vaddr = (char*)(paddr + KERNBASE); | | 705 | vaddr = (char*)(paddr + KERNBASE); |
706 | error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); | | 706 | error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); |
707 | if (error) | | 707 | if (error) |
708 | goto fail; | | 708 | goto fail; |
709 | paddr += PAGE_SIZE; | | 709 | paddr += PAGE_SIZE; |
710 | blkno += btodb(PAGE_SIZE); | | 710 | blkno += btodb(PAGE_SIZE); |
711 | --todo; | | 711 | --todo; |
712 | } while (--chunk > 0); | | 712 | } while (--chunk > 0); |
713 | | | 713 | |
714 | /* Do the second chunk (avail_start <= PA < dumpsize) */ | | 714 | /* Do the second chunk (avail_start <= PA < dumpsize) */ |
715 | vaddr = (char*)vmmap; /* Borrow /dev/mem VA */ | | 715 | vaddr = (char*)vmmap; /* Borrow /dev/mem VA */ |
716 | do { | | 716 | do { |
717 | if ((todo & 0xf) == 0) | | 717 | if ((todo & 0xf) == 0) |
718 | printf_nolog("\r%4d", todo); | | 718 | printf_nolog("\r%4d", todo); |
719 | pmap_kenter_pa(vmmap, paddr | PMAP_NC, VM_PROT_READ, 0); | | 719 | pmap_kenter_pa(vmmap, paddr | PMAP_NC, VM_PROT_READ, 0); |
720 | pmap_update(pmap_kernel()); | | 720 | pmap_update(pmap_kernel()); |
721 | error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); | | 721 | error = (*dsw->d_dump)(dumpdev, blkno, vaddr, PAGE_SIZE); |
722 | pmap_kremove(vmmap, PAGE_SIZE); | | 722 | pmap_kremove(vmmap, PAGE_SIZE); |
723 | pmap_update(pmap_kernel()); | | 723 | pmap_update(pmap_kernel()); |
724 | if (error) | | 724 | if (error) |
725 | goto fail; | | 725 | goto fail; |
726 | paddr += PAGE_SIZE; | | 726 | paddr += PAGE_SIZE; |
727 | blkno += btodb(PAGE_SIZE); | | 727 | blkno += btodb(PAGE_SIZE); |
728 | } while (--todo > 0); | | 728 | } while (--todo > 0); |
729 | | | 729 | |
730 | printf("\rdump succeeded\n"); | | 730 | printf("\rdump succeeded\n"); |
731 | return; | | 731 | return; |
732 | fail: | | 732 | fail: |
733 | printf(" dump error=%d\n", error); | | 733 | printf(" dump error=%d\n", error); |
734 | } | | 734 | } |
735 | | | 735 | |
736 | static void | | 736 | static void |
737 | initcpu(void) | | 737 | initcpu(void) |
738 | { | | 738 | { |
739 | /* XXX: Enable RAM parity/ECC checking? */ | | 739 | /* XXX: Enable RAM parity/ECC checking? */ |
740 | /* XXX: parityenable(); */ | | 740 | /* XXX: parityenable(); */ |
741 | | | 741 | |
742 | } | | 742 | } |
743 | | | 743 | |
744 | /* straptrap() in trap.c */ | | 744 | /* straptrap() in trap.c */ |
745 | | | 745 | |
746 | /* from hp300: badaddr() */ | | 746 | /* from hp300: badaddr() */ |
747 | | | 747 | |
748 | /* XXX: parityenable() ? */ | | 748 | /* XXX: parityenable() ? */ |
749 | /* regdump() moved to regdump.c */ | | 749 | /* regdump() moved to regdump.c */ |
750 | | | 750 | |
751 | /* | | 751 | /* |
752 | * cpu_exec_aout_makecmds(): | | 752 | * cpu_exec_aout_makecmds(): |
753 | * CPU-dependent a.out format hook for execve(). | | 753 | * CPU-dependent a.out format hook for execve(). |
754 | * | | 754 | * |
755 | * Determine if the given exec package refers to something which we | | 755 | * Determine if the given exec package refers to something which we |
756 | * understand and, if so, set up the vmcmds for it. | | 756 | * understand and, if so, set up the vmcmds for it. |
757 | */ | | 757 | */ |
758 | int | | 758 | int |
759 | cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) | | 759 | cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) |
760 | { | | 760 | { |
761 | return ENOEXEC; | | 761 | return ENOEXEC; |
762 | } | | 762 | } |
763 | | | 763 | |
764 | #if 0 | | 764 | #if 0 |
765 | /* | | 765 | /* |
766 | * Soft interrupt support. | | 766 | * Soft interrupt support. |
767 | */ | | 767 | */ |
768 | void | | 768 | void |
769 | isr_soft_request(int level) | | 769 | isr_soft_request(int level) |
770 | { | | 770 | { |
771 | u_char bit; | | 771 | u_char bit; |
772 | | | 772 | |
773 | if ((level < _IPL_SOFT_LEVEL_MIN) || (level > _IPL_SOFT_LEVEL_MAX)) | | 773 | if ((level < _IPL_SOFT_LEVEL_MIN) || (level > _IPL_SOFT_LEVEL_MAX)) |
774 | return; | | 774 | return; |
775 | | | 775 | |
776 | bit = 1 << level; | | 776 | bit = 1 << level; |
777 | enable_reg_or(bit); | | 777 | enable_reg_or(bit); |
778 | } | | 778 | } |
779 | | | 779 | |
780 | void | | 780 | void |
781 | isr_soft_clear(int level) | | 781 | isr_soft_clear(int level) |
782 | { | | 782 | { |
783 | u_char bit; | | 783 | u_char bit; |
784 | | | 784 | |
785 | if ((level < _IPL_SOFT_LEVEL_MIN) || (level > _IPL_SOFT_LEVEL_MAX)) | | 785 | if ((level < _IPL_SOFT_LEVEL_MIN) || (level > _IPL_SOFT_LEVEL_MAX)) |
786 | return; | | 786 | return; |
787 | | | 787 | |
788 | bit = 1 << level; | | 788 | bit = 1 << level; |
789 | enable_reg_and(~bit); | | 789 | enable_reg_and(~bit); |
790 | } | | 790 | } |
791 | #endif | | 791 | #endif |
792 | | | 792 | |
793 | /* | | 793 | /* |
794 | * Like _bus_dmamap_load(), but for raw memory allocated with | | 794 | * Like _bus_dmamap_load(), but for raw memory allocated with |
795 | * bus_dmamem_alloc(). | | 795 | * bus_dmamem_alloc(). |
796 | */ | | 796 | */ |
797 | int | | 797 | int |
798 | _bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs, | | 798 | _bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs, |
799 | int nsegs, bus_size_t size, int flags) | | 799 | int nsegs, bus_size_t size, int flags) |
800 | { | | 800 | { |
801 | struct vm_page *m; | | 801 | struct vm_page *m; |
802 | paddr_t pa; | | 802 | paddr_t pa; |
803 | bus_addr_t dva; | | 803 | bus_addr_t dva; |
804 | bus_size_t sgsize; | | 804 | bus_size_t sgsize; |
805 | struct pglist *mlist; | | 805 | struct pglist *mlist; |
806 | int pagesz = PAGE_SIZE; | | 806 | int pagesz = PAGE_SIZE; |
807 | int error; | | 807 | int error; |
808 | | | 808 | |
809 | /* | | 809 | /* |
810 | * Make sure that on error condition we return "no valid mappings". | | 810 | * Make sure that on error condition we return "no valid mappings". |
811 | */ | | 811 | */ |
812 | map->dm_nsegs = 0; | | 812 | map->dm_nsegs = 0; |
813 | map->dm_mapsize = 0; | | 813 | map->dm_mapsize = 0; |
814 | | | 814 | |
815 | /* Allocate DVMA addresses */ | | 815 | /* Allocate DVMA addresses */ |
816 | sgsize = (size + pagesz - 1) & -pagesz; | | 816 | sgsize = (size + pagesz - 1) & -pagesz; |
817 | | | 817 | |
818 | /* | | 818 | /* |
819 | * If the device can see our entire 24-bit address space, | | 819 | * If the device can see our entire 24-bit address space, |
820 | * we can use any properly aligned virtual addresses. | | 820 | * we can use any properly aligned virtual addresses. |
821 | */ | | 821 | */ |
822 | if ((map->_dm_flags & BUS_DMA_24BIT) != 0) { | | 822 | if ((map->_dm_flags & BUS_DMA_24BIT) != 0) { |
823 | dva = _bus_dma_valloc_skewed(sgsize, map->_dm_boundary, | | 823 | dva = _bus_dma_valloc_skewed(sgsize, map->_dm_boundary, |
824 | pagesz, 0); | | 824 | pagesz, 0); |
825 | if (dva == 0) | | 825 | if (dva == 0) |
826 | return (ENOMEM); | | 826 | return (ENOMEM); |
827 | } | | 827 | } |
828 | | | 828 | |
829 | /* | | 829 | /* |
830 | * Otherwise, we need virtual addresses in DVMA space. | | 830 | * Otherwise, we need virtual addresses in DVMA space. |
831 | */ | | 831 | */ |
832 | else { | | 832 | else { |
833 | error = extent_alloc(dvmamap, sgsize, pagesz, | | 833 | error = extent_alloc(dvmamap, sgsize, pagesz, |
834 | map->_dm_boundary, | | 834 | map->_dm_boundary, |
835 | (flags & BUS_DMA_NOWAIT) == 0 | | 835 | (flags & BUS_DMA_NOWAIT) == 0 |
836 | ? EX_WAITOK : EX_NOWAIT, | | 836 | ? EX_WAITOK : EX_NOWAIT, |
837 | (u_long *)&dva); | | 837 | (u_long *)&dva); |
838 | if (error) | | 838 | if (error) |
839 | return (error); | | 839 | return (error); |
840 | } | | 840 | } |
841 | | | 841 | |
842 | /* Fill in the segment. */ | | 842 | /* Fill in the segment. */ |
843 | map->dm_segs[0].ds_addr = dva; | | 843 | map->dm_segs[0].ds_addr = dva; |
844 | map->dm_segs[0].ds_len = size; | | 844 | map->dm_segs[0].ds_len = size; |
845 | map->dm_segs[0]._ds_va = dva; | | 845 | map->dm_segs[0]._ds_va = dva; |
846 | map->dm_segs[0]._ds_sgsize = sgsize; | | 846 | map->dm_segs[0]._ds_sgsize = sgsize; |
847 | | | 847 | |
848 | /* Map physical pages into MMU */ | | 848 | /* Map physical pages into MMU */ |
849 | mlist = segs[0]._ds_mlist; | | 849 | mlist = segs[0]._ds_mlist; |
850 | for (m = TAILQ_FIRST(mlist); m != NULL; m = TAILQ_NEXT(m,pageq.queue)) { | | 850 | for (m = TAILQ_FIRST(mlist); m != NULL; m = TAILQ_NEXT(m,pageq.queue)) { |
851 | if (sgsize == 0) | | 851 | if (sgsize == 0) |
852 | panic("_bus_dmamap_load_raw: size botch"); | | 852 | panic("_bus_dmamap_load_raw: size botch"); |
853 | pa = VM_PAGE_TO_PHYS(m); | | 853 | pa = VM_PAGE_TO_PHYS(m); |
854 | pmap_enter(pmap_kernel(), dva, | | 854 | pmap_enter(pmap_kernel(), dva, |
855 | (pa & -pagesz) | PMAP_NC, | | 855 | (pa & -pagesz) | PMAP_NC, |
856 | VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED); | | 856 | VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED); |
857 | | | 857 | |
858 | dva += pagesz; | | 858 | dva += pagesz; |
859 | sgsize -= pagesz; | | 859 | sgsize -= pagesz; |
860 | } | | 860 | } |
861 | pmap_update(pmap_kernel()); | | 861 | pmap_update(pmap_kernel()); |
862 | | | 862 | |
863 | /* Make the map truly valid. */ | | 863 | /* Make the map truly valid. */ |
864 | map->dm_nsegs = 1; | | 864 | map->dm_nsegs = 1; |
865 | map->dm_mapsize = size; | | 865 | map->dm_mapsize = size; |
866 | | | 866 | |
867 | return (0); | | 867 | return (0); |
868 | } | | 868 | } |
869 | | | 869 | |
870 | /* | | 870 | /* |
871 | * load DMA map with a linear buffer. | | 871 | * load DMA map with a linear buffer. |
872 | */ | | 872 | */ |
873 | int | | 873 | int |
874 | _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, | | 874 | _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, |
875 | bus_size_t buflen, struct proc *p, int flags) | | 875 | bus_size_t buflen, struct proc *p, int flags) |
876 | { | | 876 | { |
877 | bus_size_t sgsize; | | 877 | bus_size_t sgsize; |
878 | vaddr_t va = (vaddr_t)buf; | | 878 | vaddr_t va = (vaddr_t)buf; |
879 | int pagesz = PAGE_SIZE; | | 879 | int pagesz = PAGE_SIZE; |
880 | bus_addr_t dva; | | 880 | bus_addr_t dva; |
881 | pmap_t pmap; | | 881 | pmap_t pmap; |
882 | int rv __diagused; | | 882 | int rv __diagused; |
883 | | | 883 | |
884 | /* | | 884 | /* |
885 | * Make sure that on error condition we return "no valid mappings". | | 885 | * Make sure that on error condition we return "no valid mappings". |
886 | */ | | 886 | */ |
887 | map->dm_nsegs = 0; | | 887 | map->dm_nsegs = 0; |
888 | map->dm_mapsize = 0; | | 888 | map->dm_mapsize = 0; |
889 | | | 889 | |
890 | if (buflen > map->_dm_size) | | 890 | if (buflen > map->_dm_size) |
891 | return (EINVAL); | | 891 | return (EINVAL); |
892 | | | 892 | |
893 | /* | | 893 | /* |
894 | * A 24-bit device can see all of our kernel address space, so | | 894 | * A 24-bit device can see all of our kernel address space, so |
895 | * if we have KVAs, we can just load them as-is, no mapping | | 895 | * if we have KVAs, we can just load them as-is, no mapping |
896 | * necessary. | | 896 | * necessary. |
897 | */ | | 897 | */ |
898 | if ((map->_dm_flags & BUS_DMA_24BIT) != 0 && p == NULL) { | | 898 | if ((map->_dm_flags & BUS_DMA_24BIT) != 0 && p == NULL) { |
899 | /* | | 899 | /* |
900 | * XXX Need to implement "don't DMA across this boundry". | | 900 | * XXX Need to implement "don't DMA across this boundry". |
901 | */ | | 901 | */ |
902 | if (map->_dm_boundary != 0) | | 902 | if (map->_dm_boundary != 0) |
903 | panic("bus_dmamap_load: boundaries not implemented"); | | 903 | panic("bus_dmamap_load: boundaries not implemented"); |
904 | map->dm_mapsize = buflen; | | 904 | map->dm_mapsize = buflen; |
905 | map->dm_nsegs = 1; | | 905 | map->dm_nsegs = 1; |
906 | map->dm_segs[0].ds_addr = (bus_addr_t)va; | | 906 | map->dm_segs[0].ds_addr = (bus_addr_t)va; |
907 | map->dm_segs[0].ds_len = buflen; | | 907 | map->dm_segs[0].ds_len = buflen; |
908 | map->_dm_flags |= _BUS_DMA_DIRECTMAP; | | 908 | map->_dm_flags |= _BUS_DMA_DIRECTMAP; |
909 | return (0); | | 909 | return (0); |
910 | } | | 910 | } |
911 | | | 911 | |
912 | /* | | 912 | /* |
913 | * Allocate a region in DVMA space. | | 913 | * Allocate a region in DVMA space. |
914 | */ | | 914 | */ |
915 | sgsize = m68k_round_page(buflen + (va & (pagesz - 1))); | | 915 | sgsize = m68k_round_page(buflen + (va & (pagesz - 1))); |
916 | | | 916 | |
917 | if (extent_alloc(dvmamap, sgsize, pagesz, map->_dm_boundary, | | 917 | if (extent_alloc(dvmamap, sgsize, pagesz, map->_dm_boundary, |
918 | (flags & BUS_DMA_NOWAIT) == 0 ? EX_WAITOK : EX_NOWAIT, | | 918 | (flags & BUS_DMA_NOWAIT) == 0 ? EX_WAITOK : EX_NOWAIT, |
919 | (u_long *)&dva) != 0) { | | 919 | (u_long *)&dva) != 0) { |
920 | return (ENOMEM); | | 920 | return (ENOMEM); |
921 | } | | 921 | } |
922 | | | 922 | |
923 | /* Fill in the segment. */ | | 923 | /* Fill in the segment. */ |
924 | map->dm_segs[0].ds_addr = dva + (va & (pagesz - 1)); | | 924 | map->dm_segs[0].ds_addr = dva + (va & (pagesz - 1)); |
925 | map->dm_segs[0].ds_len = buflen; | | 925 | map->dm_segs[0].ds_len = buflen; |
926 | map->dm_segs[0]._ds_va = dva; | | 926 | map->dm_segs[0]._ds_va = dva; |
927 | map->dm_segs[0]._ds_sgsize = sgsize; | | 927 | map->dm_segs[0]._ds_sgsize = sgsize; |
928 | | | 928 | |
929 | /* | | 929 | /* |
930 | * Now map the DVMA addresses we allocated to point to the | | 930 | * Now map the DVMA addresses we allocated to point to the |
931 | * pages of the caller's buffer. | | 931 | * pages of the caller's buffer. |
932 | */ | | 932 | */ |
933 | if (p != NULL) | | 933 | if (p != NULL) |
934 | pmap = p->p_vmspace->vm_map.pmap; | | 934 | pmap = p->p_vmspace->vm_map.pmap; |
935 | else | | 935 | else |
936 | pmap = pmap_kernel(); | | 936 | pmap = pmap_kernel(); |
937 | | | 937 | |
938 | for (; buflen > 0; ) { | | 938 | for (; buflen > 0; ) { |
939 | paddr_t pa; | | 939 | paddr_t pa; |
940 | /* | | 940 | /* |
941 | * Get the physical address for this page. | | 941 | * Get the physical address for this page. |
942 | */ | | 942 | */ |
943 | rv = pmap_extract(pmap, va, &pa); | | 943 | rv = pmap_extract(pmap, va, &pa); |
944 | #ifdef DIAGNOSTIC | | 944 | #ifdef DIAGNOSTIC |
945 | if (!rv) | | 945 | if (!rv) |
946 | panic("_bus_dmamap_load: no page"); | | 946 | panic("_bus_dmamap_load: no page"); |
947 | #endif /* DIAGNOSTIC */ | | 947 | #endif /* DIAGNOSTIC */ |
948 | | | 948 | |
949 | /* | | 949 | /* |
950 | * Compute the segment size, and adjust counts. | | 950 | * Compute the segment size, and adjust counts. |
951 | */ | | 951 | */ |
952 | sgsize = pagesz - (va & (pagesz - 1)); | | 952 | sgsize = pagesz - (va & (pagesz - 1)); |
953 | if (buflen < sgsize) | | 953 | if (buflen < sgsize) |
954 | sgsize = buflen; | | 954 | sgsize = buflen; |
955 | | | 955 | |
956 | pmap_enter(pmap_kernel(), dva, | | 956 | pmap_enter(pmap_kernel(), dva, |
957 | (pa & -pagesz) | PMAP_NC, | | 957 | (pa & -pagesz) | PMAP_NC, |
958 | VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED); | | 958 | VM_PROT_READ|VM_PROT_WRITE, PMAP_WIRED); |
959 | | | 959 | |
960 | dva += pagesz; | | 960 | dva += pagesz; |
961 | va += sgsize; | | 961 | va += sgsize; |
962 | buflen -= sgsize; | | 962 | buflen -= sgsize; |
963 | } | | 963 | } |
964 | pmap_update(pmap_kernel()); | | 964 | pmap_update(pmap_kernel()); |
965 | | | 965 | |
966 | /* Make the map truly valid. */ | | 966 | /* Make the map truly valid. */ |
967 | map->dm_nsegs = 1; | | 967 | map->dm_nsegs = 1; |
968 | map->dm_mapsize = map->dm_segs[0].ds_len; | | 968 | map->dm_mapsize = map->dm_segs[0].ds_len; |
969 | | | 969 | |
970 | return (0); | | 970 | return (0); |
971 | } | | 971 | } |
972 | | | 972 | |
973 | /* | | 973 | /* |
974 | * unload a DMA map. | | 974 | * unload a DMA map. |
975 | */ | | 975 | */ |
976 | void | | 976 | void |
977 | _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) | | 977 | _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) |
978 | { | | 978 | { |
979 | bus_dma_segment_t *segs = map->dm_segs; | | 979 | bus_dma_segment_t *segs = map->dm_segs; |
980 | int nsegs = map->dm_nsegs; | | 980 | int nsegs = map->dm_nsegs; |
981 | int flags = map->_dm_flags; | | 981 | int flags = map->_dm_flags; |
982 | bus_addr_t dva; | | 982 | bus_addr_t dva; |
983 | bus_size_t len; | | 983 | bus_size_t len; |
984 | int s, error; | | 984 | int s, error; |
985 | | | 985 | |
986 | if (nsegs != 1) | | 986 | if (nsegs != 1) |
987 | panic("_bus_dmamem_unload: nsegs = %d", nsegs); | | 987 | panic("_bus_dmamem_unload: nsegs = %d", nsegs); |
988 | | | 988 | |
989 | /* | | 989 | /* |
990 | * _BUS_DMA_DIRECTMAP is set iff this map was loaded using | | 990 | * _BUS_DMA_DIRECTMAP is set iff this map was loaded using |
991 | * _bus_dmamap_load for a 24-bit device. | | 991 | * _bus_dmamap_load for a 24-bit device. |
992 | */ | | 992 | */ |
993 | if ((flags & _BUS_DMA_DIRECTMAP) != 0) { | | 993 | if ((flags & _BUS_DMA_DIRECTMAP) != 0) { |
994 | /* Nothing to release */ | | 994 | /* Nothing to release */ |
995 | map->_dm_flags &= ~_BUS_DMA_DIRECTMAP; | | 995 | map->_dm_flags &= ~_BUS_DMA_DIRECTMAP; |
996 | } | | 996 | } |
997 | | | 997 | |
998 | /* | | 998 | /* |
999 | * Otherwise, this map was loaded using _bus_dmamap_load for a | | 999 | * Otherwise, this map was loaded using _bus_dmamap_load for a |
1000 | * non-24-bit device, or using _bus_dmamap_load_raw. | | 1000 | * non-24-bit device, or using _bus_dmamap_load_raw. |
1001 | */ | | 1001 | */ |
1002 | else { | | 1002 | else { |
1003 | dva = segs[0]._ds_va & -PAGE_SIZE; | | 1003 | dva = segs[0]._ds_va & -PAGE_SIZE; |
1004 | len = segs[0]._ds_sgsize; | | 1004 | len = segs[0]._ds_sgsize; |
1005 | | | 1005 | |
1006 | /* | | 1006 | /* |
1007 | * Unmap the DVMA addresses. | | 1007 | * Unmap the DVMA addresses. |
1008 | */ | | 1008 | */ |
1009 | pmap_remove(pmap_kernel(), dva, dva + len); | | 1009 | pmap_remove(pmap_kernel(), dva, dva + len); |
1010 | pmap_update(pmap_kernel()); | | 1010 | pmap_update(pmap_kernel()); |
1011 | | | 1011 | |
1012 | /* | | 1012 | /* |
1013 | * Free the DVMA addresses. | | 1013 | * Free the DVMA addresses. |
1014 | */ | | 1014 | */ |
1015 | if ((flags & BUS_DMA_24BIT) != 0) { | | 1015 | if ((flags & BUS_DMA_24BIT) != 0) { |
1016 | /* | | 1016 | /* |
1017 | * This map was loaded using _bus_dmamap_load_raw | | 1017 | * This map was loaded using _bus_dmamap_load_raw |
1018 | * for a 24-bit device. | | 1018 | * for a 24-bit device. |
1019 | */ | | 1019 | */ |
1020 | uvm_unmap(kernel_map, dva, dva + len); | | 1020 | uvm_unmap(kernel_map, dva, dva + len); |
1021 | } else { | | 1021 | } else { |
1022 | /* | | 1022 | /* |
1023 | * This map was loaded using _bus_dmamap_load or | | 1023 | * This map was loaded using _bus_dmamap_load or |
1024 | * _bus_dmamap_load_raw for a non-24-bit device. | | 1024 | * _bus_dmamap_load_raw for a non-24-bit device. |
1025 | */ | | 1025 | */ |
1026 | s = splhigh(); | | 1026 | s = splhigh(); |
1027 | error = extent_free(dvmamap, dva, len, EX_NOWAIT); | | 1027 | error = extent_free(dvmamap, dva, len, EX_NOWAIT); |
1028 | splx(s); | | 1028 | splx(s); |
1029 | if (error != 0) | | 1029 | if (error != 0) |
1030 | printf("warning: %ld of DVMA space lost\n", len); | | 1030 | printf("warning: %ld of DVMA space lost\n", len); |
1031 | } | | 1031 | } |
1032 | } | | 1032 | } |
1033 | | | 1033 | |
1034 | /* Mark the mappings as invalid. */ | | 1034 | /* Mark the mappings as invalid. */ |
1035 | map->dm_mapsize = 0; | | 1035 | map->dm_mapsize = 0; |
1036 | map->dm_nsegs = 0; | | 1036 | map->dm_nsegs = 0; |
1037 | } | | 1037 | } |
1038 | | | 1038 | |
1039 | /* | | 1039 | /* |
1040 | * Translate a VME address and address modifier | | 1040 | * Translate a VME address and address modifier |
1041 | * into a CPU physical address and page type. | | 1041 | * into a CPU physical address and page type. |
1042 | */ | | 1042 | */ |
1043 | int | | 1043 | int |
1044 | vmebus_translate(vme_am_t mod, vme_addr_t addr, bus_type_t *btp, | | 1044 | vmebus_translate(vme_am_t mod, vme_addr_t addr, bus_type_t *btp, |
1045 | bus_addr_t *bap) | | 1045 | bus_addr_t *bap) |
1046 | { | | 1046 | { |
1047 | bus_addr_t base; | | 1047 | bus_addr_t base; |
1048 | | | 1048 | |
1049 | switch(mod) { | | 1049 | switch(mod) { |
1050 | #define _DS (VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA) | | 1050 | #define _DS (VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA) |
1051 | | | 1051 | |
1052 | case (VME_AM_A16|_DS): | | 1052 | case (VME_AM_A16|_DS): |
1053 | base = 0x00ff0000; | | 1053 | base = 0x00ff0000; |
1054 | break; | | 1054 | break; |
1055 | | | 1055 | |
1056 | case (VME_AM_A24|_DS): | | 1056 | case (VME_AM_A24|_DS): |
1057 | base = 0; | | 1057 | base = 0; |
1058 | break; | | 1058 | break; |
1059 | | | 1059 | |
1060 | default: | | 1060 | default: |
1061 | return (ENOENT); | | 1061 | return (ENOENT); |
1062 | #undef _DS | | 1062 | #undef _DS |
1063 | } | | 1063 | } |
1064 | | | 1064 | |
1065 | *bap = base | addr; | | 1065 | *bap = base | addr; |
1066 | *btp = (*bap & 0x800000 ? PMAP_VME8 : PMAP_VME0); | | 1066 | *btp = (*bap & 0x800000 ? PMAP_VME8 : PMAP_VME0); |
1067 | return (0); | | 1067 | return (0); |
1068 | } | | 1068 | } |
1069 | | | 1069 | |
1070 | /* | | 1070 | /* |
1071 | * If we can find a mapping that was established by the PROM, use it. | | 1071 | * If we can find a mapping that was established by the PROM, use it. |
1072 | */ | | 1072 | */ |
1073 | int | | 1073 | int |
1074 | find_prom_map(paddr_t pa, bus_type_t iospace, int len, vaddr_t *vap) | | 1074 | find_prom_map(paddr_t pa, bus_type_t iospace, int len, vaddr_t *vap) |
1075 | { | | 1075 | { |
1076 | u_long pf; | | 1076 | u_long pf; |
1077 | int pgtype; | | 1077 | int pgtype; |
1078 | vaddr_t va, eva; | | 1078 | vaddr_t va, eva; |
1079 | int sme; | | 1079 | int sme; |
1080 | u_long pte; | | 1080 | u_long pte; |
1081 | int saved_ctx; | | 1081 | int saved_ctx; |
1082 | | | 1082 | |
1083 | /* | | 1083 | /* |
1084 | * The mapping must fit entirely within one page. | | 1084 | * The mapping must fit entirely within one page. |
1085 | */ | | 1085 | */ |
1086 | if ((((u_long)pa & PGOFSET) + len) > PAGE_SIZE) | | 1086 | if ((((u_long)pa & PGOFSET) + len) > PAGE_SIZE) |
1087 | return EINVAL; | | 1087 | return EINVAL; |
1088 | | | 1088 | |
1089 | pf = PA_PGNUM(pa); | | 1089 | pf = PA_PGNUM(pa); |
1090 | pgtype = iospace << PG_MOD_SHIFT; | | 1090 | pgtype = iospace << PG_MOD_SHIFT; |
1091 | saved_ctx = kernel_context(); | | 1091 | saved_ctx = kernel_context(); |
1092 | | | 1092 | |
1093 | /* | | 1093 | /* |
1094 | * Walk the PROM address space, looking for a page with the | | 1094 | * Walk the PROM address space, looking for a page with the |
1095 | * mapping we want. | | 1095 | * mapping we want. |
1096 | */ | | 1096 | */ |
1097 | for (va = SUN_MONSTART; va < SUN_MONEND; ) { | | 1097 | for (va = SUN_MONSTART; va < SUN_MONEND; ) { |
1098 | | | 1098 | |
1099 | /* | | 1099 | /* |
1100 | * Make sure this segment is mapped. | | 1100 | * Make sure this segment is mapped. |
1101 | */ | | 1101 | */ |
1102 | sme = get_segmap(va); | | 1102 | sme = get_segmap(va); |
1103 | if (sme == SEGINV) { | | 1103 | if (sme == SEGINV) { |
1104 | va += NBSG; | | 1104 | va += NBSG; |
1105 | continue; /* next segment */ | | 1105 | continue; /* next segment */ |
1106 | } | | 1106 | } |
1107 | | | 1107 | |
1108 | /* | | 1108 | /* |
1109 | * Walk the pages of this segment. | | 1109 | * Walk the pages of this segment. |
1110 | */ | | 1110 | */ |
1111 | for(eva = va + NBSG; va < eva; va += PAGE_SIZE) { | | 1111 | for(eva = va + NBSG; va < eva; va += PAGE_SIZE) { |
1112 | pte = get_pte(va); | | 1112 | pte = get_pte(va); |
1113 | | | 1113 | |
1114 | if ((pte & (PG_VALID | PG_TYPE)) == | | 1114 | if ((pte & (PG_VALID | PG_TYPE)) == |
1115 | (PG_VALID | pgtype) && | | 1115 | (PG_VALID | pgtype) && |
1116 | PG_PFNUM(pte) == pf) | | 1116 | PG_PFNUM(pte) == pf) |
1117 | { | | 1117 | { |
1118 | /* | | 1118 | /* |
1119 | * Found the PROM mapping. | | 1119 | * Found the PROM mapping. |
1120 | * note: preserve page offset | | 1120 | * note: preserve page offset |
1121 | */ | | 1121 | */ |
1122 | *vap = (va | ((vaddr_t)pa & PGOFSET)); | | 1122 | *vap = (va | ((vaddr_t)pa & PGOFSET)); |
1123 | restore_context(saved_ctx); | | 1123 | restore_context(saved_ctx); |
1124 | return 0; | | 1124 | return 0; |
1125 | } | | 1125 | } |
1126 | } | | 1126 | } |
1127 | } | | 1127 | } |
1128 | restore_context(saved_ctx); | | 1128 | restore_context(saved_ctx); |
1129 | return ENOENT; | | 1129 | return ENOENT; |
1130 | } | | 1130 | } |
1131 | | | 1131 | |
1132 | int | | 1132 | int |
1133 | mm_md_physacc(paddr_t pa, vm_prot_t prot) | | 1133 | mm_md_physacc(paddr_t pa, vm_prot_t prot) |
1134 | { | | 1134 | { |
1135 | | | 1135 | |
1136 | /* Allow access only in "managed" RAM. */ | | 1136 | /* Allow access only in "managed" RAM. */ |
1137 | if (pa < avail_start || pa >= avail_end) | | 1137 | if (pa < avail_start || pa >= avail_end) |
1138 | return EFAULT; | | 1138 | return EFAULT; |
1139 | return 0; | | 1139 | return 0; |
1140 | } | | 1140 | } |
1141 | | | 1141 | |
1142 | bool | | 1142 | bool |
1143 | mm_md_direct_mapped_phys(paddr_t paddr, vaddr_t *vaddr) | | 1143 | mm_md_direct_mapped_phys(paddr_t paddr, vaddr_t *vaddr) |
1144 | { | | 1144 | { |
1145 | | | 1145 | |
1146 | if (paddr >= avail_start) | | 1146 | if (paddr >= avail_start) |
1147 | return false; | | 1147 | return false; |
1148 | *vaddr = paddr; | | 1148 | *vaddr = paddr; |
1149 | return true; | | 1149 | return true; |
1150 | } | | 1150 | } |
1151 | | | 1151 | |
1152 | /* | | 1152 | /* |
1153 | * Allow access to the PROM mapping similar to uvm_kernacc(). | | 1153 | * Allow access to the PROM mapping similar to uvm_kernacc(). |
1154 | */ | | 1154 | */ |
1155 | int | | 1155 | int |
1156 | mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled) | | 1156 | mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled) |
1157 | { | | 1157 | { |
1158 | | | 1158 | |
1159 | if ((vaddr_t)ptr < SUN2_PROM_BASE || (vaddr_t)ptr > SUN2_MONEND) { | | 1159 | if ((vaddr_t)ptr < SUN2_PROM_BASE || (vaddr_t)ptr > SUN2_MONEND) { |
1160 | *handled = false; | | 1160 | *handled = false; |
1161 | return 0; | | 1161 | return 0; |
1162 | } | | 1162 | } |
1163 | | | 1163 | |
1164 | *handled = true; | | 1164 | *handled = true; |
1165 | /* Read in the PROM itself is OK, write not. */ | | 1165 | /* Read in the PROM itself is OK, write not. */ |
1166 | if ((prot & VM_PROT_WRITE) == 0) | | 1166 | if ((prot & VM_PROT_WRITE) == 0) |
1167 | return 0; | | 1167 | return 0; |
1168 | return EFAULT; | | 1168 | return EFAULT; |
1169 | } | | 1169 | } |