xref: /netbsd/sys/arch/amiga/amiga/amiga_init.c (revision db6ae655)
1 /*	$NetBSD: amiga_init.c,v 1.131 2021/08/17 22:00:27 andvar Exp $	*/
2 
3 /*
4  * Copyright (c) 1994 Michael L. Hitch
5  * Copyright (c) 1993 Markus Wild
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by Markus Wild.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "opt_amigaccgrf.h"
35 #include "opt_p5ppc68kboard.h"
36 #include "opt_devreload.h"
37 #include "opt_m68k_arch.h"
38 #include "z3rambd.h"
39 #include "ser.h"
40 
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: amiga_init.c,v 1.131 2021/08/17 22:00:27 andvar Exp $");
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/ioctl.h>
47 #include <sys/select.h>
48 #include <sys/tty.h>
49 #include <sys/buf.h>
50 #include <sys/msgbuf.h>
51 #include <sys/mbuf.h>
52 #include <sys/protosw.h>
53 #include <sys/domain.h>
54 #include <sys/dkbad.h>
55 #include <sys/reboot.h>
56 #include <sys/exec.h>
57 
58 #include <dev/mm.h>
59 #include <uvm/uvm_extern.h>
60 
61 #include <machine/pte.h>
62 #include <machine/cpu.h>
63 #include <amiga/amiga/cc.h>
64 #include <amiga/amiga/cia.h>
65 #include <amiga/amiga/custom.h>
66 #include <amiga/amiga/cfdev.h>
67 #include <amiga/amiga/drcustom.h>
68 #include <amiga/amiga/gayle.h>
69 #include <amiga/amiga/memlist.h>
70 #include <amiga/dev/zbusvar.h>
71 #include <amiga/dev/z3rambdvar.h>
72 
73 #define RELOC(v, t)	*((t*)((u_int)&(v) + loadbase))
74 
75 extern u_int	lowram;
76 extern u_int	Umap;
77 extern u_long boot_partition;
78 extern vaddr_t	m68k_uptbase;
79 
80 #ifdef P5PPC68KBOARD
81 extern int	p5ppc;
82 #endif
83 
84 extern char *esym;
85 
86 #ifdef GRF_AGA
87 extern u_long aga_enable;
88 #endif
89 
90 #if NSER > 0
91 extern int serconsole;
92 #endif
93 
94 extern u_long noncontig_enable;
95 
96 /*
97  * some addresses used in locore
98  */
99 vaddr_t INTREQRaddr;
100 vaddr_t INTREQWaddr;
101 
102 /*
103  * these are used by the extended spl?() macros.
104  */
105 volatile unsigned short *amiga_intena_read, *amiga_intena_write;
106 
107 vaddr_t CHIPMEMADDR;
108 vaddr_t chipmem_start;
109 vaddr_t chipmem_end;
110 
111 vaddr_t z2mem_start;		/* XXX */
112 static vaddr_t z2mem_end;		/* XXX */
113 int use_z2_mem = 1;			/* XXX */
114 
115 u_long boot_fphystart, boot_fphysize, boot_cphysize;
116 static u_int start_c_fphystart;
117 static u_int start_c_pstart;
118 
119 static u_long boot_flags;
120 
121 struct boot_memlist *memlist;
122 
123 struct cfdev *cfdev;
124 int ncfdev;
125 
126 u_long scsi_nosync;
127 int shift_nosync;
128 
129 void  start_c(int, u_int, u_int, u_int, char *, u_int, u_long, u_long, u_int);
130 void rollcolor(int);
131 #ifdef DEVRELOAD
132 static int kernel_image_magic_size(void);
133 static void kernel_image_magic_copy(u_char *);
134 int kernel_reload_write(struct uio *);
135 extern void kernel_reload(char *, u_long, u_long, u_long, u_long,
136 	u_long, u_long, u_long, u_long, u_long, u_long);
137 #endif
138 extern void etext(void);
139 void start_c_finish(void);
140 
141 void *
chipmem_steal(long amount)142 chipmem_steal(long amount)
143 {
144 	/*
145 	 * steal from top of chipmem, so we don't collide with
146 	 * the kernel loaded into chipmem in the not-yet-mapped state.
147 	 */
148 	vaddr_t p = chipmem_end - amount;
149 	if (p & 1)
150 		p = p - 1;
151 	chipmem_end = p;
152 	if(chipmem_start > chipmem_end)
153 		panic("not enough chip memory");
154 	return((void *)p);
155 }
156 
157 /*
158  * XXX
159  * used by certain drivers currently to allocate zorro II memory
160  * for bounce buffers, if use_z2_mem is NULL, chipmem will be
161  * returned instead.
162  * XXX
163  */
164 void *
alloc_z2mem(long amount)165 alloc_z2mem(long amount)
166 {
167 	if (use_z2_mem && z2mem_end && (z2mem_end - amount) >= z2mem_start) {
168 		z2mem_end -= amount;
169 		return ((void *)z2mem_end);
170 	}
171 	return (alloc_chipmem(amount));
172 }
173 
174 
175 /*
176  * this is the C-level entry function, it's called from locore.s.
177  * Preconditions:
178  *	Interrupts are disabled
179  *	PA may not be == VA, so we may have to relocate addresses
180  *		before enabling the MMU
181  * 	Exec is no longer available (because we're loaded all over
182  *		low memory, no ExecBase is available anymore)
183  *
184  * It's purpose is:
185  *	Do the things that are done in locore.s in the hp300 version,
186  *		this includes allocation of kernel maps and enabling the MMU.
187  *
188  * Some of the code in here is `stolen' from Amiga MACH, and was
189  * written by Bryan Ford and Niklas Hallqvist.
190  *
191  * Very crude 68040 support by Michael L. Hitch.
192  *
193  */
194 
195 int kernel_copyback = 1;
196 
197 __attribute__ ((no_instrument_function))
198 void
start_c(int id,u_int fphystart,u_int fphysize,u_int cphysize,char * esym_addr,u_int flags,u_long inh_sync,u_long boot_part,u_int loadbase)199 start_c(int id, u_int fphystart, u_int fphysize, u_int cphysize,
200 	char *esym_addr, u_int flags, u_long inh_sync, u_long boot_part,
201 	u_int loadbase)
202 {
203 	extern char end[];
204 	extern u_int protorp[2];
205 	struct cfdev *cd;
206 	paddr_t pstart, pend;
207 	vaddr_t vstart, vend;
208 	psize_t avail;
209 	paddr_t ptpa;
210 	psize_t ptsize;
211 	u_int ptextra, kstsize;
212 	paddr_t Sysptmap_pa;
213 	register st_entry_t sg_proto, *sg;
214 #if defined(M68040) || defined(M68060)
215 	register st_entry_t *esg;
216 #endif
217 	register pt_entry_t pg_proto, *pg, *epg;
218 	vaddr_t end_loaded;
219 	u_int ncd;
220 #if defined(M68040) || defined(M68060)
221 	u_int i, nl1desc, nl2desc;
222 #endif
223 	vaddr_t kva;
224 	struct boot_memlist *ml;
225 
226 #ifdef DEBUG_KERNEL_START
227 	/* XXX this only is valid if Altais is in slot 0 */
228 	volatile u_int8_t *altaiscolpt = (u_int8_t *)0x200003c8;
229 	volatile u_int8_t *altaiscol = (u_int8_t *)0x200003c9;
230 #endif
231 
232 #ifdef DEBUG_KERNEL_START
233 	if ((id>>24)==0x7D) {
234 		*altaiscolpt = 0;
235 		*altaiscol = 40;
236 		*altaiscol = 0;
237 		*altaiscol = 0;
238 	} else
239 ((volatile struct Custom *)0xdff000)->color[0] = 0xa00;		/* RED */
240 #endif
241 
242 #ifdef LIMITMEM
243 	if (fphysize > LIMITMEM*1024*1024)
244 		fphysize = LIMITMEM*1024*1024;
245 #endif
246 
247 	RELOC(boot_fphystart, u_long) = fphystart;
248 	RELOC(boot_fphysize, u_long) = fphysize;
249 	RELOC(boot_cphysize, u_long) = cphysize;
250 
251 	RELOC(machineid, int) = id;
252 	RELOC(chipmem_end, vaddr_t) = cphysize;
253 	RELOC(esym, char *) = esym_addr;
254 	RELOC(boot_flags, u_long) = flags;
255 	RELOC(boot_partition, u_long) = boot_part;
256 #ifdef GRF_AGA
257 	if (flags & 1)
258 		RELOC(aga_enable, u_long) |= 1;
259 #endif
260 	if (flags & (3 << 1))
261 		RELOC(noncontig_enable, u_long) = (flags >> 1) & 3;
262 #if NSER > 0
263 	if (flags & (1 << 3))
264 		RELOC(serconsole, int) = 0;
265 #endif
266 
267 	RELOC(scsi_nosync, u_long) = inh_sync;
268 
269 	/*
270 	 * the kernel ends at end(), plus the cfdev and memlist structures
271 	 * we placed there in the loader.  Correct for this now.  Also,
272 	 * account for kernel symbols if they are present.
273 	 */
274 	if (esym_addr == NULL)
275 		end_loaded = (vaddr_t)&end;
276 	else
277 		end_loaded = (vaddr_t)esym_addr;
278 	RELOC(ncfdev, int) = *(int *)(&RELOC(*(u_int *)end_loaded, u_int));
279 	RELOC(cfdev, struct cfdev *) = (struct cfdev *) ((int)end_loaded + 4);
280 	end_loaded += 4 + RELOC(ncfdev, int) * sizeof(struct cfdev);
281 
282 	RELOC(memlist, struct boot_memlist *) =
283 	    (struct boot_memlist *)end_loaded;
284 	ml = &RELOC(*(struct boot_memlist *)end_loaded, struct boot_memlist);
285 	end_loaded = (vaddr_t)&((RELOC(memlist, struct boot_memlist *))->
286 	    m_seg[ml->m_nseg]);
287 
288 	/*
289 	 * Get ZorroII (16-bit) memory if there is any and it's not where the
290 	 * kernel is loaded.
291 	 */
292 	if (ml->m_nseg > 0 && ml->m_nseg < 16 && RELOC(use_z2_mem, int)) {
293 		struct boot_memseg *sp, *esp;
294 
295 		sp = ml->m_seg;
296 		esp = sp + ml->m_nseg;
297 		for (; sp < esp; sp++) {
298 			if ((sp->ms_attrib & (MEMF_FAST | MEMF_24BITDMA))
299 			    != (MEMF_FAST|MEMF_24BITDMA))
300 				continue;
301 			if (sp->ms_start == fphystart)
302 				continue;
303 			RELOC(z2mem_end, paddr_t) =
304 			    sp->ms_start + sp->ms_size;
305 			RELOC(z2mem_start, paddr_t) =
306 			    RELOC(z2mem_end, paddr_t) - MAXPHYS *
307 			    RELOC(use_z2_mem, int) * 7;
308 			RELOC(NZTWOMEMPG, u_int) =
309 			    (RELOC(z2mem_end, paddr_t) -
310 			    RELOC(z2mem_start, paddr_t)) / PAGE_SIZE;
311 			if ((RELOC(z2mem_end, paddr_t) -
312 			    RELOC(z2mem_start, paddr_t)) > sp->ms_size) {
313 				RELOC(NZTWOMEMPG, u_int) = sp->ms_size /
314 				    PAGE_SIZE;
315 				RELOC(z2mem_start, paddr_t) =
316 				    RELOC(z2mem_end, paddr_t) - sp->ms_size;
317 			}
318 			break;
319 		}
320 	}
321 
322 	/*
323 	 * Scan ConfigDev list and get size of Zorro I/O boards that are
324 	 * outside the Zorro II I/O area.
325 	 */
326 	for (RELOC(ZBUSAVAIL, u_int) = 0, cd =
327 	    &RELOC(*RELOC(cfdev, struct cfdev *),struct cfdev),
328 	    ncd = RELOC(ncfdev, int); ncd > 0; ncd--, cd++) {
329 		int bd_type = cd->rom.type & (ERT_TYPEMASK | ERTF_MEMLIST);
330 
331 		/*
332 		 * Hack to support p5bus and p5pb on CyberStorm Mk-III / PPC
333 		 * and Blizzard PPC. XXX: this hack should only be active if
334 		 * non-autoconfiguring CyberVision PPC or BlizzardVision PPC
335 		 * was found.
336 		 */
337 		if (cd->rom.manid == 8512 &&
338 		    (cd->rom.prodid == 100 || cd->rom.prodid == 110))
339 			RELOC(ZBUSAVAIL, u_int) += m68k_round_page(0x1400000);
340 #if NZ3RAMBD > 0
341 		if (z3rambd_match_id(cd->rom.manid, cd->rom.prodid) > 0)
342 		{
343 			/* XXX: remove board from memlist */
344 		} else
345 #endif
346 		if (bd_type != ERT_ZORROIII &&
347 		    (bd_type != ERT_ZORROII || isztwopa(cd->addr)))
348 			continue;	/* It's not Z2 or Z3 I/O board */
349 		/*
350 		 *  Hack to adjust board size for Zorro III boards that
351 		 *  do not specify an extended size or subsize.  This is
352 		 *  specifically for the GVP Spectrum and hopefully won't
353 		 *  break with other boards that configure like this.
354 		 */
355 		if (bd_type == ERT_ZORROIII &&
356 		    !(cd->rom.flags & ERFF_EXTENDED) &&
357 		    (cd->rom.flags & ERT_Z3_SSMASK) == 0)
358 			cd->size = 0x10000 <<
359 			    ((cd->rom.type - 1) & ERT_MEMMASK);
360 
361 		RELOC(ZBUSAVAIL, u_int) += m68k_round_page(cd->size);
362 	}
363 
364 	/*
365 	 * assume KVA_MIN == 0.  We subtract the kernel code (and
366 	 * the configdev's and memlists) from the virtual and
367 	 * physical starts and ends.
368 	 */
369 	vend   = fphysize;
370 	avail  = vend;
371 	vstart = end_loaded;
372 	vstart = m68k_round_page(vstart);
373 	pstart = (paddr_t)vstart + fphystart;
374 	pend   = vend   + fphystart;
375 	avail -= vstart;
376 
377 	/*
378 	 * save KVA of lwp0 u-area and allocate it.
379 	 */
380 	RELOC(lwp0uarea, vaddr_t) = vstart;
381 	pstart += USPACE;
382 	vstart += USPACE;
383 	avail -= USPACE;
384 
385 #if defined(M68040) || defined(M68060)
386 	if (RELOC(mmutype, int) == MMU_68040)
387 		kstsize = MAXKL2SIZE / (NPTEPG/SG4_LEV2SIZE);
388 	else
389 #endif
390 		kstsize = 1;
391 
392 	/*
393 	 * allocate the kernel segment table
394 	 */
395 	RELOC(Sysseg_pa, u_int) = pstart;
396 	RELOC(Sysseg, u_int) = vstart;
397 	vstart += PAGE_SIZE * kstsize;
398 	pstart += PAGE_SIZE * kstsize;
399 	avail -= PAGE_SIZE * kstsize;
400 
401 	/*
402 	 * allocate kernel page table map
403 	 */
404 	RELOC(Sysptmap, u_int) = vstart;
405 	Sysptmap_pa = pstart;
406 	vstart += PAGE_SIZE;
407 	pstart += PAGE_SIZE;
408 	avail -= PAGE_SIZE;
409 
410 	/*
411 	 * allocate initial page table pages
412 	 */
413 	ptpa = pstart;
414 #ifdef DRACO
415 	if ((id>>24)==0x7D) {
416 		ptextra = NDRCCPG
417 		    + RELOC(NZTWOMEMPG, u_int)
418 		    + btoc(RELOC(ZBUSAVAIL, u_int));
419 	} else
420 #endif
421 	ptextra = NCHIPMEMPG + NCIAPG + NZTWOROMPG + RELOC(NZTWOMEMPG, u_int) +
422 	    btoc(RELOC(ZBUSAVAIL, u_int)) + NPCMCIAPG;
423 
424 	ptsize = (RELOC(Sysptsize, u_int) +
425 	    howmany(ptextra, NPTEPG)) << PGSHIFT;
426 
427 	vstart += ptsize;
428 	pstart += ptsize;
429 	avail -= ptsize;
430 
431 	/*
432 	 * Sysmap is now placed at the end of Supervisor virtual address space.
433 	 */
434 	RELOC(Sysmap, u_int *) = (u_int *)SYSMAP_VA;
435 
436 	/*
437 	 * initialize segment table and page table map
438 	 */
439 #if defined(M68040) || defined(M68060)
440 	if (RELOC(mmutype, int) == MMU_68040) {
441 		/*
442 		 * First invalidate the entire "segment table" pages
443 		 * (levels 1 and 2 have the same "invalid" values).
444 		 */
445 		sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
446 		esg = &sg[kstsize * NPTEPG];
447 		while (sg < esg)
448 			*sg++ = SG_NV;
449 		/*
450 		 * Initialize level 2 descriptors (which immediately
451 		 * follow the level 1 table).  We need:
452 		 *	NPTEPG / SG4_LEV3SIZE
453 		 * level 2 descriptors to map each of the nptpages
454 		 * pages of PTEs.  Note that we set the "used" bit
455 		 * now to save the HW the expense of doing it.
456 		 */
457 		nl2desc = (ptsize >> PGSHIFT) * (NPTEPG / SG4_LEV3SIZE);
458 		sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
459 		sg = &sg[SG4_LEV1SIZE];
460 		esg = &sg[nl2desc];
461 		sg_proto = ptpa | SG_U | SG_RW | SG_V;
462 		while (sg < esg) {
463 			*sg++ = sg_proto;
464 			sg_proto += (SG4_LEV3SIZE * sizeof (st_entry_t));
465 		}
466 
467 		/*
468 		 * Initialize level 1 descriptors.  We need:
469 		 *	howmany(nl2desc, SG4_LEV2SIZE)
470 		 * level 1 descriptors to map the 'nl2desc' level 2's.
471 		 */
472 		nl1desc = howmany(nl2desc, SG4_LEV2SIZE);
473 		sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
474 		esg = &sg[nl1desc];
475 		sg_proto = (paddr_t)&sg[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
476 		while (sg < esg) {
477 			*sg++ = sg_proto;
478 			sg_proto += (SG4_LEV2SIZE * sizeof(st_entry_t));
479 		}
480 
481 		/* Sysmap is last entry in level 1 */
482 		sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
483 		sg = &sg[SG4_LEV1SIZE - 1];
484 		*sg = sg_proto;
485 
486 		/*
487 		 * Kernel segment table at end of next level 2 table
488 		 */
489 		i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
490 		sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
491 		sg = &sg[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)];
492 		esg = &sg[NPTEPG / SG4_LEV3SIZE];
493 		sg_proto = Sysptmap_pa | SG_U | SG_RW | SG_V;
494 		while (sg < esg) {
495 			*sg++ = sg_proto;
496 			sg_proto += (SG4_LEV3SIZE * sizeof (st_entry_t));
497 		}
498 
499 		/* Include additional level 2 table for Sysmap in protostfree */
500 		RELOC(protostfree, u_int) =
501 		    (~0 << (1 + nl1desc + 1)) /* & ~(~0 << MAXKL2SIZE) */;
502 
503 		/*
504 		 * Initialize Sysptmap
505 		 */
506 		pg = (pt_entry_t *)Sysptmap_pa;
507 		epg = &pg[ptsize >> PGSHIFT];
508 		pg_proto = ptpa | PG_RW | PG_CI | PG_V;
509 		while (pg < epg) {
510 			*pg++ = pg_proto;
511 			pg_proto += PAGE_SIZE;
512 		}
513 		/*
514 		 * Invalidate rest of Sysptmap page
515 		 */
516 		epg = (pt_entry_t *)(Sysptmap_pa + PAGE_SIZE - sizeof(st_entry_t));
517 		while (pg < epg)
518 			*pg++ = SG_NV;
519 		pg = (pt_entry_t *)Sysptmap_pa;
520 		pg = &pg[SYSMAP_VA >> SEGSHIFT];
521 		*pg = Sysptmap_pa | PG_RW | PG_CI | PG_V;
522 	} else
523 #endif /* M68040 */
524 	{
525 		/*
526 		 * Map the page table pages in both the HW segment table
527 		 * and the software Sysptmap.
528 		 */
529 		sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
530 		pg = (pt_entry_t *)Sysptmap_pa;
531 		epg = &pg[ptsize >> PGSHIFT];
532 		sg_proto = ptpa | SG_RW | SG_V;
533 		pg_proto = ptpa | PG_RW | PG_CI | PG_V;
534 		while (pg < epg) {
535 			*sg++ = sg_proto;
536 			*pg++ = pg_proto;
537 			sg_proto += PAGE_SIZE;
538 			pg_proto += PAGE_SIZE;
539 		}
540 		/*
541 		 * invalidate the remainder of each table
542 		 */
543 		epg = (pt_entry_t *)Sysptmap_pa;
544 		epg = &epg[TIA_SIZE];
545 		while (pg < epg) {
546 			*sg++ = SG_NV;
547 			*pg++ = PG_NV;
548 		}
549 		sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
550 		sg = &sg[SYSMAP_VA >> SEGSHIFT];
551 		pg = (pt_entry_t *)Sysptmap_pa;
552 		pg = &pg[SYSMAP_VA >> SEGSHIFT];
553 		*sg = Sysptmap_pa | SG_RW | SG_V;
554 		*pg = Sysptmap_pa | PG_RW | PG_CI | PG_V;
555 		/* XXX zero out rest of page? */
556 	}
557 
558 	/*
559 	 * initialize kernel page table page(s) (assume load at VA 0)
560 	 */
561 	pg_proto = fphystart | PG_RO | PG_V;	/* text pages are RO */
562 	pg       = (pt_entry_t *)ptpa;
563 	*pg++ = PG_NV;				/* Make page 0 invalid */
564 	pg_proto += PAGE_SIZE;
565 	for (kva = PAGE_SIZE; kva < (vaddr_t)etext;
566 	     kva += PAGE_SIZE, pg_proto += PAGE_SIZE)
567 		*pg++ = pg_proto;
568 
569 	/*
570 	 * data, bss and dynamic tables are read/write
571 	 */
572 	pg_proto = (pg_proto & PG_FRAME) | PG_RW | PG_V;
573 
574 #if defined(M68040) || defined(M68060)
575 	/*
576 	 * Map the kernel segment table cache invalidated for 68040/68060.
577 	 * (for the 68040 not strictly necessary, but recommended by Motorola;
578 	 *  for the 68060 mandatory)
579 	 */
580 	if (RELOC(mmutype, int) == MMU_68040) {
581 
582 		if (RELOC(kernel_copyback, int))
583 			pg_proto |= PG_CCB;
584 
585 		/*
586 		 * ASSUME: segment table and statically allocated page tables
587 		 * of the kernel are contiguously allocated, start at
588 		 * Sysseg and end at the current value of vstart.
589 		 */
590 		for (; kva < RELOC(Sysseg, u_int);
591 		     kva += PAGE_SIZE, pg_proto += PAGE_SIZE)
592 			*pg++ = pg_proto;
593 
594 		pg_proto = (pg_proto & ~PG_CCB) | PG_CI;
595 		for (; kva < vstart; kva += PAGE_SIZE, pg_proto += PAGE_SIZE)
596 			*pg++ = pg_proto;
597 
598 		pg_proto = (pg_proto & ~PG_CI);
599 		if (RELOC(kernel_copyback, int))
600 			pg_proto |= PG_CCB;
601 	}
602 #endif
603 	/*
604 	 * go till end of data allocated so far
605 	 * plus lwp0 u-area (to be allocated)
606 	 */
607 	for (; kva < vstart; kva += PAGE_SIZE, pg_proto += PAGE_SIZE)
608 		*pg++ = pg_proto;
609 	/*
610 	 * invalidate remainder of kernel PT
611 	 */
612 	while (pg < (pt_entry_t *) (ptpa + ptsize))
613 		*pg++ = PG_NV;
614 
615 	/*
616 	 * validate internal IO PTEs following current vstart
617 	 */
618 	pg = &((u_int *)ptpa)[vstart >> PGSHIFT];
619 #ifdef DRACO
620 	if ((id >> 24) == 0x7D) {
621 		RELOC(DRCCADDR, u_int) = vstart;
622 		RELOC(CIAADDR, vaddr_t) =
623 		    RELOC(DRCCADDR, u_int) + DRCIAPG * PAGE_SIZE;
624 		if (RELOC(z2mem_end, vaddr_t) == 0)
625 			RELOC(ZBUSADDR, vaddr_t) =
626 			   RELOC(DRCCADDR, u_int) + NDRCCPG * PAGE_SIZE;
627 		pg_proto = DRCCBASE | PG_RW | PG_CI | PG_V;
628 		while (pg_proto < DRZ2BASE) {
629 			*pg++ = pg_proto;
630 			pg_proto += DRCCSTRIDE;
631 			vstart += PAGE_SIZE;
632 		}
633 
634 		/* NCR 53C710 chip */
635 		*pg++ = DRSCSIBASE | PG_RW | PG_CI | PG_V;
636 		vstart += PAGE_SIZE;
637 
638 #ifdef DEBUG_KERNEL_START
639 		/*
640 		 * early rollcolor Altais mapping
641 		 * XXX (only works if in slot 0)
642 		 */
643 		*pg++ = 0x20000000 | PG_RW | PG_CI | PG_V;
644 		vstart += PAGE_SIZE;
645 #endif
646 	} else
647 #endif
648 	{
649 		RELOC(CHIPMEMADDR, vaddr_t) = vstart;
650 		pg_proto = CHIPMEMBASE | PG_RW | PG_CI | PG_V;
651 						/* CI needed here?? */
652 		while (pg_proto < CHIPMEMTOP) {
653 			*pg++     = pg_proto;
654 			pg_proto += PAGE_SIZE;
655 			vstart   += PAGE_SIZE;
656 		}
657 	}
658 	if (RELOC(z2mem_end, paddr_t)) {			/* XXX */
659 		RELOC(ZTWOMEMADDR, vaddr_t) = vstart;
660 		RELOC(ZBUSADDR, vaddr_t) = RELOC(ZTWOMEMADDR, vaddr_t) +
661 		    RELOC(NZTWOMEMPG, u_int) * PAGE_SIZE;
662 		pg_proto = RELOC(z2mem_start, paddr_t) |	/* XXX */
663 		    PG_RW | PG_V;				/* XXX */
664 		while (pg_proto < RELOC(z2mem_end, paddr_t)) { /* XXX */
665 			*pg++ = pg_proto;			/* XXX */
666 			pg_proto += PAGE_SIZE;			/* XXX */
667 			vstart   += PAGE_SIZE;
668 		}						/* XXX */
669 	}							/* XXX */
670 #ifdef DRACO
671 	if ((id >> 24) != 0x7D)
672 #endif
673 	{
674 		RELOC(CIAADDR, vaddr_t) = vstart;
675 		pg_proto = CIABASE | PG_RW | PG_CI | PG_V;
676 		while (pg_proto < CIATOP) {
677 			*pg++     = pg_proto;
678 			pg_proto += PAGE_SIZE;
679 			vstart   += PAGE_SIZE;
680 		}
681 		RELOC(ZTWOROMADDR, vaddr_t) = vstart;
682 		pg_proto  = ZTWOROMBASE | PG_RW | PG_CI | PG_V;
683 		while (pg_proto < ZTWOROMTOP) {
684 			*pg++     = pg_proto;
685 			pg_proto += PAGE_SIZE;
686 			vstart   += PAGE_SIZE;
687 		}
688 		RELOC(ZBUSADDR, vaddr_t) = vstart;
689 		/* not on 8k boundary :-( */
690 		RELOC(CIAADDR, vaddr_t) += PAGE_SIZE/2;
691 		RELOC(CUSTOMADDR, vaddr_t)  =
692 		    RELOC(ZTWOROMADDR, vaddr_t) - ZTWOROMBASE + CUSTOMBASE;
693 	}
694 
695 	/*
696 	 *[ following page tables MAY be allocated to ZORRO3 space,
697 	 * but they're then later mapped in autoconf.c ]
698 	 */
699 	vstart += RELOC(ZBUSAVAIL, u_int);
700 
701 	/*
702 	 * init mem sizes
703 	 */
704 	RELOC(maxmem, u_int)  = pend >> PGSHIFT;
705 	RELOC(lowram, u_int)  = fphystart;
706 	RELOC(physmem, u_int) = fphysize >> PGSHIFT;
707 
708 	RELOC(virtual_avail, u_int) = vstart;
709 
710 	/*
711 	 * Put user page tables starting at next 16MB boundary, to make kernel
712 	 * dumps more readable, with guaranteed 16MB of.
713 	 * XXX 16 MB instead of 256 MB should be enough, but...
714 	 * we need to fix the fastmem loading first. (see comment at line 375)
715 	 */
716 	RELOC(m68k_uptbase, vaddr_t) =
717 	    roundup(vstart + 0x10000000, 0x10000000);
718 
719 	/*
720 	 * set this before copying the kernel, so the variable is updated in
721 	 * the `real' place too. protorp[0] is already preset to the
722 	 * CRP setting.
723 	 */
724 	RELOC(protorp[1], u_int) = RELOC(Sysseg_pa, u_int);
725 
726 	RELOC(start_c_fphystart, u_int) = fphystart;
727 	RELOC(start_c_pstart, u_int) = pstart;
728 
729 	/*
730 	 * copy over the kernel (and all now initialized variables)
731 	 * to fastram.  DONT use bcopy(), this beast is much larger
732 	 * than 128k !
733 	 */
734 	if (loadbase == 0) {
735 		register paddr_t *lp, *le, *fp;
736 
737 		lp = (paddr_t *)0;
738 		le = (paddr_t *)end_loaded;
739 		fp = (paddr_t *)fphystart;
740 		while (lp < le)
741 			*fp++ = *lp++;
742 	}
743 
744 #ifdef DEBUG_KERNEL_START
745 	if ((id>>24)==0x7D) {
746 		*altaiscolpt = 0;
747 		*altaiscol = 40;
748 		*altaiscol = 40;
749 		*altaiscol = 0;
750 	} else
751 ((volatile struct Custom *)0xdff000)->color[0] = 0xAA0;		/* YELLOW */
752 #endif
753 	/*
754 	 * prepare to enable the MMU
755 	 */
756 #if defined(M68040) || defined(M68060)
757 	if (RELOC(mmutype, int) == MMU_68040) {
758 		if (id & AMIGA_68060) {
759 			/* do i need to clear the branch cache? */
760 			__asm volatile (	".word 0x4e7a,0x0002;"
761 					"orl #0x400000,%%d0;"
762 					".word 0x4e7b,0x0002" : : : "d0");
763 		}
764 
765 		/*
766 		 * movel Sysseg_pa,%a0;
767 		 * movec %a0,%srp;
768 		 */
769 
770 		__asm volatile ("movel %0,%%a0; .word 0x4e7b,0x8807"
771 		    : : "a" (RELOC(Sysseg_pa, u_int)) : "a0");
772 
773 #ifdef DEBUG_KERNEL_START
774 		if ((id>>24)==0x7D) {
775 			*altaiscolpt = 0;
776 			*altaiscol = 40;
777 			*altaiscol = 33;
778 			*altaiscol = 0;
779 		} else
780 ((volatile struct Custom *)0xdff000)->color[0] = 0xA70;		/* ORANGE */
781 #endif
782 	} else
783 #endif
784 	{
785 		/*
786 		 * setup and load SRP
787 		 * nolimit, share global, 4 byte PTE's
788 		 */
789 		(RELOC(protorp[0], u_int)) = 0x80000202;
790 		__asm volatile ("pmove %0@,%%srp":: "a" (&RELOC(protorp, u_int)));
791 	}
792 }
793 
794 void
start_c_finish(void)795 start_c_finish(void)
796 {
797 	extern u_int32_t delaydivisor;
798 #ifdef	P5PPC68KBOARD
799         struct cfdev *cdp, *ecdp;
800 #endif
801 
802 #ifdef DEBUG_KERNEL_START
803 #ifdef DRACO
804 	if ((id >> 24) == 0x7D) { /* mapping on, is_draco() is valid */
805 		int i;
806 		/* XXX experimental Altais register mapping only */
807 		altaiscolpt = (volatile u_int8_t *)(DRCCADDR+PAGE_SIZE*9+0x3c8);
808 		altaiscol = altaiscolpt + 1;
809 		for (i=0; i<140000; i++) {
810 			*altaiscolpt = 0;
811 			*altaiscol = 0;
812 			*altaiscol = 40;
813 			*altaiscol = 0;
814 		}
815 	} else
816 #endif
817 ((volatile struct Custom *)CUSTOMADDR)->color[0] = 0x0a0;	/* GREEN */
818 #endif
819 
820 	pmap_bootstrap(start_c_pstart, start_c_fphystart);
821 	pmap_bootstrap_finalize();
822 
823 	/*
824 	 * to make life easier in locore.s, set these addresses explicitly
825 	 */
826 	CIAAbase = CIAADDR + 0x1001;	/* CIA-A at odd addresses ! */
827 	CIABbase = CIAADDR;
828 	CUSTOMbase = CUSTOMADDR;
829 #ifdef DRACO
830 	if (is_draco()) {
831 		draco_intena = (volatile u_int8_t *)DRCCADDR+1;
832 		draco_intpen = draco_intena + PAGE_SIZE;
833 		draco_intfrc = draco_intpen + PAGE_SIZE;
834 		draco_misc = draco_intfrc + PAGE_SIZE;
835 		draco_ioct = (struct drioct *)(DRCCADDR + DRIOCTLPG*PAGE_SIZE);
836 	} else
837 #endif
838 	{
839 		INTREQRaddr = (vaddr_t)&custom.intreqr;
840 		INTREQWaddr = (vaddr_t)&custom.intreq;
841 	}
842 	/*
843 	 * Get our chip memory allocation system working
844 	 */
845 	chipmem_start += CHIPMEMADDR;
846 	chipmem_end   += CHIPMEMADDR;
847 
848 	/* XXX is: this MUST NOT BE DONE before the pmap_bootstrap() call */
849 	if (z2mem_end) {
850 		z2mem_end = ZTWOMEMADDR + NZTWOMEMPG * PAGE_SIZE;
851 		z2mem_start = ZTWOMEMADDR;
852 	}
853 
854 	/*
855 	 * disable all interrupts but enable allow them to be enabled
856 	 * by specific driver code (global int enable bit)
857 	 */
858 #ifdef DRACO
859 	if (is_draco()) {
860 		/* XXX to be done. For now, just: */
861 		*draco_intena = 0;
862 		*draco_intpen = 0;
863 		*draco_intfrc = 0;
864 		ciaa.icr = 0x7f;			/* and keyboard */
865 		ciab.icr = 0x7f;			/* and again */
866 
867 		draco_ioct->io_control &=
868 		    ~(DRCNTRL_KBDINTENA|DRCNTRL_FDCINTENA); /* and another */
869 
870 		draco_ioct->io_status2 &=
871 		    ~(DRSTAT2_PARIRQENA|DRSTAT2_TMRINTENA); /* some more */
872 
873 		*(volatile u_int8_t *)(DRCCADDR + 1 +
874 		    DRSUPIOPG*PAGE_SIZE + 4*(0x3F8 + 1)) = 0; /* and com0 */
875 
876 		*(volatile u_int8_t *)(DRCCADDR + 1 +
877 		    DRSUPIOPG*PAGE_SIZE + 4*(0x2F8 + 1)) = 0; /* and com1 */
878 
879 		draco_ioct->io_control |= DRCNTRL_WDOGDIS; /* stop Fido */
880 		*draco_misc &= ~1/*DRMISC_FASTZ2*/;
881 
882 	} else
883 #endif
884 	{
885 		custom.intena = 0x7fff;			/* disable ints */
886 		custom.intena = INTF_SETCLR | INTF_INTEN;
887 							/* but allow them */
888 		custom.intreq = 0x7fff;			/* clear any current */
889 		ciaa.icr = 0x7f;			/* and keyboard */
890 		ciab.icr = 0x7f;			/* and again */
891 
892 		/*
893 		 * remember address of read and write intena register for use
894 		 * by extended spl?() macros.
895 		 */
896 		amiga_intena_read  = &custom.intenar;
897 		amiga_intena_write = &custom.intena;
898 	}
899 
900 	/*
901 	 * This is needed for 3000's with superkick ROM's. Bit 7 of
902 	 * 0xde0002 enables the ROM if set. If this isn't set the machine
903 	 * has to be powercycled in order for it to boot again. ICKA! RFH
904 	 */
905 	if (is_a3000()) {
906 		volatile unsigned char *a3000_magic_reset;
907 
908 		a3000_magic_reset = (volatile unsigned char *)ztwomap(0xde0002);
909 
910 		/* Turn SuperKick ROM (V36) back on */
911 		*a3000_magic_reset |= 0x80;
912 	}
913 
914 #ifdef	P5PPC68KBOARD
915 	/*
916 	 * Are we an P5 PPC/68K board? install different reset
917 	 * routine.
918 	 */
919 
920         for (cdp = cfdev, ecdp = &cfdev[ncfdev]; cdp < ecdp; cdp++) {
921 		if (cdp->rom.manid == 8512 &&
922 		    (cdp->rom.prodid == 100 || cdp->rom.prodid == 110)) {
923 		    		p5ppc = 1;
924 				break;
925 			}
926         }
927 #endif
928 	/*
929 	 * preliminary delay divisor value
930 	 */
931 
932 	if (machineid & AMIGA_68060)
933 		delaydivisor = (1024 * 1) / 80;	/* 80 MHz 68060 w. BTC */
934 
935 	else if (machineid & AMIGA_68040)
936 		delaydivisor = (1024 * 3) / 40;	/* 40 MHz 68040 */
937 
938 	else if (machineid & AMIGA_68030)
939 		delaydivisor = (1024 * 8) / 50;	/* 50 MHz 68030 */
940 
941 	else
942 		delaydivisor = (1024 * 8) / 33; /* 33 MHz 68020 */
943 }
944 
945 void
rollcolor(int color)946 rollcolor(int color)
947 {
948 	int s, i;
949 
950 	s = splhigh();
951 	/*
952 	 * need to adjust count -
953 	 * too slow when cache off, too fast when cache on
954 	 */
955 	for (i = 0; i < 400000; i++)
956 		((volatile struct Custom *)CUSTOMbase)->color[0] = color;
957 	splx(s);
958 }
959 
960 #ifdef DEVRELOAD
961 /*
962  * Kernel reloading code
963  */
964 
965 static struct exec kernel_exec;
966 static u_char *kernel_image;
967 static u_long kernel_text_size, kernel_load_ofs;
968 static u_long kernel_load_phase;
969 static u_long kernel_load_endseg;
970 static u_long kernel_symbol_size, kernel_symbol_esym;
971 
972 /* This supports the /dev/reload device, major 2, minor 20,
973    hooked into mem.c.  Author: Bryan Ford.  */
974 
975 /*
976  * This is called below to find out how much magic storage
977  * will be needed after a kernel image to be reloaded.
978  */
979 static int
kernel_image_magic_size(void)980 kernel_image_magic_size(void)
981 {
982 	int sz;
983 
984 	/* 4 + cfdev's + Mem_Seg's + 4 */
985 	sz = 8 + ncfdev * sizeof(struct cfdev)
986 	    + memlist->m_nseg * sizeof(struct boot_memseg);
987 	return(sz);
988 }
989 
990 /* This actually copies the magic information.  */
991 static void
kernel_image_magic_copy(u_char * dest)992 kernel_image_magic_copy(u_char *dest)
993 {
994 	*((int*)dest) = ncfdev;
995 	dest += 4;
996 	memcpy(dest, cfdev, ncfdev * sizeof(struct cfdev)
997 	    + memlist->m_nseg * sizeof(struct boot_memseg) + 4);
998 }
999 
1000 #undef AOUT_LDPGSZ
1001 #define AOUT_LDPGSZ 8192 /* XXX ??? */
1002 
1003 int
kernel_reload_write(struct uio * uio)1004 kernel_reload_write(struct uio *uio)
1005 {
1006 	extern int eclockfreq;
1007 	struct iovec *iov;
1008 	int error, c;
1009 
1010 	iov = uio->uio_iov;
1011 
1012 	if (kernel_image == 0) {
1013 		/*
1014 		 * We have to get at least the whole exec header
1015 		 * in the first write.
1016 		 */
1017 		if (iov->iov_len < sizeof(kernel_exec))
1018 			return ENOEXEC;		/* XXX */
1019 
1020 		/*
1021 		 * Pull in the exec header and check it.
1022 		 */
1023 		if ((error = uiomove((void *)&kernel_exec, sizeof(kernel_exec),
1024 		     uio)) != 0)
1025 			return(error);
1026 		printf("loading kernel %ld+%ld+%ld+%ld\n", kernel_exec.a_text,
1027 		    kernel_exec.a_data, kernel_exec.a_bss,
1028 		    esym == NULL ? 0 : kernel_exec.a_syms);
1029 		/*
1030 		 * Looks good - allocate memory for a kernel image.
1031 		 */
1032 		kernel_text_size = (kernel_exec.a_text
1033 			+ AOUT_LDPGSZ - 1) & (-AOUT_LDPGSZ);
1034 		/*
1035 		 * Estimate space needed for symbol names, since we don't
1036 		 * know how big it really is.
1037 		 */
1038 		if (esym != NULL) {
1039 			kernel_symbol_size = kernel_exec.a_syms;
1040 			kernel_symbol_size += 16 * (kernel_symbol_size / 12);
1041 		}
1042 		/*
1043 		 * XXX - should check that image will fit in CHIP memory
1044 		 * XXX return an error if it doesn't
1045 		 */
1046 		if ((kernel_text_size + kernel_exec.a_data +
1047 		    kernel_exec.a_bss + kernel_symbol_size +
1048 		    kernel_image_magic_size()) > boot_cphysize)
1049 			return (EFBIG);
1050 		kernel_image = malloc(kernel_text_size + kernel_exec.a_data
1051 			+ kernel_exec.a_bss
1052 			+ kernel_symbol_size
1053 			+ kernel_image_magic_size(),
1054 			M_TEMP, M_WAITOK);
1055 		kernel_load_ofs = 0;
1056 		kernel_load_phase = 0;
1057 		kernel_load_endseg = kernel_exec.a_text;
1058 		return(0);
1059 	}
1060 	/*
1061 	 * Continue loading in the kernel image.
1062 	 */
1063 	c = uimin(iov->iov_len, kernel_load_endseg - kernel_load_ofs);
1064 	c = uimin(c, MAXPHYS);
1065 	if ((error = uiomove(kernel_image + kernel_load_ofs, (int)c, uio)) != 0)
1066 		return(error);
1067 	kernel_load_ofs += c;
1068 
1069 	/*
1070 	 * Fun and games to handle loading symbols - the length of the
1071 	 * string table isn't know until after the symbol table has
1072 	 * been loaded.  We have to load the kernel text, data, and
1073 	 * the symbol table, then get the size of the strings.  A
1074 	 * new kernel image is then allocated and the data currently
1075 	 * loaded moved to the new image.  Then continue reading the
1076 	 * string table.  This has problems if there isn't enough
1077 	 * room to allocate space for the two copies of the kernel
1078 	 * image.  So the approach I took is to guess at the size
1079 	 * of the symbol strings.  If the guess is wrong, the symbol
1080 	 * table is ignored.
1081 	 */
1082 
1083 	if (kernel_load_ofs != kernel_load_endseg)
1084 		return(0);
1085 
1086 	switch (kernel_load_phase) {
1087 	case 0:		/* done loading kernel text */
1088 		kernel_load_ofs = kernel_text_size;
1089 		kernel_load_endseg = kernel_load_ofs + kernel_exec.a_data;
1090 		kernel_load_phase = 1;
1091 		break;
1092 	case 1:		/* done loading kernel data */
1093 		for(c = 0; c < kernel_exec.a_bss; c++)
1094 			kernel_image[kernel_load_ofs + c] = 0;
1095 		kernel_load_ofs += kernel_exec.a_bss;
1096 		if (esym) {
1097 			kernel_load_endseg = kernel_load_ofs
1098 			    + kernel_exec.a_syms + 8;
1099 			*((u_long *)(kernel_image + kernel_load_ofs)) =
1100 			    kernel_exec.a_syms;
1101 			kernel_load_ofs += 4;
1102 			kernel_load_phase = 3;
1103 			break;
1104 		}
1105 		/*FALLTHROUGH*/
1106 	case 2:		/* done loading kernel */
1107 
1108 		/*
1109 		 * Put the finishing touches on the kernel image.
1110 		 */
1111 		kernel_image_magic_copy(kernel_image + kernel_load_ofs);
1112 		/*
1113 		 * Start the new kernel with code in locore.s.
1114 		 */
1115 		kernel_reload(kernel_image,
1116 		    kernel_load_ofs + kernel_image_magic_size(),
1117 		    kernel_exec.a_entry, boot_fphystart, boot_fphysize,
1118 		    boot_cphysize, kernel_symbol_esym, eclockfreq,
1119 		    boot_flags, scsi_nosync, boot_partition);
1120 		/*
1121 		 * kernel_reload() now checks to see if the reload_code
1122 		 * is at the same location in the new kernel.
1123 		 * If it isn't, it will return and we will return
1124 		 * an error.
1125 		 */
1126 		free(kernel_image, M_TEMP);
1127 		kernel_image = NULL;
1128 		return (ENODEV);	/* Say operation not supported */
1129 	case 3:		/* done loading kernel symbol table */
1130 		c = *((u_long *)(kernel_image + kernel_load_ofs - 4));
1131 		if (c > 16 * (kernel_exec.a_syms / 12))
1132 			c = 16 * (kernel_exec.a_syms / 12);
1133 		kernel_load_endseg += c - 4;
1134 		kernel_symbol_esym = kernel_load_endseg;
1135 #ifdef notyet
1136 		kernel_image_copy = kernel_image;
1137 		kernel_image = malloc(kernel_load_ofs + c
1138 		    + kernel_image_magic_size(), M_TEMP, M_WAITOK);
1139 		if (kernel_image == NULL)
1140 			panic("kernel_reload failed second malloc");
1141 		for (c = 0; c < kernel_load_ofs; c += MAXPHYS)
1142 			memcpy(kernel_image + c, kernel_image_copy + c,
1143 			    (kernel_load_ofs - c) > MAXPHYS ? MAXPHYS :
1144 			    kernel_load_ofs - c);
1145 #endif
1146 		kernel_load_phase = 2;
1147 	}
1148 	return(0);
1149 }
1150 #endif
1151 
1152 int
mm_md_readwrite(dev_t dev,struct uio * uio)1153 mm_md_readwrite(dev_t dev, struct uio *uio)
1154 {
1155 
1156 	switch (minor(dev)) {
1157 #ifdef DEVRELOAD
1158 	case DEV_RELOAD:
1159 		if (uio->uio_rw == UIO_READ)
1160 			return 0;
1161 		return kernel_reload_write(uio);
1162 #endif
1163 	default:
1164 		return ENXIO;
1165 	}
1166 }
1167