Sat Jan 3 06:36:59 2009 UTC ()
Raise IPL to splsoftnet() before calling callback funcions registered
via (atari specific) add_sicallback(), as a workaround hack.

Many drivers which use the MD sicallback depend on BASEPRI() macro
defined in <machine/cpu.h> to check nested interrupts,
but functions invoked from MI softint(9) won't run at IPL_SOFT
any longer and the BASEPRI() macro doesn't return expected value
as the past.

Fixes lost interrupt problem on Falcon wdc(4) reported by
Tuomo Makinen on port-atari, and also confirmed by him.

Should be pulled up to netbsd-5.


(tsutsui)
diff -r1.154 -r1.155 src/sys/arch/atari/atari/machdep.c

cvs diff -r1.154 -r1.155 src/sys/arch/atari/atari/machdep.c (switch to unified diff)

--- src/sys/arch/atari/atari/machdep.c 2008/11/30 18:21:32 1.154
+++ src/sys/arch/atari/atari/machdep.c 2009/01/03 06:36:58 1.155
@@ -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
132static void bootsync(void); 132static void bootsync(void);
133static void call_sicallbacks(void); 133static void call_sicallbacks(void);
134static void identifycpu(void); 134static void identifycpu(void);
135void straymfpint(int, u_short); 135void straymfpint(int, u_short);
136void straytrap(int, u_short); 136void straytrap(int, u_short);
137 137
138#ifdef _MILANHW_ 138#ifdef _MILANHW_
139void nmihandler(void); 139void nmihandler(void);
140#endif 140#endif
141 141
142struct vm_map *mb_map = NULL; 142struct vm_map *mb_map = NULL;
143struct vm_map *phys_map = NULL; 143struct vm_map *phys_map = NULL;
144 144
145void * msgbufaddr; 145void * msgbufaddr;
146vaddr_t msgbufpa; 146vaddr_t msgbufpa;
147 147
148int physmem = MAXMEM; /* max supported memory, changes to actual */ 148int 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 */
153int safepri = PSL_LOWIPL; 153int safepri = PSL_LOWIPL;
154extern int freebufspace; 154extern int freebufspace;
155extern u_int lowram; 155extern 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 */
160int fputype = 0; 160int fputype = 0;
161 161
162/* the following is used externally (sysctl_hw) */ 162/* the following is used externally (sysctl_hw) */
163char machine[] = MACHINE; /* from <machine/param.h> */ 163char 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. */
166struct cpu_info cpu_info_store; 166struct 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 */
173void 173void
174consinit(void) 174consinit(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 */
224void 224void
225cpu_startup(void) 225cpu_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 */
283void 283void
284setregs(struct lwp *l, struct exec_package *pack, u_long stack) 284setregs(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 */
316char cpu_model[120]; 316char cpu_model[120];
317  317
318static void 318static void
319identifycpu(void) 319identifycpu(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 */
379SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 379SYSCTL_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
395static int waittime = -1; 395static int waittime = -1;
396 396
397static void 397static void
398bootsync(void) 398bootsync(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
413void 413void
414cpu_reboot(int howto, char *bootstr) 414cpu_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 */
449static vaddr_t dumpspace; /* Virt. space to map dumppages */ 449static 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 */
454vaddr_t 454vaddr_t
455reserve_dumppages(vaddr_t p) 455reserve_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
461u_int32_t dumpmag = 0x8fca0101; /* magic number for savecore */ 461u_int32_t dumpmag = 0x8fca0101; /* magic number for savecore */
462int dumpsize = 0; /* also for savecore (pages) */ 462int dumpsize = 0; /* also for savecore (pages) */
463long dumplo = 0; /* (disk blocks) */ 463long dumplo = 0; /* (disk blocks) */
464 464
465void 465void
466cpu_dumpconf(void) 466cpu_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 */
507void 507void
508dumpsys(void) 508dumpsys(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
626void 626void
627straytrap(int pc, u_short evec) 627straytrap(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
641void 641void
642straymfpint(int pc, u_short evec) 642straymfpint(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
648int *nofault; 648int *nofault;
649 649
650int 650int
651badbaddr(void *addr, int size) 651badbaddr(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 */
694struct si_callback { 694struct 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};
699static void *si_callback_cookie; 699static void *si_callback_cookie;
700static struct si_callback *si_callbacks; 700static struct si_callback *si_callbacks;
701static struct si_callback *si_free; 701static struct si_callback *si_free;
702#ifdef DIAGNOSTIC 702#ifdef DIAGNOSTIC
703static int ncbd; /* number of callback blocks dynamically allocated */ 703static int ncbd; /* number of callback blocks dynamically allocated */
704#endif 704#endif
705 705
706void 706void
707init_sicallback(void) 707init_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
714void 714void
715add_sicallback(void (*function)(void *, void *), void *rock1, void *rock2) 715add_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
764void 764void
765rem_sicallback(void (*function)(void *rock1, void *rock2)) 765rem_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 */
789static void 789static void
790call_sicallbacks(void) 790call_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
831int panicbutton = 1; /* non-zero if panic buttons are enabled */ 844int panicbutton = 1; /* non-zero if panic buttons are enabled */
832int crashandburn = 0; 845int crashandburn = 0;
833int candbdelay = 50; /* give em half a second */ 846int candbdelay = 50; /* give em half a second */
834 847
835void candbtimer(void); 848void candbtimer(void);
836 849
837void 850void
838candbtimer(void) 851candbtimer(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 */
850int 863int
851cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) 864cpu_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 */
876void 889void
877nmihandler(void) 890nmihandler(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