| @@ -1,883 +1,896 @@ | | | @@ -1,883 +1,896 @@ |
1 | /* $NetBSD: machdep.c,v 1.154 2008/11/30 18:21:32 martin Exp $ */ | | 1 | /* $NetBSD: machdep.c,v 1.155 2009/01/03 06:36:58 tsutsui Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. | | 4 | * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. |
5 | * All rights reserved. | | 5 | * 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.63 91/04/24$ | | 35 | * from: Utah $Hdr: machdep.c 1.63 91/04/24$ |
36 | * | | 36 | * |
37 | * @(#)machdep.c 7.16 (Berkeley) 6/3/91 | | 37 | * @(#)machdep.c 7.16 (Berkeley) 6/3/91 |
38 | */ | | 38 | */ |
39 | /* | | 39 | /* |
40 | * Copyright (c) 1988 University of Utah. | | 40 | * Copyright (c) 1988 University of Utah. |
41 | * | | 41 | * |
42 | * This code is derived from software contributed to Berkeley by | | 42 | * This code is derived from software contributed to Berkeley by |
43 | * the Systems Programming Group of the University of Utah Computer | | 43 | * the Systems Programming Group of the University of Utah Computer |
44 | * Science Department. | | 44 | * Science Department. |
45 | * | | 45 | * |
46 | * Redistribution and use in source and binary forms, with or without | | 46 | * Redistribution and use in source and binary forms, with or without |
47 | * modification, are permitted provided that the following conditions | | 47 | * modification, are permitted provided that the following conditions |
48 | * are met: | | 48 | * are met: |
49 | * 1. Redistributions of source code must retain the above copyright | | 49 | * 1. Redistributions of source code must retain the above copyright |
50 | * notice, this list of conditions and the following disclaimer. | | 50 | * notice, this list of conditions and the following disclaimer. |
51 | * 2. Redistributions in binary form must reproduce the above copyright | | 51 | * 2. Redistributions in binary form must reproduce the above copyright |
52 | * notice, this list of conditions and the following disclaimer in the | | 52 | * notice, this list of conditions and the following disclaimer in the |
53 | * documentation and/or other materials provided with the distribution. | | 53 | * documentation and/or other materials provided with the distribution. |
54 | * 3. All advertising materials mentioning features or use of this software | | 54 | * 3. All advertising materials mentioning features or use of this software |
55 | * must display the following acknowledgement: | | 55 | * must display the following acknowledgement: |
56 | * This product includes software developed by the University of | | 56 | * This product includes software developed by the University of |
57 | * California, Berkeley and its contributors. | | 57 | * California, Berkeley and its contributors. |
58 | * 4. Neither the name of the University nor the names of its contributors | | 58 | * 4. Neither the name of the University nor the names of its contributors |
59 | * may be used to endorse or promote products derived from this software | | 59 | * may be used to endorse or promote products derived from this software |
60 | * without specific prior written permission. | | 60 | * without specific prior written permission. |
61 | * | | 61 | * |
62 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 62 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
63 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 63 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
64 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 64 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
65 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 65 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
66 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 66 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
67 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 67 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
68 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 68 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
69 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 69 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
70 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 70 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
71 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 71 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
72 | * SUCH DAMAGE. | | 72 | * SUCH DAMAGE. |
73 | * | | 73 | * |
74 | * from: Utah $Hdr: machdep.c 1.63 91/04/24$ | | 74 | * from: Utah $Hdr: machdep.c 1.63 91/04/24$ |
75 | * | | 75 | * |
76 | * @(#)machdep.c 7.16 (Berkeley) 6/3/91 | | 76 | * @(#)machdep.c 7.16 (Berkeley) 6/3/91 |
77 | */ | | 77 | */ |
78 | | | 78 | |
79 | #include <sys/cdefs.h> | | 79 | #include <sys/cdefs.h> |
80 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.154 2008/11/30 18:21:32 martin Exp $"); | | 80 | __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.155 2009/01/03 06:36:58 tsutsui Exp $"); |
81 | | | 81 | |
82 | #include "opt_ddb.h" | | 82 | #include "opt_ddb.h" |
83 | #include "opt_compat_netbsd.h" | | 83 | #include "opt_compat_netbsd.h" |
84 | #include "opt_mbtype.h" | | 84 | #include "opt_mbtype.h" |
85 | #include "opt_panicbutton.h" | | 85 | #include "opt_panicbutton.h" |
86 | | | 86 | |
87 | #include <sys/param.h> | | 87 | #include <sys/param.h> |
88 | #include <sys/systm.h> | | 88 | #include <sys/systm.h> |
89 | #include <sys/signalvar.h> | | 89 | #include <sys/signalvar.h> |
90 | #include <sys/kernel.h> | | 90 | #include <sys/kernel.h> |
91 | #include <sys/proc.h> | | 91 | #include <sys/proc.h> |
92 | #include <sys/buf.h> | | 92 | #include <sys/buf.h> |
93 | #include <sys/reboot.h> | | 93 | #include <sys/reboot.h> |
94 | #include <sys/conf.h> | | 94 | #include <sys/conf.h> |
95 | #include <sys/file.h> | | 95 | #include <sys/file.h> |
96 | #include <sys/device.h> | | 96 | #include <sys/device.h> |
97 | #include <sys/malloc.h> | | 97 | #include <sys/malloc.h> |
98 | #include <sys/mbuf.h> | | 98 | #include <sys/mbuf.h> |
99 | #include <sys/msgbuf.h> | | 99 | #include <sys/msgbuf.h> |
100 | #include <sys/user.h> | | 100 | #include <sys/user.h> |
101 | #include <sys/vnode.h> | | 101 | #include <sys/vnode.h> |
102 | #include <sys/queue.h> | | 102 | #include <sys/queue.h> |
103 | #include <sys/mount.h> | | 103 | #include <sys/mount.h> |
104 | #include <sys/syscallargs.h> | | 104 | #include <sys/syscallargs.h> |
105 | #include <sys/ksyms.h> | | 105 | #include <sys/ksyms.h> |
106 | #include <sys/intr.h> | | 106 | #include <sys/intr.h> |
107 | #include <sys/exec.h> | | 107 | #include <sys/exec.h> |
108 | #include <sys/cpu.h> | | 108 | #include <sys/cpu.h> |
109 | #if defined(DDB) && defined(__ELF__) | | 109 | #if defined(DDB) && defined(__ELF__) |
110 | #include <sys/exec_elf.h> | | 110 | #include <sys/exec_elf.h> |
111 | #endif | | 111 | #endif |
112 | | | 112 | |
113 | #undef PS /* XXX netccitt/pk.h conflict with machine/reg.h? */ | | 113 | #undef PS /* XXX netccitt/pk.h conflict with machine/reg.h? */ |
114 | | | 114 | |
115 | #define MAXMEM 64*1024 /* XXX - from cmap.h */ | | 115 | #define MAXMEM 64*1024 /* XXX - from cmap.h */ |
116 | #include <uvm/uvm_extern.h> | | 116 | #include <uvm/uvm_extern.h> |
117 | | | 117 | |
118 | #include <sys/sysctl.h> | | 118 | #include <sys/sysctl.h> |
119 | | | 119 | |
120 | #include <machine/db_machdep.h> | | 120 | #include <machine/db_machdep.h> |
121 | #include <ddb/db_sym.h> | | 121 | #include <ddb/db_sym.h> |
122 | #include <ddb/db_extern.h> | | 122 | #include <ddb/db_extern.h> |
123 | | | 123 | |
124 | #include <machine/reg.h> | | 124 | #include <machine/reg.h> |
125 | #include <machine/psl.h> | | 125 | #include <machine/psl.h> |
126 | #include <machine/pte.h> | | 126 | #include <machine/pte.h> |
127 | | | 127 | |
128 | #include <dev/cons.h> | | 128 | #include <dev/cons.h> |
129 | | | 129 | |
130 | #include "ksyms.h" | | 130 | #include "ksyms.h" |
131 | | | 131 | |
132 | static void bootsync(void); | | 132 | static void bootsync(void); |
133 | static void call_sicallbacks(void); | | 133 | static void call_sicallbacks(void); |
134 | static void identifycpu(void); | | 134 | static void identifycpu(void); |
135 | void straymfpint(int, u_short); | | 135 | void straymfpint(int, u_short); |
136 | void straytrap(int, u_short); | | 136 | void straytrap(int, u_short); |
137 | | | 137 | |
138 | #ifdef _MILANHW_ | | 138 | #ifdef _MILANHW_ |
139 | void nmihandler(void); | | 139 | void nmihandler(void); |
140 | #endif | | 140 | #endif |
141 | | | 141 | |
142 | struct vm_map *mb_map = NULL; | | 142 | struct vm_map *mb_map = NULL; |
143 | struct vm_map *phys_map = NULL; | | 143 | struct vm_map *phys_map = NULL; |
144 | | | 144 | |
145 | void * msgbufaddr; | | 145 | void * msgbufaddr; |
146 | vaddr_t msgbufpa; | | 146 | vaddr_t msgbufpa; |
147 | | | 147 | |
148 | int physmem = MAXMEM; /* max supported memory, changes to actual */ | | 148 | int physmem = MAXMEM; /* max supported memory, changes to actual */ |
149 | /* | | 149 | /* |
150 | * safepri is a safe priority for sleep to set for a spin-wait | | 150 | * safepri is a safe priority for sleep to set for a spin-wait |
151 | * during autoconfiguration or after a panic. | | 151 | * during autoconfiguration or after a panic. |
152 | */ | | 152 | */ |
153 | int safepri = PSL_LOWIPL; | | 153 | int safepri = PSL_LOWIPL; |
154 | extern int freebufspace; | | 154 | extern int freebufspace; |
155 | extern u_int lowram; | | 155 | extern u_int lowram; |
156 | | | 156 | |
157 | /* | | 157 | /* |
158 | * For the fpu emulation and the fpu driver | | 158 | * For the fpu emulation and the fpu driver |
159 | */ | | 159 | */ |
160 | int fputype = 0; | | 160 | int fputype = 0; |
161 | | | 161 | |
162 | /* the following is used externally (sysctl_hw) */ | | 162 | /* the following is used externally (sysctl_hw) */ |
163 | char machine[] = MACHINE; /* from <machine/param.h> */ | | 163 | char machine[] = MACHINE; /* from <machine/param.h> */ |
164 | | | 164 | |
165 | /* Our exported CPU info; we can have only one. */ | | 165 | /* Our exported CPU info; we can have only one. */ |
166 | struct cpu_info cpu_info_store; | | 166 | struct cpu_info cpu_info_store; |
167 | | | 167 | |
168 | /* | | 168 | /* |
169 | * Console initialization: called early on from main, | | 169 | * Console initialization: called early on from main, |
170 | * before vm init or startup. Do enough configuration | | 170 | * before vm init or startup. Do enough configuration |
171 | * to choose and initialize a console. | | 171 | * to choose and initialize a console. |
172 | */ | | 172 | */ |
173 | void | | 173 | void |
174 | consinit(void) | | 174 | consinit(void) |
175 | { | | 175 | { |
176 | int i; | | 176 | int i; |
177 | | | 177 | |
178 | /* | | 178 | /* |
179 | * Initialize error message buffer. pmap_bootstrap() has | | 179 | * Initialize error message buffer. pmap_bootstrap() has |
180 | * positioned this at the end of kernel memory segment - map | | 180 | * positioned this at the end of kernel memory segment - map |
181 | * and initialize it now. | | 181 | * and initialize it now. |
182 | */ | | 182 | */ |
183 | for (i = 0; i < btoc(MSGBUFSIZE); i++) | | 183 | for (i = 0; i < btoc(MSGBUFSIZE); i++) |
184 | pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE, | | 184 | pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE, |
185 | msgbufpa + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, | | 185 | msgbufpa + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, |
186 | VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); | | 186 | VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); |
187 | pmap_update(pmap_kernel()); | | 187 | pmap_update(pmap_kernel()); |
188 | initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); | | 188 | initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); |
189 | | | 189 | |
190 | /* | | 190 | /* |
191 | * Initialize hardware that support various console types like | | 191 | * Initialize hardware that support various console types like |
192 | * the grf and PCI busses. | | 192 | * the grf and PCI busses. |
193 | */ | | 193 | */ |
194 | config_console(); | | 194 | config_console(); |
195 | | | 195 | |
196 | /* | | 196 | /* |
197 | * Now pick the best console candidate. | | 197 | * Now pick the best console candidate. |
198 | */ | | 198 | */ |
199 | cninit(); | | 199 | cninit(); |
200 | | | 200 | |
201 | #if NKSYMS || defined(DDB) || defined(MODULAR) | | 201 | #if NKSYMS || defined(DDB) || defined(MODULAR) |
202 | { | | 202 | { |
203 | extern int end; | | 203 | extern int end; |
204 | extern int *esym; | | 204 | extern int *esym; |
205 | | | 205 | |
206 | #ifndef __ELF__ | | 206 | #ifndef __ELF__ |
207 | ksyms_addsyms_elf(*(int *)&end, ((int *)&end) + 1, esym); | | 207 | ksyms_addsyms_elf(*(int *)&end, ((int *)&end) + 1, esym); |
208 | #else | | 208 | #else |
209 | ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr), | | 209 | ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr), |
210 | (void *)&end, esym); | | 210 | (void *)&end, esym); |
211 | #endif | | 211 | #endif |
212 | } | | 212 | } |
213 | #endif | | 213 | #endif |
214 | #if defined (DDB) | | 214 | #if defined (DDB) |
215 | if(boothowto & RB_KDB) | | 215 | if(boothowto & RB_KDB) |
216 | Debugger(); | | 216 | Debugger(); |
217 | #endif | | 217 | #endif |
218 | } | | 218 | } |
219 | | | 219 | |
220 | /* | | 220 | /* |
221 | * cpu_startup: allocate memory for variable-sized tables, | | 221 | * cpu_startup: allocate memory for variable-sized tables, |
222 | * initialize CPU, and do autoconfiguration. | | 222 | * initialize CPU, and do autoconfiguration. |
223 | */ | | 223 | */ |
224 | void | | 224 | void |
225 | cpu_startup(void) | | 225 | cpu_startup(void) |
226 | { | | 226 | { |
227 | extern int iomem_malloc_safe; | | 227 | extern int iomem_malloc_safe; |
228 | char pbuf[9]; | | 228 | char pbuf[9]; |
229 | | | 229 | |
230 | #ifdef DEBUG | | 230 | #ifdef DEBUG |
231 | extern int pmapdebug; | | 231 | extern int pmapdebug; |
232 | int opmapdebug = pmapdebug; | | 232 | int opmapdebug = pmapdebug; |
233 | #endif | | 233 | #endif |
234 | vaddr_t minaddr, maxaddr; | | 234 | vaddr_t minaddr, maxaddr; |
235 | extern vsize_t mem_size; /* from pmap.c */ | | 235 | extern vsize_t mem_size; /* from pmap.c */ |
236 | | | 236 | |
237 | #ifdef DEBUG | | 237 | #ifdef DEBUG |
238 | pmapdebug = 0; | | 238 | pmapdebug = 0; |
239 | #endif | | 239 | #endif |
240 | | | 240 | |
241 | if (fputype != FPU_NONE) | | 241 | if (fputype != FPU_NONE) |
242 | m68k_make_fpu_idle_frame(); | | 242 | m68k_make_fpu_idle_frame(); |
243 | | | 243 | |
244 | /* | | 244 | /* |
245 | * Good {morning,afternoon,evening,night}. | | 245 | * Good {morning,afternoon,evening,night}. |
246 | */ | | 246 | */ |
247 | printf("%s%s", copyright, version); | | 247 | printf("%s%s", copyright, version); |
248 | identifycpu(); | | 248 | identifycpu(); |
249 | | | 249 | |
250 | format_bytes(pbuf, sizeof(pbuf), mem_size); | | 250 | format_bytes(pbuf, sizeof(pbuf), mem_size); |
251 | printf("total memory = %s\n", pbuf); | | 251 | printf("total memory = %s\n", pbuf); |
252 | | | 252 | |
253 | minaddr = 0; | | 253 | minaddr = 0; |
254 | | | 254 | |
255 | /* | | 255 | /* |
256 | * Allocate a submap for physio | | 256 | * Allocate a submap for physio |
257 | */ | | 257 | */ |
258 | phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, | | 258 | phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, |
259 | VM_PHYS_SIZE, 0, false, NULL); | | 259 | VM_PHYS_SIZE, 0, false, NULL); |
260 | | | 260 | |
261 | /* | | 261 | /* |
262 | * Finally, allocate mbuf cluster submap. | | 262 | * Finally, allocate mbuf cluster submap. |
263 | */ | | 263 | */ |
264 | mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, | | 264 | mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, |
265 | nmbclusters * mclbytes, VM_MAP_INTRSAFE, | | 265 | nmbclusters * mclbytes, VM_MAP_INTRSAFE, |
266 | false, NULL); | | 266 | false, NULL); |
267 | | | 267 | |
268 | #ifdef DEBUG | | 268 | #ifdef DEBUG |
269 | pmapdebug = opmapdebug; | | 269 | pmapdebug = opmapdebug; |
270 | #endif | | 270 | #endif |
271 | format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); | | 271 | format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); |
272 | printf("avail memory = %s\n", pbuf); | | 272 | printf("avail memory = %s\n", pbuf); |
273 | | | 273 | |
274 | /* | | 274 | /* |
275 | * Alloc extent allocation to use malloc | | 275 | * Alloc extent allocation to use malloc |
276 | */ | | 276 | */ |
277 | iomem_malloc_safe = 1; | | 277 | iomem_malloc_safe = 1; |
278 | } | | 278 | } |
279 | | | 279 | |
280 | /* | | 280 | /* |
281 | * Set registers on exec. | | 281 | * Set registers on exec. |
282 | */ | | 282 | */ |
283 | void | | 283 | void |
284 | setregs(struct lwp *l, struct exec_package *pack, u_long stack) | | 284 | setregs(struct lwp *l, struct exec_package *pack, u_long stack) |
285 | { | | 285 | { |
286 | struct frame *frame = (struct frame *)l->l_md.md_regs; | | 286 | struct frame *frame = (struct frame *)l->l_md.md_regs; |
287 | | | 287 | |
288 | frame->f_sr = PSL_USERSET; | | 288 | frame->f_sr = PSL_USERSET; |
289 | frame->f_pc = pack->ep_entry & ~1; | | 289 | frame->f_pc = pack->ep_entry & ~1; |
290 | frame->f_regs[D0] = 0; | | 290 | frame->f_regs[D0] = 0; |
291 | frame->f_regs[D1] = 0; | | 291 | frame->f_regs[D1] = 0; |
292 | frame->f_regs[D2] = 0; | | 292 | frame->f_regs[D2] = 0; |
293 | frame->f_regs[D3] = 0; | | 293 | frame->f_regs[D3] = 0; |
294 | frame->f_regs[D4] = 0; | | 294 | frame->f_regs[D4] = 0; |
295 | frame->f_regs[D5] = 0; | | 295 | frame->f_regs[D5] = 0; |
296 | frame->f_regs[D6] = 0; | | 296 | frame->f_regs[D6] = 0; |
297 | frame->f_regs[D7] = 0; | | 297 | frame->f_regs[D7] = 0; |
298 | frame->f_regs[A0] = 0; | | 298 | frame->f_regs[A0] = 0; |
299 | frame->f_regs[A1] = 0; | | 299 | frame->f_regs[A1] = 0; |
300 | frame->f_regs[A2] = (int)l->l_proc->p_psstr; | | 300 | frame->f_regs[A2] = (int)l->l_proc->p_psstr; |
301 | frame->f_regs[A3] = 0; | | 301 | frame->f_regs[A3] = 0; |
302 | frame->f_regs[A4] = 0; | | 302 | frame->f_regs[A4] = 0; |
303 | frame->f_regs[A5] = 0; | | 303 | frame->f_regs[A5] = 0; |
304 | frame->f_regs[A6] = 0; | | 304 | frame->f_regs[A6] = 0; |
305 | frame->f_regs[SP] = stack; | | 305 | frame->f_regs[SP] = stack; |
306 | | | 306 | |
307 | /* restore a null state frame */ | | 307 | /* restore a null state frame */ |
308 | l->l_addr->u_pcb.pcb_fpregs.fpf_null = 0; | | 308 | l->l_addr->u_pcb.pcb_fpregs.fpf_null = 0; |
309 | if (fputype) | | 309 | if (fputype) |
310 | m68881_restore(&l->l_addr->u_pcb.pcb_fpregs); | | 310 | m68881_restore(&l->l_addr->u_pcb.pcb_fpregs); |
311 | } | | 311 | } |
312 | | | 312 | |
313 | /* | | 313 | /* |
314 | * Info for CTL_HW | | 314 | * Info for CTL_HW |
315 | */ | | 315 | */ |
316 | char cpu_model[120]; | | 316 | char cpu_model[120]; |
317 | | | 317 | |
318 | static void | | 318 | static void |
319 | identifycpu(void) | | 319 | identifycpu(void) |
320 | { | | 320 | { |
321 | const char *mach, *mmu, *fpu, *cpu; | | 321 | const char *mach, *mmu, *fpu, *cpu; |
322 | | | 322 | |
323 | switch (machineid & ATARI_ANYMACH) { | | 323 | switch (machineid & ATARI_ANYMACH) { |
324 | case ATARI_TT: | | 324 | case ATARI_TT: |
325 | mach = "Atari TT"; | | 325 | mach = "Atari TT"; |
326 | break; | | 326 | break; |
327 | case ATARI_FALCON: | | 327 | case ATARI_FALCON: |
328 | mach = "Atari Falcon"; | | 328 | mach = "Atari Falcon"; |
329 | break; | | 329 | break; |
330 | case ATARI_HADES: | | 330 | case ATARI_HADES: |
331 | mach = "Atari Hades"; | | 331 | mach = "Atari Hades"; |
332 | break; | | 332 | break; |
333 | case ATARI_MILAN: | | 333 | case ATARI_MILAN: |
334 | mach = "Atari Milan"; | | 334 | mach = "Atari Milan"; |
335 | break; | | 335 | break; |
336 | default: | | 336 | default: |
337 | mach = "Atari UNKNOWN"; | | 337 | mach = "Atari UNKNOWN"; |
338 | break; | | 338 | break; |
339 | } | | 339 | } |
340 | | | 340 | |
341 | cpu = "m68k"; | | 341 | cpu = "m68k"; |
342 | fputype = fpu_probe(); | | 342 | fputype = fpu_probe(); |
343 | fpu = fpu_describe(fputype); | | 343 | fpu = fpu_describe(fputype); |
344 | | | 344 | |
345 | switch (cputype) { | | 345 | switch (cputype) { |
346 | | | 346 | |
347 | case CPU_68060: | | 347 | case CPU_68060: |
348 | { | | 348 | { |
349 | u_int32_t pcr; | | 349 | u_int32_t pcr; |
350 | char cputxt[30]; | | 350 | char cputxt[30]; |
351 | | | 351 | |
352 | __asm(".word 0x4e7a,0x0808;" | | 352 | __asm(".word 0x4e7a,0x0808;" |
353 | "movl %%d0,%0" : "=d"(pcr) : : "d0"); | | 353 | "movl %%d0,%0" : "=d"(pcr) : : "d0"); |
354 | sprintf(cputxt, "68%s060 rev.%d", | | 354 | sprintf(cputxt, "68%s060 rev.%d", |
355 | pcr & 0x10000 ? "LC/EC" : "", (pcr>>8)&0xff); | | 355 | pcr & 0x10000 ? "LC/EC" : "", (pcr>>8)&0xff); |
356 | cpu = cputxt; | | 356 | cpu = cputxt; |
357 | mmu = "/MMU"; | | 357 | mmu = "/MMU"; |
358 | } | | 358 | } |
359 | break; | | 359 | break; |
360 | case CPU_68040: | | 360 | case CPU_68040: |
361 | cpu = "m68040"; | | 361 | cpu = "m68040"; |
362 | mmu = "/MMU"; | | 362 | mmu = "/MMU"; |
363 | break; | | 363 | break; |
364 | case CPU_68030: | | 364 | case CPU_68030: |
365 | cpu = "m68030"; | | 365 | cpu = "m68030"; |
366 | mmu = "/MMU"; | | 366 | mmu = "/MMU"; |
367 | break; | | 367 | break; |
368 | default: /* XXX */ | | 368 | default: /* XXX */ |
369 | cpu = "m68020"; | | 369 | cpu = "m68020"; |
370 | mmu = " m68851 MMU"; | | 370 | mmu = " m68851 MMU"; |
371 | } | | 371 | } |
372 | sprintf(cpu_model, "%s (%s CPU%s%sFPU)", mach, cpu, mmu, fpu); | | 372 | sprintf(cpu_model, "%s (%s CPU%s%sFPU)", mach, cpu, mmu, fpu); |
373 | printf("%s\n", cpu_model); | | 373 | printf("%s\n", cpu_model); |
374 | } | | 374 | } |
375 | | | 375 | |
376 | /* | | 376 | /* |
377 | * machine dependent system variables. | | 377 | * machine dependent system variables. |
378 | */ | | 378 | */ |
379 | SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") | | 379 | SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") |
380 | { | | 380 | { |
381 | | | 381 | |
382 | sysctl_createv(clog, 0, NULL, NULL, | | 382 | sysctl_createv(clog, 0, NULL, NULL, |
383 | CTLFLAG_PERMANENT, | | 383 | CTLFLAG_PERMANENT, |
384 | CTLTYPE_NODE, "machdep", NULL, | | 384 | CTLTYPE_NODE, "machdep", NULL, |
385 | NULL, 0, NULL, 0, | | 385 | NULL, 0, NULL, 0, |
386 | CTL_MACHDEP, CTL_EOL); | | 386 | CTL_MACHDEP, CTL_EOL); |
387 | | | 387 | |
388 | sysctl_createv(clog, 0, NULL, NULL, | | 388 | sysctl_createv(clog, 0, NULL, NULL, |
389 | CTLFLAG_PERMANENT, | | 389 | CTLFLAG_PERMANENT, |
390 | CTLTYPE_STRUCT, "console_device", NULL, | | 390 | CTLTYPE_STRUCT, "console_device", NULL, |
391 | sysctl_consdev, 0, NULL, sizeof(dev_t), | | 391 | sysctl_consdev, 0, NULL, sizeof(dev_t), |
392 | CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); | | 392 | CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); |
393 | } | | 393 | } |
394 | | | 394 | |
395 | static int waittime = -1; | | 395 | static int waittime = -1; |
396 | | | 396 | |
397 | static void | | 397 | static void |
398 | bootsync(void) | | 398 | bootsync(void) |
399 | { | | 399 | { |
400 | if (waittime < 0) { | | 400 | if (waittime < 0) { |
401 | waittime = 0; | | 401 | waittime = 0; |
402 | | | 402 | |
403 | vfs_shutdown(); | | 403 | vfs_shutdown(); |
404 | | | 404 | |
405 | /* | | 405 | /* |
406 | * If we've been adjusting the clock, the todr | | 406 | * If we've been adjusting the clock, the todr |
407 | * will be out of synch; adjust it now. | | 407 | * will be out of synch; adjust it now. |
408 | */ | | 408 | */ |
409 | resettodr(); | | 409 | resettodr(); |
410 | } | | 410 | } |
411 | } | | 411 | } |
412 | | | 412 | |
413 | void | | 413 | void |
414 | cpu_reboot(int howto, char *bootstr) | | 414 | cpu_reboot(int howto, char *bootstr) |
415 | { | | 415 | { |
416 | /* take a snap shot before clobbering any registers */ | | 416 | /* take a snap shot before clobbering any registers */ |
417 | if (curlwp->l_addr) | | 417 | if (curlwp->l_addr) |
418 | savectx(&curlwp->l_addr->u_pcb); | | 418 | savectx(&curlwp->l_addr->u_pcb); |
419 | | | 419 | |
420 | boothowto = howto; | | 420 | boothowto = howto; |
421 | if((howto & RB_NOSYNC) == 0) | | 421 | if((howto & RB_NOSYNC) == 0) |
422 | bootsync(); | | 422 | bootsync(); |
423 | | | 423 | |
424 | /* | | 424 | /* |
425 | * Call shutdown hooks. Do this _before_ anything might be | | 425 | * Call shutdown hooks. Do this _before_ anything might be |
426 | * asked to the user in case nobody is there.... | | 426 | * asked to the user in case nobody is there.... |
427 | */ | | 427 | */ |
428 | doshutdownhooks(); | | 428 | doshutdownhooks(); |
429 | | | 429 | |
430 | pmf_system_shutdown(boothowto); | | 430 | pmf_system_shutdown(boothowto); |
431 | | | 431 | |
432 | splhigh(); /* extreme priority */ | | 432 | splhigh(); /* extreme priority */ |
433 | if(howto & RB_HALT) { | | 433 | if(howto & RB_HALT) { |
434 | printf("halted\n\n"); | | 434 | printf("halted\n\n"); |
435 | __asm(" stop #0x2700"); | | 435 | __asm(" stop #0x2700"); |
436 | } | | 436 | } |
437 | else { | | 437 | else { |
438 | if(howto & RB_DUMP) | | 438 | if(howto & RB_DUMP) |
439 | dumpsys(); | | 439 | dumpsys(); |
440 | | | 440 | |
441 | doboot(); | | 441 | doboot(); |
442 | /*NOTREACHED*/ | | 442 | /*NOTREACHED*/ |
443 | } | | 443 | } |
444 | panic("Boot() should never come here"); | | 444 | panic("Boot() should never come here"); |
445 | /*NOTREACHED*/ | | 445 | /*NOTREACHED*/ |
446 | } | | 446 | } |
447 | | | 447 | |
448 | #define BYTES_PER_DUMP PAGE_SIZE /* Must be a multiple of PAGE_SIZE */ | | 448 | #define BYTES_PER_DUMP PAGE_SIZE /* Must be a multiple of PAGE_SIZE */ |
449 | static vaddr_t dumpspace; /* Virt. space to map dumppages */ | | 449 | static vaddr_t dumpspace; /* Virt. space to map dumppages */ |
450 | | | 450 | |
451 | /* | | 451 | /* |
452 | * Reserve _virtual_ memory to map in the page to be dumped | | 452 | * Reserve _virtual_ memory to map in the page to be dumped |
453 | */ | | 453 | */ |
454 | vaddr_t | | 454 | vaddr_t |
455 | reserve_dumppages(vaddr_t p) | | 455 | reserve_dumppages(vaddr_t p) |
456 | { | | 456 | { |
457 | dumpspace = p; | | 457 | dumpspace = p; |
458 | return(p + BYTES_PER_DUMP); | | 458 | return(p + BYTES_PER_DUMP); |
459 | } | | 459 | } |
460 | | | 460 | |
461 | u_int32_t dumpmag = 0x8fca0101; /* magic number for savecore */ | | 461 | u_int32_t dumpmag = 0x8fca0101; /* magic number for savecore */ |
462 | int dumpsize = 0; /* also for savecore (pages) */ | | 462 | int dumpsize = 0; /* also for savecore (pages) */ |
463 | long dumplo = 0; /* (disk blocks) */ | | 463 | long dumplo = 0; /* (disk blocks) */ |
464 | | | 464 | |
465 | void | | 465 | void |
466 | cpu_dumpconf(void) | | 466 | cpu_dumpconf(void) |
467 | { | | 467 | { |
468 | const struct bdevsw *bdev; | | 468 | const struct bdevsw *bdev; |
469 | int nblks, i; | | 469 | int nblks, i; |
470 | | | 470 | |
471 | for (i = dumpsize = 0; i < NMEM_SEGS; i++) { | | 471 | for (i = dumpsize = 0; i < NMEM_SEGS; i++) { |
472 | if (boot_segs[i].start == boot_segs[i].end) | | 472 | if (boot_segs[i].start == boot_segs[i].end) |
473 | break; | | 473 | break; |
474 | dumpsize += boot_segs[i].end - boot_segs[i].start; | | 474 | dumpsize += boot_segs[i].end - boot_segs[i].start; |
475 | } | | 475 | } |
476 | dumpsize = btoc(dumpsize); | | 476 | dumpsize = btoc(dumpsize); |
477 | | | 477 | |
478 | if (dumpdev != NODEV) { | | 478 | if (dumpdev != NODEV) { |
479 | bdev = bdevsw_lookup(dumpdev); | | 479 | bdev = bdevsw_lookup(dumpdev); |
480 | if (bdev == NULL) { | | 480 | if (bdev == NULL) { |
481 | dumpdev = NODEV; | | 481 | dumpdev = NODEV; |
482 | return; | | 482 | return; |
483 | } | | 483 | } |
484 | if (bdev->d_psize != NULL) { | | 484 | if (bdev->d_psize != NULL) { |
485 | nblks = (*bdev->d_psize)(dumpdev); | | 485 | nblks = (*bdev->d_psize)(dumpdev); |
486 | if (dumpsize > btoc(dbtob(nblks - dumplo))) | | 486 | if (dumpsize > btoc(dbtob(nblks - dumplo))) |
487 | dumpsize = btoc(dbtob(nblks - dumplo)); | | 487 | dumpsize = btoc(dbtob(nblks - dumplo)); |
488 | else if (dumplo == 0) | | 488 | else if (dumplo == 0) |
489 | dumplo = nblks - btodb(ctob(dumpsize)); | | 489 | dumplo = nblks - btodb(ctob(dumpsize)); |
490 | } | | 490 | } |
491 | } | | 491 | } |
492 | dumplo -= cpu_dumpsize(); | | 492 | dumplo -= cpu_dumpsize(); |
493 | | | 493 | |
494 | /* | | 494 | /* |
495 | * Don't dump on the first PAGE_SIZE (why PAGE_SIZE?) | | 495 | * Don't dump on the first PAGE_SIZE (why PAGE_SIZE?) |
496 | * in case the dump device includes a disk label. | | 496 | * in case the dump device includes a disk label. |
497 | */ | | 497 | */ |
498 | if (dumplo < btodb(PAGE_SIZE)) | | 498 | if (dumplo < btodb(PAGE_SIZE)) |
499 | dumplo = btodb(PAGE_SIZE); | | 499 | dumplo = btodb(PAGE_SIZE); |
500 | } | | 500 | } |
501 | | | 501 | |
502 | /* | | 502 | /* |
503 | * Doadump comes here after turning off memory management and | | 503 | * Doadump comes here after turning off memory management and |
504 | * getting on the dump stack, either when called above, or by | | 504 | * getting on the dump stack, either when called above, or by |
505 | * the auto-restart code. | | 505 | * the auto-restart code. |
506 | */ | | 506 | */ |
507 | void | | 507 | void |
508 | dumpsys(void) | | 508 | dumpsys(void) |
509 | { | | 509 | { |
510 | const struct bdevsw *bdev; | | 510 | const struct bdevsw *bdev; |
511 | daddr_t blkno; /* Current block to write */ | | 511 | daddr_t blkno; /* Current block to write */ |
512 | int (*dump)(dev_t, daddr_t, void *, size_t); | | 512 | int (*dump)(dev_t, daddr_t, void *, size_t); |
513 | /* Dumping function */ | | 513 | /* Dumping function */ |
514 | u_long maddr; /* PA being dumped */ | | 514 | u_long maddr; /* PA being dumped */ |
515 | int segbytes; /* Number of bytes in this seg. */ | | 515 | int segbytes; /* Number of bytes in this seg. */ |
516 | int segnum; /* Segment we are dumping */ | | 516 | int segnum; /* Segment we are dumping */ |
517 | int nbytes; /* Bytes left to dump */ | | 517 | int nbytes; /* Bytes left to dump */ |
518 | int i, n, error; | | 518 | int i, n, error; |
519 | | | 519 | |
520 | error = segnum = 0; | | 520 | error = segnum = 0; |
521 | if (dumpdev == NODEV) | | 521 | if (dumpdev == NODEV) |
522 | return; | | 522 | return; |
523 | bdev = bdevsw_lookup(dumpdev); | | 523 | bdev = bdevsw_lookup(dumpdev); |
524 | if (bdev == NULL) | | 524 | if (bdev == NULL) |
525 | return; | | 525 | return; |
526 | /* | | 526 | /* |
527 | * For dumps during autoconfiguration, | | 527 | * For dumps during autoconfiguration, |
528 | * if dump device has already configured... | | 528 | * if dump device has already configured... |
529 | */ | | 529 | */ |
530 | if (dumpsize == 0) | | 530 | if (dumpsize == 0) |
531 | cpu_dumpconf(); | | 531 | cpu_dumpconf(); |
532 | if (dumplo <= 0) { | | 532 | if (dumplo <= 0) { |
533 | printf("\ndump to dev %u,%u not possible\n", major(dumpdev), | | 533 | printf("\ndump to dev %u,%u not possible\n", major(dumpdev), |
534 | minor(dumpdev)); | | 534 | minor(dumpdev)); |
535 | return; | | 535 | return; |
536 | } | | 536 | } |
537 | printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), | | 537 | printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev), |
538 | minor(dumpdev), dumplo); | | 538 | minor(dumpdev), dumplo); |
539 | | | 539 | |
540 | #if defined(DDB) || defined(PANICWAIT) | | 540 | #if defined(DDB) || defined(PANICWAIT) |
541 | printf("Do you want to dump memory? [y]"); | | 541 | printf("Do you want to dump memory? [y]"); |
542 | cnputc(i = cngetc()); | | 542 | cnputc(i = cngetc()); |
543 | switch (i) { | | 543 | switch (i) { |
544 | case 'n': | | 544 | case 'n': |
545 | case 'N': | | 545 | case 'N': |
546 | return; | | 546 | return; |
547 | case '\n': | | 547 | case '\n': |
548 | break; | | 548 | break; |
549 | default : | | 549 | default : |
550 | cnputc('\n'); | | 550 | cnputc('\n'); |
551 | } | | 551 | } |
552 | #endif /* defined(DDB) || defined(PANICWAIT) */ | | 552 | #endif /* defined(DDB) || defined(PANICWAIT) */ |
553 | | | 553 | |
554 | maddr = 0; | | 554 | maddr = 0; |
555 | segbytes = boot_segs[0].end; | | 555 | segbytes = boot_segs[0].end; |
556 | blkno = dumplo; | | 556 | blkno = dumplo; |
557 | dump = bdev->d_dump; | | 557 | dump = bdev->d_dump; |
558 | nbytes = dumpsize * PAGE_SIZE; | | 558 | nbytes = dumpsize * PAGE_SIZE; |
559 | | | 559 | |
560 | printf("dump "); | | 560 | printf("dump "); |
561 | | | 561 | |
562 | error = cpu_dump(dump, &blkno); | | 562 | error = cpu_dump(dump, &blkno); |
563 | if (!error) { | | 563 | if (!error) { |
564 | for (i = 0; i < nbytes; i += n, segbytes -= n) { | | 564 | for (i = 0; i < nbytes; i += n, segbytes -= n) { |
565 | /* | | 565 | /* |
566 | * Skip the hole | | 566 | * Skip the hole |
567 | */ | | 567 | */ |
568 | if (segbytes == 0) { | | 568 | if (segbytes == 0) { |
569 | segnum++; | | 569 | segnum++; |
570 | maddr = boot_segs[segnum].start; | | 570 | maddr = boot_segs[segnum].start; |
571 | segbytes = boot_segs[segnum].end - boot_segs[segnum].start; | | 571 | segbytes = boot_segs[segnum].end - boot_segs[segnum].start; |
572 | } | | 572 | } |
573 | /* | | 573 | /* |
574 | * Print Mb's to go | | 574 | * Print Mb's to go |
575 | */ | | 575 | */ |
576 | n = nbytes - i; | | 576 | n = nbytes - i; |
577 | if (n && (n % (1024*1024)) == 0) | | 577 | if (n && (n % (1024*1024)) == 0) |
578 | printf_nolog("%d ", n / (1024 * 1024)); | | 578 | printf_nolog("%d ", n / (1024 * 1024)); |
579 | | | 579 | |
580 | /* | | 580 | /* |
581 | * Limit transfer to BYTES_PER_DUMP | | 581 | * Limit transfer to BYTES_PER_DUMP |
582 | */ | | 582 | */ |
583 | if (n > BYTES_PER_DUMP) | | 583 | if (n > BYTES_PER_DUMP) |
584 | n = BYTES_PER_DUMP; | | 584 | n = BYTES_PER_DUMP; |
585 | | | 585 | |
586 | /* | | 586 | /* |
587 | * Map to a VA and write it | | 587 | * Map to a VA and write it |
588 | */ | | 588 | */ |
589 | if (maddr != 0) { /* XXX kvtop chokes on this */ | | 589 | if (maddr != 0) { /* XXX kvtop chokes on this */ |
590 | (void)pmap_map(dumpspace, maddr, maddr+n, VM_PROT_READ); | | 590 | (void)pmap_map(dumpspace, maddr, maddr+n, VM_PROT_READ); |
591 | error = (*dump)(dumpdev, blkno, (void *)dumpspace, n); | | 591 | error = (*dump)(dumpdev, blkno, (void *)dumpspace, n); |
592 | if (error) | | 592 | if (error) |
593 | break; | | 593 | break; |
594 | } | | 594 | } |
595 | | | 595 | |
596 | maddr += n; | | 596 | maddr += n; |
597 | blkno += btodb(n); | | 597 | blkno += btodb(n); |
598 | } | | 598 | } |
599 | } | | 599 | } |
600 | switch (error) { | | 600 | switch (error) { |
601 | | | 601 | |
602 | case ENXIO: | | 602 | case ENXIO: |
603 | printf("device bad\n"); | | 603 | printf("device bad\n"); |
604 | break; | | 604 | break; |
605 | | | 605 | |
606 | case EFAULT: | | 606 | case EFAULT: |
607 | printf("device not ready\n"); | | 607 | printf("device not ready\n"); |
608 | break; | | 608 | break; |
609 | | | 609 | |
610 | case EINVAL: | | 610 | case EINVAL: |
611 | printf("area improper\n"); | | 611 | printf("area improper\n"); |
612 | break; | | 612 | break; |
613 | | | 613 | |
614 | case EIO: | | 614 | case EIO: |
615 | printf("i/o error\n"); | | 615 | printf("i/o error\n"); |
616 | break; | | 616 | break; |
617 | | | 617 | |
618 | default: | | 618 | default: |
619 | printf("succeeded\n"); | | 619 | printf("succeeded\n"); |
620 | break; | | 620 | break; |
621 | } | | 621 | } |
622 | printf("\n\n"); | | 622 | printf("\n\n"); |
623 | delay(5000000); /* 5 seconds */ | | 623 | delay(5000000); /* 5 seconds */ |
624 | } | | 624 | } |
625 | | | 625 | |
626 | void | | 626 | void |
627 | straytrap(int pc, u_short evec) | | 627 | straytrap(int pc, u_short evec) |
628 | { | | 628 | { |
629 | static int prev_evec; | | 629 | static int prev_evec; |
630 | | | 630 | |
631 | printf("unexpected trap (vector offset 0x%x) from 0x%x\n", | | 631 | printf("unexpected trap (vector offset 0x%x) from 0x%x\n", |
632 | evec & 0xFFF, pc); | | 632 | evec & 0xFFF, pc); |
633 | | | 633 | |
634 | if(prev_evec == evec) { | | 634 | if(prev_evec == evec) { |
635 | delay(1000000); | | 635 | delay(1000000); |
636 | prev_evec = 0; | | 636 | prev_evec = 0; |
637 | } | | 637 | } |
638 | else prev_evec = evec; | | 638 | else prev_evec = evec; |
639 | } | | 639 | } |
640 | | | 640 | |
641 | void | | 641 | void |
642 | straymfpint(int pc, u_short evec) | | 642 | straymfpint(int pc, u_short evec) |
643 | { | | 643 | { |
644 | printf("unexpected mfp-interrupt (vector offset 0x%x) from 0x%x\n", | | 644 | printf("unexpected mfp-interrupt (vector offset 0x%x) from 0x%x\n", |
645 | evec & 0xFFF, pc); | | 645 | evec & 0xFFF, pc); |
646 | } | | 646 | } |
647 | | | 647 | |
648 | int *nofault; | | 648 | int *nofault; |
649 | | | 649 | |
650 | int | | 650 | int |
651 | badbaddr(void *addr, int size) | | 651 | badbaddr(void *addr, int size) |
652 | { | | 652 | { |
653 | register int i; | | 653 | register int i; |
654 | label_t faultbuf; | | 654 | label_t faultbuf; |
655 | | | 655 | |
656 | #ifdef lint | | 656 | #ifdef lint |
657 | i = *addr; if (i) return(0); | | 657 | i = *addr; if (i) return(0); |
658 | #endif | | 658 | #endif |
659 | nofault = (int *) &faultbuf; | | 659 | nofault = (int *) &faultbuf; |
660 | if (setjmp((label_t *)nofault)) { | | 660 | if (setjmp((label_t *)nofault)) { |
661 | nofault = (int *) 0; | | 661 | nofault = (int *) 0; |
662 | return(1); | | 662 | return(1); |
663 | } | | 663 | } |
664 | switch (size) { | | 664 | switch (size) { |
665 | case 1: | | 665 | case 1: |
666 | i = *(volatile char *)addr; | | 666 | i = *(volatile char *)addr; |
667 | break; | | 667 | break; |
668 | case 2: | | 668 | case 2: |
669 | i = *(volatile short *)addr; | | 669 | i = *(volatile short *)addr; |
670 | break; | | 670 | break; |
671 | case 4: | | 671 | case 4: |
672 | i = *(volatile long *)addr; | | 672 | i = *(volatile long *)addr; |
673 | break; | | 673 | break; |
674 | default: | | 674 | default: |
675 | panic("badbaddr: unknown size"); | | 675 | panic("badbaddr: unknown size"); |
676 | } | | 676 | } |
677 | nofault = (int *) 0; | | 677 | nofault = (int *) 0; |
678 | return(0); | | 678 | return(0); |
679 | } | | 679 | } |
680 | | | 680 | |
681 | /* | | 681 | /* |
682 | * this is a handy package to have asynchronously executed | | 682 | * this is a handy package to have asynchronously executed |
683 | * function calls executed at very low interrupt priority. | | 683 | * function calls executed at very low interrupt priority. |
684 | * Example for use is keyboard repeat, where the repeat | | 684 | * Example for use is keyboard repeat, where the repeat |
685 | * handler running at splclock() triggers such a (hardware | | 685 | * handler running at splclock() triggers such a (hardware |
686 | * aided) software interrupt. | | 686 | * aided) software interrupt. |
687 | * Note: the installed functions are currently called in a | | 687 | * Note: the installed functions are currently called in a |
688 | * LIFO fashion, might want to change this to FIFO | | 688 | * LIFO fashion, might want to change this to FIFO |
689 | * later. | | 689 | * later. |
690 | * | | 690 | * |
691 | * XXX: Some of functions which use this callback should be rewritten | | 691 | * XXX: Some of functions which use this callback should be rewritten |
692 | * XXX: to use MI softintr(9) directly. | | 692 | * XXX: to use MI softintr(9) directly. |
693 | */ | | 693 | */ |
694 | struct si_callback { | | 694 | struct si_callback { |
695 | struct si_callback *next; | | 695 | struct si_callback *next; |
696 | void (*function)(void *rock1, void *rock2); | | 696 | void (*function)(void *rock1, void *rock2); |
697 | void *rock1, *rock2; | | 697 | void *rock1, *rock2; |
698 | }; | | 698 | }; |
699 | static void *si_callback_cookie; | | 699 | static void *si_callback_cookie; |
700 | static struct si_callback *si_callbacks; | | 700 | static struct si_callback *si_callbacks; |
701 | static struct si_callback *si_free; | | 701 | static struct si_callback *si_free; |
702 | #ifdef DIAGNOSTIC | | 702 | #ifdef DIAGNOSTIC |
703 | static int ncbd; /* number of callback blocks dynamically allocated */ | | 703 | static int ncbd; /* number of callback blocks dynamically allocated */ |
704 | #endif | | 704 | #endif |
705 | | | 705 | |
706 | void | | 706 | void |
707 | init_sicallback(void) | | 707 | init_sicallback(void) |
708 | { | | 708 | { |
709 | | | 709 | |
710 | si_callback_cookie = softint_establish(SOFTINT_NET, | | 710 | si_callback_cookie = softint_establish(SOFTINT_NET, |
711 | (void (*)(void *))call_sicallbacks, NULL); | | 711 | (void (*)(void *))call_sicallbacks, NULL); |
712 | } | | 712 | } |
713 | | | 713 | |
714 | void | | 714 | void |
715 | add_sicallback(void (*function)(void *, void *), void *rock1, void *rock2) | | 715 | add_sicallback(void (*function)(void *, void *), void *rock1, void *rock2) |
716 | { | | 716 | { |
717 | struct si_callback *si; | | 717 | struct si_callback *si; |
718 | int s; | | 718 | int s; |
719 | | | 719 | |
720 | /* | | 720 | /* |
721 | * this function may be called from high-priority interrupt handlers. | | 721 | * this function may be called from high-priority interrupt handlers. |
722 | * We may NOT block for memory-allocation in here!. | | 722 | * We may NOT block for memory-allocation in here!. |
723 | */ | | 723 | */ |
724 | s = splhigh(); | | 724 | s = splhigh(); |
725 | if((si = si_free) != NULL) | | 725 | if((si = si_free) != NULL) |
726 | si_free = si->next; | | 726 | si_free = si->next; |
727 | splx(s); | | 727 | splx(s); |
728 | | | 728 | |
729 | if(si == NULL) { | | 729 | if(si == NULL) { |
730 | si = (struct si_callback *)malloc(sizeof(*si),M_TEMP,M_NOWAIT); | | 730 | si = (struct si_callback *)malloc(sizeof(*si),M_TEMP,M_NOWAIT); |
731 | #ifdef DIAGNOSTIC | | 731 | #ifdef DIAGNOSTIC |
732 | if(si) | | 732 | if(si) |
733 | ++ncbd; /* count # dynamically allocated */ | | 733 | ++ncbd; /* count # dynamically allocated */ |
734 | #endif | | 734 | #endif |
735 | if(!si) | | 735 | if(!si) |
736 | return; | | 736 | return; |
737 | } | | 737 | } |
738 | | | 738 | |
739 | si->function = function; | | 739 | si->function = function; |
740 | si->rock1 = rock1; | | 740 | si->rock1 = rock1; |
741 | si->rock2 = rock2; | | 741 | si->rock2 = rock2; |
742 | | | 742 | |
743 | s = splhigh(); | | 743 | s = splhigh(); |
744 | si->next = si_callbacks; | | 744 | si->next = si_callbacks; |
745 | si_callbacks = si; | | 745 | si_callbacks = si; |
746 | splx(s); | | 746 | splx(s); |
747 | | | 747 | |
748 | /* | | 748 | /* |
749 | * and cause a software interrupt (spl1). This interrupt might | | 749 | * and cause a software interrupt (spl1). This interrupt might |
750 | * happen immediately, or after returning to a safe enough level. | | 750 | * happen immediately, or after returning to a safe enough level. |
751 | * | | 751 | * |
752 | * XXX: | | 752 | * XXX: |
753 | * According to <machine/scu.h> and lev1intr() hander in locore.s, | | 753 | * According to <machine/scu.h> and lev1intr() hander in locore.s, |
754 | * at least _ATARIHW_ machines (ATARITT and HADES?) seem to have | | 754 | * at least _ATARIHW_ machines (ATARITT and HADES?) seem to have |
755 | * some hardware support which can initiate real hardware interrupt | | 755 | * some hardware support which can initiate real hardware interrupt |
756 | * at ipl 1 for software interrupt. But as per <machine/mtpr.h>, | | 756 | * at ipl 1 for software interrupt. But as per <machine/mtpr.h>, |
757 | * this feature was not used at all on setsoft*() calls and | | 757 | * this feature was not used at all on setsoft*() calls and |
758 | * traditional hp300 derived ssir (simulated software interrupt | | 758 | * traditional hp300 derived ssir (simulated software interrupt |
759 | * request) on VAX REI emulation in locore.s is used. | | 759 | * request) on VAX REI emulation in locore.s is used. |
760 | */ | | 760 | */ |
761 | softint_schedule(si_callback_cookie); | | 761 | softint_schedule(si_callback_cookie); |
762 | } | | 762 | } |
763 | | | 763 | |
764 | void | | 764 | void |
765 | rem_sicallback(void (*function)(void *rock1, void *rock2)) | | 765 | rem_sicallback(void (*function)(void *rock1, void *rock2)) |
766 | { | | 766 | { |
767 | struct si_callback *si, *psi, *nsi; | | 767 | struct si_callback *si, *psi, *nsi; |
768 | int s; | | 768 | int s; |
769 | | | 769 | |
770 | s = splhigh(); | | 770 | s = splhigh(); |
771 | for(psi = 0, si = si_callbacks; si; ) { | | 771 | for(psi = 0, si = si_callbacks; si; ) { |
772 | nsi = si->next; | | 772 | nsi = si->next; |
773 | | | 773 | |
774 | if(si->function != function) | | 774 | if(si->function != function) |
775 | psi = si; | | 775 | psi = si; |
776 | else { | | 776 | else { |
777 | si->next = si_free; | | 777 | si->next = si_free; |
778 | si_free = si; | | 778 | si_free = si; |
779 | if(psi) | | 779 | if(psi) |
780 | psi->next = nsi; | | 780 | psi->next = nsi; |
781 | else si_callbacks = nsi; | | 781 | else si_callbacks = nsi; |
782 | } | | 782 | } |
783 | si = nsi; | | 783 | si = nsi; |
784 | } | | 784 | } |
785 | splx(s); | | 785 | splx(s); |
786 | } | | 786 | } |
787 | | | 787 | |
788 | /* purge the list */ | | 788 | /* purge the list */ |
789 | static void | | 789 | static void |
790 | call_sicallbacks(void) | | 790 | call_sicallbacks(void) |
791 | { | | 791 | { |
792 | struct si_callback *si; | | 792 | struct si_callback *si; |
793 | int s; | | 793 | int s; |
794 | void *rock1, *rock2; | | 794 | void *rock1, *rock2; |
795 | void (*function)(void *, void *); | | 795 | void (*function)(void *, void *); |
796 | | | 796 | |
797 | do { | | 797 | do { |
798 | s = splhigh (); | | 798 | s = splhigh (); |
799 | if ((si = si_callbacks) != NULL) | | 799 | if ((si = si_callbacks) != NULL) |
800 | si_callbacks = si->next; | | 800 | si_callbacks = si->next; |
801 | splx(s); | | 801 | splx(s); |
802 | | | 802 | |
803 | if (si) { | | 803 | if (si) { |
804 | function = si->function; | | 804 | function = si->function; |
805 | rock1 = si->rock1; | | 805 | rock1 = si->rock1; |
806 | rock2 = si->rock2; | | 806 | rock2 = si->rock2; |
807 | s = splhigh (); | | 807 | s = splhigh (); |
808 | if(si_callbacks) | | 808 | if(si_callbacks) |
809 | softint_schedule(si_callback_cookie); | | 809 | softint_schedule(si_callback_cookie); |
810 | si->next = si_free; | | 810 | si->next = si_free; |
811 | si_free = si; | | 811 | si_free = si; |
812 | splx(s); | | 812 | splx(s); |
| | | 813 | |
| | | 814 | /* |
| | | 815 | * Raise spl for BASEPRI() checks to see |
| | | 816 | * nested interrupts in some drivers using callbacks |
| | | 817 | * since modern MI softint(9) doesn't seem to do it |
| | | 818 | * in !__HAVE_FAST_SOFTINTS case. |
| | | 819 | * |
| | | 820 | * XXX: This is just a workaround hack. |
| | | 821 | * Each driver should raise spl in its handler |
| | | 822 | * to avoid nested interrupts if necessary. |
| | | 823 | */ |
| | | 824 | s = splsoftnet(); /* XXX */ |
813 | function(rock1, rock2); | | 825 | function(rock1, rock2); |
| | | 826 | splx(s); |
814 | } | | 827 | } |
815 | } while (si); | | 828 | } while (si); |
816 | #ifdef DIAGNOSTIC | | 829 | #ifdef DIAGNOSTIC |
817 | if (ncbd) { | | 830 | if (ncbd) { |
818 | #ifdef DEBUG | | 831 | #ifdef DEBUG |
819 | printf("call_sicallback: %d more dynamic structures\n", ncbd); | | 832 | printf("call_sicallback: %d more dynamic structures\n", ncbd); |
820 | #endif | | 833 | #endif |
821 | ncbd = 0; | | 834 | ncbd = 0; |
822 | } | | 835 | } |
823 | #endif | | 836 | #endif |
824 | } | | 837 | } |
825 | | | 838 | |
826 | #if defined(DEBUG) && !defined(PANICBUTTON) | | 839 | #if defined(DEBUG) && !defined(PANICBUTTON) |
827 | #define PANICBUTTON | | 840 | #define PANICBUTTON |
828 | #endif | | 841 | #endif |
829 | | | 842 | |
830 | #ifdef PANICBUTTON | | 843 | #ifdef PANICBUTTON |
831 | int panicbutton = 1; /* non-zero if panic buttons are enabled */ | | 844 | int panicbutton = 1; /* non-zero if panic buttons are enabled */ |
832 | int crashandburn = 0; | | 845 | int crashandburn = 0; |
833 | int candbdelay = 50; /* give em half a second */ | | 846 | int candbdelay = 50; /* give em half a second */ |
834 | | | 847 | |
835 | void candbtimer(void); | | 848 | void candbtimer(void); |
836 | | | 849 | |
837 | void | | 850 | void |
838 | candbtimer(void) | | 851 | candbtimer(void) |
839 | { | | 852 | { |
840 | crashandburn = 0; | | 853 | crashandburn = 0; |
841 | } | | 854 | } |
842 | #endif | | 855 | #endif |
843 | | | 856 | |
844 | /* | | 857 | /* |
845 | * should only get here, if no standard executable. This can currently | | 858 | * should only get here, if no standard executable. This can currently |
846 | * only mean, we're reading an old ZMAGIC file without MID, but since Atari | | 859 | * only mean, we're reading an old ZMAGIC file without MID, but since Atari |
847 | * ZMAGIC always worked the `right' way (;-)) just ignore the missing | | 860 | * ZMAGIC always worked the `right' way (;-)) just ignore the missing |
848 | * MID and proceed to new zmagic code ;-) | | 861 | * MID and proceed to new zmagic code ;-) |
849 | */ | | 862 | */ |
850 | int | | 863 | int |
851 | cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) | | 864 | cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) |
852 | { | | 865 | { |
853 | int error = ENOEXEC; | | 866 | int error = ENOEXEC; |
854 | #ifdef COMPAT_NOMID | | 867 | #ifdef COMPAT_NOMID |
855 | struct exec *execp = epp->ep_hdr; | | 868 | struct exec *execp = epp->ep_hdr; |
856 | #endif | | 869 | #endif |
857 | | | 870 | |
858 | #ifdef COMPAT_NOMID | | 871 | #ifdef COMPAT_NOMID |
859 | if (!((execp->a_midmag >> 16) & 0x0fff) | | 872 | if (!((execp->a_midmag >> 16) & 0x0fff) |
860 | && execp->a_midmag == ZMAGIC) | | 873 | && execp->a_midmag == ZMAGIC) |
861 | return(exec_aout_prep_zmagic(l->l_proc, epp)); | | 874 | return(exec_aout_prep_zmagic(l->l_proc, epp)); |
862 | #endif | | 875 | #endif |
863 | return(error); | | 876 | return(error); |
864 | } | | 877 | } |
865 | | | 878 | |
866 | #ifdef _MILANHW_ | | 879 | #ifdef _MILANHW_ |
867 | | | 880 | |
868 | /* | | 881 | /* |
869 | * Currently the only source of NMI interrupts on the Milan is the PLX9080. | | 882 | * Currently the only source of NMI interrupts on the Milan is the PLX9080. |
870 | * On access errors to the PCI bus, an NMI is generated. This NMI is shorted | | 883 | * On access errors to the PCI bus, an NMI is generated. This NMI is shorted |
871 | * in locore in case of a PCI config cycle to a non-existing address to allow | | 884 | * in locore in case of a PCI config cycle to a non-existing address to allow |
872 | * for probes. On other occaisions, it ShouldNotHappen(TM). | | 885 | * for probes. On other occaisions, it ShouldNotHappen(TM). |
873 | * Note: The handler in locore clears the errors, to make further PCI access | | 886 | * Note: The handler in locore clears the errors, to make further PCI access |
874 | * possible. | | 887 | * possible. |
875 | */ | | 888 | */ |
876 | void | | 889 | void |
877 | nmihandler(void) | | 890 | nmihandler(void) |
878 | { | | 891 | { |
879 | extern unsigned long plx_status; | | 892 | extern unsigned long plx_status; |
880 | | | 893 | |
881 | printf("nmihandler: plx_status = 0x%08lx\n", plx_status); | | 894 | printf("nmihandler: plx_status = 0x%08lx\n", plx_status); |
882 | } | | 895 | } |
883 | #endif | | 896 | #endif |