machdep.c revision 2014
1/*-
2 * Copyright (c) 1992 Terrence R. Lambert.
3 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * William Jolitz.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *	This product includes software developed by the University of
20 *	California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 *    may be used to endorse or promote products derived from this software
23 *    without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 *	from: @(#)machdep.c	7.4 (Berkeley) 6/3/91
38 *	$Id: machdep.c,v 1.49 1994/08/10 03:53:33 wollman Exp $
39 */
40
41#include "npx.h"
42#include "isa.h"
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/signalvar.h>
47#include <sys/kernel.h>
48#include <sys/map.h>
49#include <sys/proc.h>
50#include <sys/user.h>
51#include <sys/buf.h>
52#include <sys/reboot.h>
53#include <sys/conf.h>
54#include <sys/file.h>
55#include <sys/callout.h>
56#include <sys/malloc.h>
57#include <sys/mbuf.h>
58#include <sys/msgbuf.h>
59#include <sys/ioctl.h>
60#include <sys/tty.h>
61#include <sys/sysctl.h>
62
63#ifdef SYSVSHM
64#include "sys/shm.h"
65#endif
66
67#ifdef SYSVMSG
68#include "msg.h"
69#endif
70
71#ifdef SYSVSEM
72#include "sem.h"
73#endif
74
75#include "vm/vm.h"
76#include "vm/vm_kern.h"
77#include "vm/vm_page.h"
78
79#include "sys/exec.h"
80#include "sys/vnode.h"
81
82extern vm_offset_t avail_start, avail_end;
83
84#include "machine/cpu.h"
85#include "machine/reg.h"
86#include "machine/psl.h"
87#include "machine/specialreg.h"
88#include "machine/sysarch.h"
89#include "machine/cons.h"
90
91#include "i386/isa/isa.h"
92#include "i386/isa/rtc.h"
93
94static void identifycpu(void);
95static void initcpu(void);
96static int test_page(int *, int);
97
98extern int grow(struct proc *,u_int);
99char machine[] = "i386";
100char cpu_model[sizeof("Pentium") + 1];
101
102#ifndef PANIC_REBOOT_WAIT_TIME
103#define PANIC_REBOOT_WAIT_TIME 15 /* default to 15 seconds */
104#endif
105
106/*
107 * Declare these as initialized data so we can patch them.
108 */
109int	nswbuf = 0;
110#ifdef	NBUF
111int	nbuf = NBUF;
112#else
113int	nbuf = 0;
114#endif
115#ifdef	BUFPAGES
116int	bufpages = BUFPAGES;
117#else
118int	bufpages = 0;
119#endif
120#ifdef BOUNCEPAGES
121int	bouncepages = BOUNCEPAGES;
122#else
123int	bouncepages = 0;
124#endif
125int	msgbufmapped = 0;		/* set when safe to use msgbuf */
126extern int freebufspace;
127extern char *bouncememory;
128
129int _udatasel, _ucodesel;
130
131/*
132 * Machine-dependent startup code
133 */
134int boothowto = 0, Maxmem = 0, badpages = 0, physmem = 0;
135long dumplo;
136extern int bootdev;
137int biosmem;
138
139vm_offset_t	phys_avail[6];
140
141extern cyloffset;
142
143int cpu_class;
144
145void dumpsys __P((void));
146vm_offset_t buffer_sva, buffer_eva;
147vm_offset_t clean_sva, clean_eva;
148vm_offset_t pager_sva, pager_eva;
149int maxbkva, pager_map_size;
150
151#define offsetof(type, member)	((size_t)(&((type *)0)->member))
152
153void
154cpu_startup()
155{
156	register int unixsize;
157	register unsigned i;
158	register struct pte *pte;
159	int mapaddr, j;
160	register caddr_t v;
161	int maxbufs, base, residual;
162	extern long Usrptsize;
163	vm_offset_t minaddr, maxaddr;
164	vm_size_t size = 0;
165	int firstaddr;
166
167	/*
168	 * Initialize error message buffer (at end of core).
169	 */
170
171	/* avail_end was pre-decremented in init_386() to compensate */
172	for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
173		pmap_enter(pmap_kernel(), (vm_offset_t)msgbufp,
174			   avail_end + i * NBPG,
175			   VM_PROT_ALL, TRUE);
176	msgbufmapped = 1;
177
178	/*
179	 * Good {morning,afternoon,evening,night}.
180	 */
181	printf(version);
182	startrtclock();
183	identifycpu();
184	printf("real memory  = %d (%d pages)\n", ptoa(physmem), physmem);
185	if (badpages)
186		printf("bad memory   = %d (%d pages)\n", ptoa(badpages), badpages);
187
188	/*
189	 * Allocate space for system data structures.
190	 * The first available kernel virtual address is in "v".
191	 * As pages of kernel virtual memory are allocated, "v" is incremented.
192	 * As pages of memory are allocated and cleared,
193	 * "firstaddr" is incremented.
194	 * An index into the kernel page table corresponding to the
195	 * virtual memory address maintained in "v" is kept in "mapaddr".
196	 */
197
198	/*
199	 * Make two passes.  The first pass calculates how much memory is
200	 * needed and allocates it.  The second pass assigns virtual
201	 * addresses to the various data structures.
202	 */
203	firstaddr = 0;
204again:
205	v = (caddr_t)firstaddr;
206
207#define	valloc(name, type, num) \
208	    (name) = (type *)v; v = (caddr_t)((name)+(num))
209#define	valloclim(name, type, num, lim) \
210	    (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
211	valloc(callout, struct callout, ncallout);
212#ifdef SYSVSHM
213	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
214#endif
215#ifdef SYSVSEM
216	valloc(sema, struct semid_ds, seminfo.semmni);
217	valloc(sem, struct sem, seminfo.semmns);
218	/* This is pretty disgusting! */
219	valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
220#endif
221#ifdef SYSVMSG
222	valloc(msgpool, char, msginfo.msgmax);
223	valloc(msgmaps, struct msgmap, msginfo.msgseg);
224	valloc(msghdrs, struct msg, msginfo.msgtql);
225	valloc(msqids, struct msqid_ds, msginfo.msgmni);
226#endif
227	/*
228	 * Determine how many buffers to allocate.
229	 * Use 20% of memory of memory beyond the first 2MB
230	 * Insure a minimum of 16 fs buffers.
231	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
232	 */
233	if (bufpages == 0)
234		bufpages = ((physmem << PGSHIFT) - 2048*1024) / NBPG / 5;
235	if (bufpages < 64)
236		bufpages = 64;
237
238	/*
239	 * We must still limit the maximum number of buffers to be no
240	 * more than 2/5's of the size of the kernal malloc region, this
241	 * will only take effect for machines with lots of memory
242	 */
243	bufpages = min(bufpages, (VM_KMEM_SIZE / NBPG) * 2 / 5);
244	if (nbuf == 0) {
245		nbuf = bufpages / 2;
246		if (nbuf < 32)
247			nbuf = 32;
248	}
249	freebufspace = bufpages * NBPG;
250	if (nswbuf == 0) {
251		nswbuf = (nbuf / 2) &~ 1;	/* force even */
252		if (nswbuf > 64)
253			nswbuf = 64;		/* sanity */
254	}
255	valloc(swbuf, struct buf, nswbuf);
256	valloc(buf, struct buf, nbuf);
257
258#ifndef NOBOUNCE
259	/*
260	 * If there is more than 16MB of memory, allocate some bounce buffers
261	 */
262	if (Maxmem > 4096) {
263		if (bouncepages == 0)
264			bouncepages = 96;	/* largest physio size + extra */
265		v = (caddr_t)((vm_offset_t)((vm_offset_t)v + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
266		valloc(bouncememory, char, bouncepages * PAGE_SIZE);
267	}
268#endif
269
270	/*
271	 * End of first pass, size has been calculated so allocate memory
272	 */
273	if (firstaddr == 0) {
274		size = (vm_size_t)(v - firstaddr);
275		firstaddr = (int)kmem_alloc(kernel_map, round_page(size));
276		if (firstaddr == 0)
277			panic("startup: no room for tables");
278		goto again;
279	}
280
281	/*
282	 * End of second pass, addresses have been assigned
283	 */
284	if ((vm_size_t)(v - firstaddr) != size)
285		panic("startup: table size inconsistency");
286
287	clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva,
288			(nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) +
289				maxbkva + pager_map_size, TRUE);
290	buffer_map = kmem_suballoc(clean_map, &buffer_sva, &buffer_eva,
291				(nbuf*MAXBSIZE), TRUE);
292	pager_map = kmem_suballoc(clean_map, &pager_sva, &pager_eva,
293				(nswbuf*MAXPHYS) + pager_map_size, TRUE);
294	io_map = kmem_suballoc(clean_map, &minaddr, &maxaddr, maxbkva, FALSE);
295
296#if 0
297	/*
298	 * Allocate a submap for physio
299	 */
300	phys_map = kmem_suballoc(clean_map, &minaddr, &maxaddr,
301				 VM_PHYS_SIZE, TRUE);
302#endif
303
304	/*
305	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
306	 * we use the more space efficient malloc in place of kmem_alloc.
307	 */
308	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
309				   M_MBUF, M_NOWAIT);
310	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
311	mb_map = kmem_suballoc(kmem_map, (vm_offset_t *)&mbutl, &maxaddr,
312			       VM_MBUF_SIZE, FALSE);
313	/*
314	 * Initialize callouts
315	 */
316	callfree = callout;
317	for (i = 1; i < ncallout; i++)
318		callout[i-1].c_next = &callout[i];
319
320	printf("avail memory = %d (%d pages)\n", ptoa(cnt.v_free_count), cnt.v_free_count);
321	printf("using %d buffers containing %d bytes of memory\n",
322		nbuf, bufpages * CLBYTES);
323
324#ifndef NOBOUNCE
325	/*
326	 * init bounce buffers
327	 */
328	vm_bounce_init();
329#endif
330
331	/*
332	 * Set up CPU-specific registers, cache, etc.
333	 */
334	initcpu();
335
336	/*
337	 * Set up buffers, so they can be used to read disk labels.
338	 */
339	bufinit();
340	vm_pager_bufferinit();
341
342	/*
343	 * Configure the system.
344	 */
345	configure();
346}
347
348
349struct cpu_nameclass i386_cpus[] = {
350	{ "Intel 80286",	CPUCLASS_286 },		/* CPU_286   */
351	{ "i386SX",		CPUCLASS_386 },		/* CPU_386SX */
352	{ "i386DX",		CPUCLASS_386 },		/* CPU_386   */
353	{ "i486SX",		CPUCLASS_486 },		/* CPU_486SX */
354	{ "i486DX",		CPUCLASS_486 },		/* CPU_486   */
355	{ "Pentium",		CPUCLASS_586 },		/* CPU_586   */
356};
357
358static void
359identifycpu()
360{
361	extern u_long cpu_id;
362	extern char cpu_vendor[];
363	printf("CPU: ");
364	if (cpu >= 0
365	    && cpu < (sizeof i386_cpus/sizeof(struct cpu_nameclass))) {
366		printf("%s", i386_cpus[cpu].cpu_name);
367		cpu_class = i386_cpus[cpu].cpu_class;
368		strncpy(cpu_model, i386_cpus[cpu].cpu_name, sizeof cpu_model);
369	} else {
370		printf("unknown cpu type %d\n", cpu);
371		panic("startup: bad cpu id");
372	}
373	printf(" (");
374	switch(cpu_class) {
375	case CPUCLASS_286:
376		printf("286");
377		break;
378	case CPUCLASS_386:
379		printf("386");
380		break;
381	case CPUCLASS_486:
382		printf("486");
383		break;
384	case CPUCLASS_586:
385		printf("Pentium");
386		break;
387	default:
388		printf("unknown");	/* will panic below... */
389	}
390	printf("-class CPU)");
391#ifdef I586_CPU
392	if(cpu_class == CPUCLASS_586) {
393		extern void calibrate_cyclecounter();
394		extern int pentium_mhz;
395		calibrate_cyclecounter();
396		printf(" %d MHz", pentium_mhz);
397	}
398#endif
399	if(cpu_id)
400		printf("  Id = 0x%x",cpu_id);
401	if(*cpu_vendor)
402		printf("  Origin = \"%s\"",cpu_vendor);
403	printf("\n");	/* cpu speed would be nice, but how? */
404
405	/*
406	 * Now that we have told the user what they have,
407	 * let them know if that machine type isn't configured.
408	 */
409	switch (cpu_class) {
410	case CPUCLASS_286:	/* a 286 should not make it this far, anyway */
411#if !defined(I386_CPU) && !defined(I486_CPU) && !defined(I586_CPU)
412#error This kernel is not configured for one of the supported CPUs
413#endif
414#if !defined(I386_CPU)
415	case CPUCLASS_386:
416#endif
417#if !defined(I486_CPU)
418	case CPUCLASS_486:
419#endif
420#if !defined(I586_CPU)
421	case CPUCLASS_586:
422#endif
423		panic("CPU class not configured");
424	default:
425		break;
426	}
427}
428
429#ifdef PGINPROF
430/*
431 * Return the difference (in microseconds)
432 * between the  current time and a previous
433 * time as represented  by the arguments.
434 * If there is a pending clock interrupt
435 * which has not been serviced due to high
436 * ipl, return error code.
437 */
438/*ARGSUSED*/
439vmtime(otime, olbolt, oicr)
440	register int otime, olbolt, oicr;
441{
442
443	return (((time.tv_sec-otime)*60 + lbolt-olbolt)*16667);
444}
445#endif
446
447extern int kstack[];
448
449/*
450 * Send an interrupt to process.
451 *
452 * Stack is set up to allow sigcode stored
453 * in u. to call routine, followed by kcall
454 * to sigreturn routine below.  After sigreturn
455 * resets the signal mask, the stack, and the
456 * frame pointer, it returns to the user
457 * specified pc, psl.
458 */
459void
460sendsig(catcher, sig, mask, code)
461	sig_t catcher;
462	int sig, mask;
463	unsigned code;
464{
465	register struct proc *p = curproc;
466	register int *regs;
467	register struct sigframe *fp;
468	struct sigacts *psp = p->p_sigacts;
469	int oonstack, frmtrap;
470
471	regs = p->p_md.md_regs;
472        oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
473	/*
474	 * Allocate and validate space for the signal handler
475	 * context. Note that if the stack is in P0 space, the
476	 * call to grow() is a nop, and the useracc() check
477	 * will fail if the process has not already allocated
478	 * the space with a `brk'.
479	 */
480        if ((psp->ps_flags & SAS_ALTSTACK) &&
481	    (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
482	    (psp->ps_sigonstack & sigmask(sig))) {
483		fp = (struct sigframe *)(psp->ps_sigstk.ss_base +
484		    psp->ps_sigstk.ss_size - sizeof(struct sigframe));
485		psp->ps_sigstk.ss_flags |= SA_ONSTACK;
486	} else {
487		fp = (struct sigframe *)(regs[tESP]
488			- sizeof(struct sigframe));
489	}
490
491	/*
492	 * grow() will return FALSE if the fp will not fit inside the stack
493	 *	and the stack can not be grown. useracc will return FALSE
494	 *	if access is denied.
495	 */
496	if ((grow(p, (int)fp) == FALSE) ||
497	    (useracc((caddr_t)fp, sizeof (struct sigframe), B_WRITE) == FALSE)) {
498		/*
499		 * Process has trashed its stack; give it an illegal
500		 * instruction to halt it in its tracks.
501		 */
502		SIGACTION(p, SIGILL) = SIG_DFL;
503		sig = sigmask(SIGILL);
504		p->p_sigignore &= ~sig;
505		p->p_sigcatch &= ~sig;
506		p->p_sigmask &= ~sig;
507		psignal(p, SIGILL);
508		return;
509	}
510
511	/*
512	 * Build the argument list for the signal handler.
513	 */
514	fp->sf_signum = sig;
515	fp->sf_code = code;
516	fp->sf_scp = &fp->sf_sc;
517	fp->sf_addr = (char *) regs[tERR];
518	fp->sf_handler = catcher;
519
520	/* save scratch registers */
521	fp->sf_sc.sc_eax = regs[tEAX];
522	fp->sf_sc.sc_ebx = regs[tEBX];
523	fp->sf_sc.sc_ecx = regs[tECX];
524	fp->sf_sc.sc_edx = regs[tEDX];
525	fp->sf_sc.sc_esi = regs[tESI];
526	fp->sf_sc.sc_edi = regs[tEDI];
527	fp->sf_sc.sc_cs = regs[tCS];
528	fp->sf_sc.sc_ds = regs[tDS];
529	fp->sf_sc.sc_ss = regs[tSS];
530	fp->sf_sc.sc_es = regs[tES];
531	fp->sf_sc.sc_isp = regs[tISP];
532
533	/*
534	 * Build the signal context to be used by sigreturn.
535	 */
536	fp->sf_sc.sc_onstack = oonstack;
537	fp->sf_sc.sc_mask = mask;
538	fp->sf_sc.sc_sp = regs[tESP];
539	fp->sf_sc.sc_fp = regs[tEBP];
540	fp->sf_sc.sc_pc = regs[tEIP];
541	fp->sf_sc.sc_ps = regs[tEFLAGS];
542	regs[tESP] = (int)fp;
543	regs[tEIP] = (int)((struct pcb *)kstack)->pcb_sigc;
544	regs[tEFLAGS] &= ~PSL_VM;
545	regs[tCS] = _ucodesel;
546	regs[tDS] = _udatasel;
547	regs[tES] = _udatasel;
548	regs[tSS] = _udatasel;
549}
550
551/*
552 * System call to cleanup state after a signal
553 * has been taken.  Reset signal mask and
554 * stack state from context left by sendsig (above).
555 * Return to previous pc and psl as specified by
556 * context left by sendsig. Check carefully to
557 * make sure that the user has not modified the
558 * psl to gain improper privileges or to cause
559 * a machine fault.
560 */
561struct sigreturn_args {
562	struct sigcontext *sigcntxp;
563};
564
565int
566sigreturn(p, uap, retval)
567	struct proc *p;
568	struct sigreturn_args *uap;
569	int *retval;
570{
571	register struct sigcontext *scp;
572	register struct sigframe *fp;
573	register int *regs = p->p_md.md_regs;
574	int eflags;
575
576	/*
577	 * (XXX old comment) regs[tESP] points to the return address.
578	 * The user scp pointer is above that.
579	 * The return address is faked in the signal trampoline code
580	 * for consistency.
581	 */
582	scp = uap->sigcntxp;
583	fp = (struct sigframe *)
584	     ((caddr_t)scp - offsetof(struct sigframe, sf_sc));
585
586	if (useracc((caddr_t)fp, sizeof (*fp), 0) == 0)
587		return(EINVAL);
588
589	eflags = scp->sc_ps;
590	if ((eflags & PSL_USERCLR) != 0 ||
591	    (eflags & PSL_USERSET) != PSL_USERSET ||
592	    (eflags & PSL_IOPL) < (regs[tEFLAGS] & PSL_IOPL)) {
593#ifdef DEBUG
594    		printf("sigreturn:  eflags=0x%x\n", eflags);
595#endif
596    		return(EINVAL);
597	}
598
599	/*
600	 * Sanity check the user's selectors and error if they
601	 * are suspect.
602	 */
603#define max_ldt_sel(pcb) \
604	((pcb)->pcb_ldt ? (pcb)->pcb_ldt_len : (sizeof(ldt) / sizeof(ldt[0])))
605
606#define valid_ldt_sel(sel) \
607	(ISLDT(sel) && ISPL(sel) == SEL_UPL && \
608	 IDXSEL(sel) < max_ldt_sel(&p->p_addr->u_pcb))
609
610#define null_sel(sel) \
611	(!ISLDT(sel) && IDXSEL(sel) == 0)
612
613	if ((scp->sc_cs&0xffff != _ucodesel && !valid_ldt_sel(scp->sc_cs)) ||
614	    (scp->sc_ss&0xffff != _udatasel && !valid_ldt_sel(scp->sc_ss)) ||
615	    (scp->sc_ds&0xffff != _udatasel && !valid_ldt_sel(scp->sc_ds) &&
616	     !null_sel(scp->sc_ds)) ||
617	    (scp->sc_es&0xffff != _udatasel && !valid_ldt_sel(scp->sc_es) &&
618	     !null_sel(scp->sc_es))) {
619#ifdef DEBUG
620    		printf("sigreturn:  cs=0x%x ss=0x%x ds=0x%x es=0x%x\n",
621			scp->sc_cs, scp->sc_ss, scp->sc_ds, scp->sc_es);
622#endif
623		trapsignal(p, SIGBUS, T_PROTFLT);
624		return(EINVAL);
625	}
626
627#undef max_ldt_sel
628#undef valid_ldt_sel
629#undef null_sel
630
631	/* restore scratch registers */
632	regs[tEAX] = scp->sc_eax;
633	regs[tEBX] = scp->sc_ebx;
634	regs[tECX] = scp->sc_ecx;
635	regs[tEDX] = scp->sc_edx;
636	regs[tESI] = scp->sc_esi;
637	regs[tEDI] = scp->sc_edi;
638	regs[tCS] = scp->sc_cs;
639	regs[tDS] = scp->sc_ds;
640	regs[tES] = scp->sc_es;
641	regs[tSS] = scp->sc_ss;
642	regs[tISP] = scp->sc_isp;
643
644	if (useracc((caddr_t)scp, sizeof (*scp), 0) == 0)
645		return(EINVAL);
646
647	if (scp->sc_onstack & 01)
648		p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
649	else
650		p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
651	p->p_sigmask = scp->sc_mask &~
652	    (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
653	regs[tEBP] = scp->sc_fp;
654	regs[tESP] = scp->sc_sp;
655	regs[tEIP] = scp->sc_pc;
656	regs[tEFLAGS] = eflags;
657	return(EJUSTRETURN);
658}
659
660/*
661 * a simple function to make the system panic (and dump a vmcore)
662 * in a predictable fashion
663 */
664void diediedie()
665{
666	panic("because you said to!");
667}
668
669int	waittime = -1;
670struct pcb dumppcb;
671
672void
673boot(arghowto)
674	int arghowto;
675{
676	register long dummy;		/* r12 is reserved */
677	register int howto;		/* r11 == how to boot */
678	register int devtype;		/* r10 == major of root dev */
679	extern int cold;
680	int nomsg = 1;
681
682	if (cold) {
683		printf("hit reset please");
684		for(;;);
685	}
686	howto = arghowto;
687	if ((howto&RB_NOSYNC) == 0 && waittime < 0) {
688		register struct buf *bp;
689		int iter, nbusy;
690
691		waittime = 0;
692		(void) splnet();
693		printf("syncing disks... ");
694		/*
695		 * Release inodes held by texts before update.
696		 */
697		if (panicstr == 0)
698			vnode_pager_umount(NULL);
699		sync(curproc, NULL, NULL);
700		/*
701		 * Unmount filesystems
702		 */
703#if 0
704		if (panicstr == 0)
705			vfs_unmountall();
706#endif
707
708		for (iter = 0; iter < 20; iter++) {
709			nbusy = 0;
710			for (bp = &buf[nbuf]; --bp >= buf; )
711				if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
712					nbusy++;
713			if (nbusy == 0)
714				break;
715			if (nomsg) {
716				printf("updating disks before rebooting... ");
717				nomsg = 0;
718			}
719			printf("%d ", nbusy);
720			DELAY(40000 * iter);
721		}
722		if (nbusy)
723			printf("giving up\n");
724		else
725			printf("done\n");
726		DELAY(10000);			/* wait for printf to finish */
727	}
728	splhigh();
729	devtype = major(rootdev);
730	if (howto&RB_HALT) {
731		printf("\n");
732		printf("The operating system has halted.\n");
733		printf("Please press any key to reboot.\n\n");
734		cngetc();
735	} else {
736		if (howto & RB_DUMP) {
737			savectx(&dumppcb, 0);
738			dumppcb.pcb_ptd = rcr3();
739			dumpsys();
740
741			if (PANIC_REBOOT_WAIT_TIME != 0) {
742				if (PANIC_REBOOT_WAIT_TIME != -1) {
743					int loop;
744					printf("Automatic reboot in %d seconds - press a key on the console to abort\n",
745						PANIC_REBOOT_WAIT_TIME);
746					for (loop = PANIC_REBOOT_WAIT_TIME; loop > 0; --loop) {
747						DELAY(1000 * 1000); /* one second */
748						if (sgetc(1)) /* Did user type a key? */
749							break;
750					}
751					if (!loop)
752						goto die;
753				}
754			} else { /* zero time specified - reboot NOW */
755				goto die;
756			}
757			printf("--> Press a key on the console to reboot <--\n");
758			cngetc();
759		}
760	}
761#ifdef lint
762	dummy = 0; dummy = dummy;
763	printf("howto %d, devtype %d\n", arghowto, devtype);
764#endif
765die:
766	printf("Rebooting...\n");
767	DELAY(1000000);	/* wait 1 sec for printf's to complete and be read */
768	cpu_reset();
769	for(;;) ;
770	/* NOTREACHED */
771}
772
773unsigned long	dumpmag = 0x8fca0101UL;	/* magic number for savecore */
774int		dumpsize = 0;		/* also for savecore */
775/*
776 * Doadump comes here after turning off memory management and
777 * getting on the dump stack, either when called above, or by
778 * the auto-restart code.
779 */
780void
781dumpsys()
782{
783
784	if (dumpdev == NODEV)
785		return;
786	if ((minor(dumpdev)&07) != 1)
787		return;
788	dumpsize = Maxmem;
789	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
790	printf("dump ");
791	switch ((*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
792
793	case ENXIO:
794		printf("device bad\n");
795		break;
796
797	case EFAULT:
798		printf("device not ready\n");
799		break;
800
801	case EINVAL:
802		printf("area improper\n");
803		break;
804
805	case EIO:
806		printf("i/o error\n");
807		break;
808
809	case EINTR:
810		printf("aborted from console\n");
811		break;
812
813	default:
814		printf("succeeded\n");
815		break;
816	}
817}
818
819#ifdef HZ
820/*
821 * If HZ is defined we use this code, otherwise the code in
822 * /sys/i386/i386/microtime.s is used.  The othercode only works
823 * for HZ=100.
824 */
825microtime(tvp)
826	register struct timeval *tvp;
827{
828	int s = splhigh();
829
830	*tvp = time;
831	tvp->tv_usec += tick;
832	while (tvp->tv_usec > 1000000) {
833		tvp->tv_sec++;
834		tvp->tv_usec -= 1000000;
835	}
836	splx(s);
837}
838#endif /* HZ */
839
840static void
841initcpu()
842{
843}
844
845/*
846 * Clear registers on exec
847 */
848void
849setregs(p, entry, stack)
850	struct proc *p;
851	u_long entry;
852	u_long stack;
853{
854	p->p_md.md_regs[tEBP] = 0;	/* bottom of the fp chain */
855	p->p_md.md_regs[tEIP] = entry;
856	p->p_md.md_regs[tESP] = stack;
857	p->p_md.md_regs[tSS] = _udatasel;
858	p->p_md.md_regs[tDS] = _udatasel;
859	p->p_md.md_regs[tES] = _udatasel;
860	p->p_md.md_regs[tCS] = _ucodesel;
861
862	p->p_addr->u_pcb.pcb_flags = 0;	/* no fp at all */
863	load_cr0(rcr0() | CR0_TS);	/* start emulating */
864#if	NNPX > 0
865	npxinit(__INITIAL_NPXCW__);
866#endif	/* NNPX > 0 */
867}
868
869/*
870 * machine dependent system variables.
871 */
872int
873cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
874	int *name;
875	u_int namelen;
876	void *oldp;
877	size_t *oldlenp;
878	void *newp;
879	size_t newlen;
880	struct proc *p;
881{
882
883	/* all sysctl names at this level are terminal */
884	if (namelen != 1)
885		return (ENOTDIR);               /* overloaded */
886
887	switch (name[0]) {
888	case CPU_CONSDEV:
889		return (sysctl_rdstruct(oldp, oldlenp, newp, &cn_tty->t_dev,
890		   sizeof cn_tty->t_dev));
891	default:
892		return (EOPNOTSUPP);
893	}
894	/* NOTREACHED */
895}
896
897/*
898 * Initialize 386 and configure to run kernel
899 */
900
901/*
902 * Initialize segments & interrupt table
903 */
904
905union descriptor gdt[NGDT];
906union descriptor ldt[NLDT];		/* local descriptor table */
907struct gate_descriptor idt[NIDT];	/* interrupt descriptor table */
908
909int _default_ldt, currentldt;
910
911struct	i386tss	tss, panic_tss;
912
913extern  struct user *proc0paddr;
914
915/* software prototypes -- in more palatable form */
916struct soft_segment_descriptor gdt_segs[] = {
917	/* Null Descriptor */
918{	0x0,			/* segment base address  */
919	0x0,			/* length */
920	0,			/* segment type */
921	0,			/* segment descriptor priority level */
922	0,			/* segment descriptor present */
923	0, 0,
924	0,			/* default 32 vs 16 bit size */
925	0  			/* limit granularity (byte/page units)*/ },
926	/* Code Descriptor for kernel */
927{	0x0,			/* segment base address  */
928	0xfffff,		/* length - all address space */
929	SDT_MEMERA,		/* segment type */
930	0,			/* segment descriptor priority level */
931	1,			/* segment descriptor present */
932	0, 0,
933	1,			/* default 32 vs 16 bit size */
934	1  			/* limit granularity (byte/page units)*/ },
935	/* Data Descriptor for kernel */
936{	0x0,			/* segment base address  */
937	0xfffff,		/* length - all address space */
938	SDT_MEMRWA,		/* segment type */
939	0,			/* segment descriptor priority level */
940	1,			/* segment descriptor present */
941	0, 0,
942	1,			/* default 32 vs 16 bit size */
943	1  			/* limit granularity (byte/page units)*/ },
944	/* LDT Descriptor */
945{	(int) ldt,			/* segment base address  */
946	sizeof(ldt)-1,		/* length - all address space */
947	SDT_SYSLDT,		/* segment type */
948	0,			/* segment descriptor priority level */
949	1,			/* segment descriptor present */
950	0, 0,
951	0,			/* unused - default 32 vs 16 bit size */
952	0  			/* limit granularity (byte/page units)*/ },
953	/* Null Descriptor - Placeholder */
954{	0x0,			/* segment base address  */
955	0x0,			/* length - all address space */
956	0,			/* segment type */
957	0,			/* segment descriptor priority level */
958	0,			/* segment descriptor present */
959	0, 0,
960	0,			/* default 32 vs 16 bit size */
961	0  			/* limit granularity (byte/page units)*/ },
962	/* Panic Tss Descriptor */
963{	(int) &panic_tss,		/* segment base address  */
964	sizeof(tss)-1,		/* length - all address space */
965	SDT_SYS386TSS,		/* segment type */
966	0,			/* segment descriptor priority level */
967	1,			/* segment descriptor present */
968	0, 0,
969	0,			/* unused - default 32 vs 16 bit size */
970	0  			/* limit granularity (byte/page units)*/ },
971	/* Proc 0 Tss Descriptor */
972{	(int) kstack,			/* segment base address  */
973	sizeof(tss)-1,		/* length - all address space */
974	SDT_SYS386TSS,		/* segment type */
975	0,			/* segment descriptor priority level */
976	1,			/* segment descriptor present */
977	0, 0,
978	0,			/* unused - default 32 vs 16 bit size */
979	0  			/* limit granularity (byte/page units)*/ },
980	/* User LDT Descriptor per process */
981{	(int) ldt,			/* segment base address  */
982	(512 * sizeof(union descriptor)-1),		/* length */
983	SDT_SYSLDT,		/* segment type */
984	0,			/* segment descriptor priority level */
985	1,			/* segment descriptor present */
986	0, 0,
987	0,			/* unused - default 32 vs 16 bit size */
988	0  			/* limit granularity (byte/page units)*/ },
989};
990
991struct soft_segment_descriptor ldt_segs[] = {
992	/* Null Descriptor - overwritten by call gate */
993{	0x0,			/* segment base address  */
994	0x0,			/* length - all address space */
995	0,			/* segment type */
996	0,			/* segment descriptor priority level */
997	0,			/* segment descriptor present */
998	0, 0,
999	0,			/* default 32 vs 16 bit size */
1000	0  			/* limit granularity (byte/page units)*/ },
1001	/* Null Descriptor - overwritten by call gate */
1002{	0x0,			/* segment base address  */
1003	0x0,			/* length - all address space */
1004	0,			/* segment type */
1005	0,			/* segment descriptor priority level */
1006	0,			/* segment descriptor present */
1007	0, 0,
1008	0,			/* default 32 vs 16 bit size */
1009	0  			/* limit granularity (byte/page units)*/ },
1010	/* Null Descriptor - overwritten by call gate */
1011{	0x0,			/* segment base address  */
1012	0x0,			/* length - all address space */
1013	0,			/* segment type */
1014	0,			/* segment descriptor priority level */
1015	0,			/* segment descriptor present */
1016	0, 0,
1017	0,			/* default 32 vs 16 bit size */
1018	0  			/* limit granularity (byte/page units)*/ },
1019	/* Code Descriptor for user */
1020{	0x0,			/* segment base address  */
1021	0xfffff,		/* length - all address space */
1022	SDT_MEMERA,		/* segment type */
1023	SEL_UPL,		/* segment descriptor priority level */
1024	1,			/* segment descriptor present */
1025	0, 0,
1026	1,			/* default 32 vs 16 bit size */
1027	1  			/* limit granularity (byte/page units)*/ },
1028	/* Data Descriptor for user */
1029{	0x0,			/* segment base address  */
1030	0xfffff,		/* length - all address space */
1031	SDT_MEMRWA,		/* segment type */
1032	SEL_UPL,		/* segment descriptor priority level */
1033	1,			/* segment descriptor present */
1034	0, 0,
1035	1,			/* default 32 vs 16 bit size */
1036	1  			/* limit granularity (byte/page units)*/ } };
1037
1038void
1039setidt(idx, func, typ, dpl)
1040	int idx;
1041	void (*func)();
1042	int typ;
1043	int dpl;
1044{
1045	struct gate_descriptor *ip = idt + idx;
1046
1047	ip->gd_looffset = (int)func;
1048	ip->gd_selector = 8;
1049	ip->gd_stkcpy = 0;
1050	ip->gd_xx = 0;
1051	ip->gd_type = typ;
1052	ip->gd_dpl = dpl;
1053	ip->gd_p = 1;
1054	ip->gd_hioffset = ((int)func)>>16 ;
1055}
1056
1057#define	IDTVEC(name)	__CONCAT(X,name)
1058typedef void idtvec_t();
1059
1060extern idtvec_t
1061	IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
1062	IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
1063	IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
1064	IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(rsvd0),
1065	IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4),
1066	IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8),
1067	IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12),
1068	IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(syscall);
1069
1070int _gsel_tss;
1071
1072void
1073init386(first)
1074	int first;
1075{
1076	extern ssdtosd(), lgdt(), lidt(), lldt(), etext;
1077	int x, *pi;
1078	unsigned biosbasemem, biosextmem;
1079	struct gate_descriptor *gdp;
1080	extern int sigcode,szsigcode;
1081	/* table descriptors - used to load tables by microp */
1082	struct region_descriptor r_gdt, r_idt;
1083	int	pagesinbase, pagesinext;
1084	int	target_page;
1085	extern struct pte *CMAP1;
1086	extern caddr_t CADDR1;
1087
1088	proc0.p_addr = proc0paddr;
1089
1090	/*
1091	 * Initialize the console before we print anything out.
1092	 */
1093
1094	cninit ();
1095
1096	/*
1097	 * make gdt memory segments, the code segment goes up to end of the
1098	 * page with etext in it, the data segment goes to the end of
1099	 * the address space
1100	 */
1101	gdt_segs[GCODE_SEL].ssd_limit = i386_btop(i386_round_page(&etext)) - 1;
1102	gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1;
1103	for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
1104
1105	/* make ldt memory segments */
1106	/*
1107	 * The data segment limit must not cover the user area because we
1108	 * don't want the user area to be writable in copyout() etc. (page
1109	 * level protection is lost in kernel mode on 386's).  Also, we
1110	 * don't want the user area to be writable directly (page level
1111	 * protection of the user area is not available on 486's with
1112	 * CR0_WP set, because there is no user-read/kernel-write mode).
1113	 *
1114	 * XXX - VM_MAXUSER_ADDRESS is an end address, not a max.  And it
1115	 * should be spelled ...MAX_USER...
1116	 */
1117#define VM_END_USER_RW_ADDRESS	VM_MAXUSER_ADDRESS
1118	/*
1119	 * The code segment limit has to cover the user area until we move
1120	 * the signal trampoline out of the user area.  This is safe because
1121	 * the code segment cannot be written to directly.
1122	 */
1123#define VM_END_USER_R_ADDRESS	(VM_END_USER_RW_ADDRESS + UPAGES * NBPG)
1124	ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1;
1125	ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1;
1126	/* Note. eventually want private ldts per process */
1127	for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
1128
1129	/* exceptions */
1130	setidt(0, &IDTVEC(div),  SDT_SYS386TGT, SEL_KPL);
1131	setidt(1, &IDTVEC(dbg),  SDT_SYS386TGT, SEL_KPL);
1132	setidt(2, &IDTVEC(nmi),  SDT_SYS386TGT, SEL_KPL);
1133 	setidt(3, &IDTVEC(bpt),  SDT_SYS386TGT, SEL_UPL);
1134	setidt(4, &IDTVEC(ofl),  SDT_SYS386TGT, SEL_UPL);
1135	setidt(5, &IDTVEC(bnd),  SDT_SYS386TGT, SEL_KPL);
1136	setidt(6, &IDTVEC(ill),  SDT_SYS386TGT, SEL_KPL);
1137	setidt(7, &IDTVEC(dna),  SDT_SYS386TGT, SEL_KPL);
1138	setidt(8, &IDTVEC(dble),  SDT_SYS386TGT, SEL_KPL);
1139	setidt(9, &IDTVEC(fpusegm),  SDT_SYS386TGT, SEL_KPL);
1140	setidt(10, &IDTVEC(tss),  SDT_SYS386TGT, SEL_KPL);
1141	setidt(11, &IDTVEC(missing),  SDT_SYS386TGT, SEL_KPL);
1142	setidt(12, &IDTVEC(stk),  SDT_SYS386TGT, SEL_KPL);
1143	setidt(13, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL);
1144	setidt(14, &IDTVEC(page),  SDT_SYS386TGT, SEL_KPL);
1145	setidt(15, &IDTVEC(rsvd),  SDT_SYS386TGT, SEL_KPL);
1146	setidt(16, &IDTVEC(fpu),  SDT_SYS386TGT, SEL_KPL);
1147	setidt(17, &IDTVEC(rsvd0),  SDT_SYS386TGT, SEL_KPL);
1148	setidt(18, &IDTVEC(rsvd1),  SDT_SYS386TGT, SEL_KPL);
1149	setidt(19, &IDTVEC(rsvd2),  SDT_SYS386TGT, SEL_KPL);
1150	setidt(20, &IDTVEC(rsvd3),  SDT_SYS386TGT, SEL_KPL);
1151	setidt(21, &IDTVEC(rsvd4),  SDT_SYS386TGT, SEL_KPL);
1152	setidt(22, &IDTVEC(rsvd5),  SDT_SYS386TGT, SEL_KPL);
1153	setidt(23, &IDTVEC(rsvd6),  SDT_SYS386TGT, SEL_KPL);
1154	setidt(24, &IDTVEC(rsvd7),  SDT_SYS386TGT, SEL_KPL);
1155	setidt(25, &IDTVEC(rsvd8),  SDT_SYS386TGT, SEL_KPL);
1156	setidt(26, &IDTVEC(rsvd9),  SDT_SYS386TGT, SEL_KPL);
1157	setidt(27, &IDTVEC(rsvd10),  SDT_SYS386TGT, SEL_KPL);
1158	setidt(28, &IDTVEC(rsvd11),  SDT_SYS386TGT, SEL_KPL);
1159	setidt(29, &IDTVEC(rsvd12),  SDT_SYS386TGT, SEL_KPL);
1160	setidt(30, &IDTVEC(rsvd13),  SDT_SYS386TGT, SEL_KPL);
1161	setidt(31, &IDTVEC(rsvd14),  SDT_SYS386TGT, SEL_KPL);
1162
1163#include	"isa.h"
1164#if	NISA >0
1165	isa_defaultirq();
1166#endif
1167
1168	r_gdt.rd_limit = sizeof(gdt) - 1;
1169	r_gdt.rd_base =  (int) gdt;
1170	lgdt(&r_gdt);
1171
1172	r_idt.rd_limit = sizeof(idt) - 1;
1173	r_idt.rd_base = (int) idt;
1174	lidt(&r_idt);
1175
1176	_default_ldt = GSEL(GLDT_SEL, SEL_KPL);
1177	lldt(_default_ldt);
1178	currentldt = _default_ldt;
1179
1180#include "ddb.h"
1181#if NDDB > 0
1182	kdb_init();
1183	if (boothowto & RB_KDB)
1184		Debugger("Boot flags requested debugger");
1185#endif
1186
1187	/* Use BIOS values stored in RTC CMOS RAM, since probing
1188	 * breaks certain 386 AT relics.
1189	 */
1190	biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8);
1191	biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8);
1192
1193	/*
1194	 * If BIOS tells us that it has more than 640k in the basemem,
1195	 *	don't believe it - set it to 640k.
1196	 */
1197	if (biosbasemem > 640)
1198		biosbasemem = 640;
1199
1200	/*
1201	 * Some 386 machines might give us a bogus number for extended
1202	 *	mem. If this happens, stop now.
1203	 */
1204#ifndef LARGEMEM
1205	if (biosextmem > 65536) {
1206		panic("extended memory beyond limit of 64MB");
1207		/* NOTREACHED */
1208	}
1209#endif
1210
1211	pagesinbase = biosbasemem * 1024 / NBPG;
1212	pagesinext = biosextmem * 1024 / NBPG;
1213
1214	/*
1215	 * Special hack for chipsets that still remap the 384k hole when
1216	 *	there's 16MB of memory - this really confuses people that
1217	 *	are trying to use bus mastering ISA controllers with the
1218	 *	"16MB limit"; they only have 16MB, but the remapping puts
1219	 *	them beyond the limit.
1220	 * XXX - this should be removed when bounce buffers are
1221	 *	implemented.
1222	 */
1223	/*
1224	 * If extended memory is between 15-16MB (16-17MB phys address range),
1225	 *	chop it to 15MB.
1226	 */
1227	if ((pagesinext > 3840) && (pagesinext < 4096))
1228		pagesinext = 3840;
1229
1230	/*
1231	 * Maxmem isn't the "maximum memory", it's the highest page of
1232	 * of the physical address space. It should be "Maxphyspage".
1233	 */
1234	Maxmem = pagesinext + 0x100000/PAGE_SIZE;
1235
1236#ifdef MAXMEM
1237	if (MAXMEM/4 < Maxmem)
1238		Maxmem = MAXMEM/4;
1239#endif
1240	/*
1241	 * Calculate number of physical pages, but account for Maxmem
1242	 *	limitation above.
1243	 */
1244	physmem = pagesinbase +
1245	    (min(pagesinext + 0x100000/PAGE_SIZE, Maxmem) - 0x100000/PAGE_SIZE);
1246
1247	/* call pmap initialization to make new kernel address space */
1248	pmap_bootstrap (first, 0);
1249
1250	/*
1251	 * Do simple memory test over range of extended memory that BIOS
1252	 *	indicates exists. Adjust Maxmem to the highest page of
1253	 *	good memory.
1254	 */
1255	printf("Testing memory (%dMB)...", ptoa(Maxmem)/1024/1024);
1256
1257	for (target_page = Maxmem - 1; target_page >= atop(first); target_page--) {
1258
1259		/*
1260		 * map page into kernel: valid, read/write, non-cacheable
1261		 */
1262		*(int *)CMAP1 = PG_V | PG_KW | PG_N | ptoa(target_page);
1263		tlbflush();
1264
1265		/*
1266		 * Test for alternating 1's and 0's
1267		 */
1268		filli(0xaaaaaaaa, CADDR1, PAGE_SIZE/sizeof(int));
1269		if (test_page((int *)CADDR1, 0xaaaaaaaa)) {
1270			Maxmem = target_page;
1271			badpages++;
1272			continue;
1273		}
1274		/*
1275		 * Test for alternating 0's and 1's
1276		 */
1277		filli(0x55555555, CADDR1, PAGE_SIZE/sizeof(int));
1278		if (test_page((int *)CADDR1, 0x55555555)) {
1279			Maxmem = target_page;
1280			badpages++;
1281			continue;
1282		}
1283		/*
1284		 * Test for all 1's
1285		 */
1286		filli(0xffffffff, CADDR1, PAGE_SIZE/sizeof(int));
1287		if (test_page((int *)CADDR1, 0xffffffff)) {
1288			Maxmem = target_page;
1289			badpages++;
1290			continue;
1291		}
1292		/*
1293		 * Test zeroing of page
1294		 */
1295		bzero(CADDR1, PAGE_SIZE);
1296		if (test_page((int *)CADDR1, 0)) {
1297			/*
1298			 * test of page failed
1299			 */
1300			Maxmem = target_page;
1301			badpages++;
1302			continue;
1303		}
1304	}
1305	printf("done.\n");
1306
1307	*(int *)CMAP1 = 0;
1308	tlbflush();
1309
1310	avail_end = (Maxmem << PAGE_SHIFT)
1311		    - i386_round_page(sizeof(struct msgbuf));
1312
1313	/*
1314	 * Initialize pointers to the two chunks of memory; for use
1315	 *	later in vm_page_startup.
1316	 */
1317	/* avail_start is initialized in pmap_bootstrap */
1318	x = 0;
1319	if (pagesinbase > 1) {
1320		phys_avail[x++] = NBPG;		/* skip first page of memory */
1321		phys_avail[x++] = pagesinbase * NBPG;	/* memory up to the ISA hole */
1322	}
1323	phys_avail[x++] = avail_start;	/* memory up to the end */
1324	phys_avail[x++] = avail_end;
1325	phys_avail[x++] = 0;		/* no more chunks */
1326	phys_avail[x++] = 0;
1327
1328	/* now running on new page tables, configured,and u/iom is accessible */
1329
1330	/* make a initial tss so microp can get interrupt stack on syscall! */
1331	proc0.p_addr->u_pcb.pcb_tss.tss_esp0 = (int) kstack + UPAGES*NBPG;
1332	proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
1333	_gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
1334
1335	((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt =
1336		(sizeof(tss))<<16;
1337
1338	ltr(_gsel_tss);
1339
1340	/* make a call gate to reenter kernel with */
1341	gdp = &ldt[LSYS5CALLS_SEL].gd;
1342
1343	x = (int) &IDTVEC(syscall);
1344	gdp->gd_looffset = x++;
1345	gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
1346	gdp->gd_stkcpy = 1;
1347	gdp->gd_type = SDT_SYS386CGT;
1348	gdp->gd_dpl = SEL_UPL;
1349	gdp->gd_p = 1;
1350	gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16;
1351
1352	/* transfer to user mode */
1353
1354	_ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
1355	_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
1356
1357	/* setup proc 0's pcb */
1358	bcopy(&sigcode, proc0.p_addr->u_pcb.pcb_sigc, szsigcode);
1359	proc0.p_addr->u_pcb.pcb_flags = 0;
1360	proc0.p_addr->u_pcb.pcb_ptd = IdlePTD;
1361}
1362
1363int
1364test_page(address, pattern)
1365	int *address;
1366	int pattern;
1367{
1368	int *x;
1369
1370	for (x = address; x < (int *)((char *)address + PAGE_SIZE); x++) {
1371		if (*x != pattern)
1372			return (1);
1373	}
1374	return(0);
1375}
1376
1377/*
1378 * The registers are in the frame; the frame is in the user area of
1379 * the process in question; when the process is active, the registers
1380 * are in "the kernel stack"; when it's not, they're still there, but
1381 * things get flipped around.  So, since p->p_md.md_regs is the whole address
1382 * of the register set, take its offset from the kernel stack, and
1383 * index into the user block.  Don't you just *love* virtual memory?
1384 * (I'm starting to think seymour is right...)
1385 */
1386
1387int
1388ptrace_set_pc (struct proc *p, unsigned int addr) {
1389	void *regs = (char*)p->p_addr +
1390		((char*) p->p_md.md_regs - (char*) kstack);
1391
1392	((struct trapframe *)regs)->tf_eip = addr;
1393	return 0;
1394}
1395
1396int
1397ptrace_single_step (struct proc *p) {
1398	void *regs = (char*)p->p_addr +
1399		((char*) p->p_md.md_regs - (char*) kstack);
1400
1401	((struct trapframe *)regs)->tf_eflags |= PSL_T;
1402	return 0;
1403}
1404
1405/*
1406 * Copy the registers to user-space.
1407 */
1408
1409int
1410ptrace_getregs (struct proc *p, unsigned int *addr) {
1411	int error;
1412	struct reg regs = {0};
1413
1414	if (error = fill_regs (p, &regs))
1415		return error;
1416
1417	return copyout (&regs, addr, sizeof (regs));
1418}
1419
1420int
1421ptrace_setregs (struct proc *p, unsigned int *addr) {
1422	int error;
1423	struct reg regs = {0};
1424
1425	if (error = copyin (addr, &regs, sizeof(regs)))
1426		return error;
1427
1428	return set_regs (p, &regs);
1429}
1430
1431int
1432fill_regs(struct proc *p, struct reg *regs) {
1433	int error;
1434	struct trapframe *tp;
1435	void *ptr = (char*)p->p_addr +
1436		((char*) p->p_md.md_regs - (char*) kstack);
1437
1438	tp = ptr;
1439	regs->r_es = tp->tf_es;
1440	regs->r_ds = tp->tf_ds;
1441	regs->r_edi = tp->tf_edi;
1442	regs->r_esi = tp->tf_esi;
1443	regs->r_ebp = tp->tf_ebp;
1444	regs->r_ebx = tp->tf_ebx;
1445	regs->r_edx = tp->tf_edx;
1446	regs->r_ecx = tp->tf_ecx;
1447	regs->r_eax = tp->tf_eax;
1448	regs->r_eip = tp->tf_eip;
1449	regs->r_cs = tp->tf_cs;
1450	regs->r_eflags = tp->tf_eflags;
1451	regs->r_esp = tp->tf_esp;
1452	regs->r_ss = tp->tf_ss;
1453	return 0;
1454}
1455
1456int
1457set_regs (struct proc *p, struct reg *regs) {
1458	int error;
1459	struct trapframe *tp;
1460	void *ptr = (char*)p->p_addr +
1461		((char*) p->p_md.md_regs - (char*) kstack);
1462
1463	tp = ptr;
1464	tp->tf_es = regs->r_es;
1465	tp->tf_ds = regs->r_ds;
1466	tp->tf_edi = regs->r_edi;
1467	tp->tf_esi = regs->r_esi;
1468	tp->tf_ebp = regs->r_ebp;
1469	tp->tf_ebx = regs->r_ebx;
1470	tp->tf_edx = regs->r_edx;
1471	tp->tf_ecx = regs->r_ecx;
1472	tp->tf_eax = regs->r_eax;
1473	tp->tf_eip = regs->r_eip;
1474	tp->tf_cs = regs->r_cs;
1475	tp->tf_eflags = regs->r_eflags;
1476	tp->tf_esp = regs->r_esp;
1477	tp->tf_ss = regs->r_ss;
1478	return 0;
1479}
1480
1481#include "ddb.h"
1482#if NDDB <= 0
1483void
1484Debugger(const char *msg)
1485{
1486	printf("Debugger(\"%s\") called.\n", msg);
1487}
1488#endif /* no DDB */
1489
1490#include <sys/disklabel.h>
1491#define b_cylin	b_resid
1492#define dkpart(dev)              (minor(dev) & 7)
1493/*
1494 * Determine the size of the transfer, and make sure it is
1495 * within the boundaries of the partition. Adjust transfer
1496 * if needed, and signal errors or early completion.
1497 */
1498int
1499bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel)
1500{
1501        struct partition *p = lp->d_partitions + dkpart(bp->b_dev);
1502        int labelsect = lp->d_partitions[0].p_offset;
1503        int maxsz = p->p_size,
1504                sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
1505
1506        /* overwriting disk label ? */
1507        /* XXX should also protect bootstrap in first 8K */
1508        if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect &&
1509#if LABELSECTOR != 0
1510            bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect &&
1511#endif
1512            (bp->b_flags & B_READ) == 0 && wlabel == 0) {
1513                bp->b_error = EROFS;
1514                goto bad;
1515        }
1516
1517#if     defined(DOSBBSECTOR) && defined(notyet)
1518        /* overwriting master boot record? */
1519        if (bp->b_blkno + p->p_offset <= DOSBBSECTOR &&
1520            (bp->b_flags & B_READ) == 0 && wlabel == 0) {
1521                bp->b_error = EROFS;
1522                goto bad;
1523        }
1524#endif
1525
1526        /* beyond partition? */
1527        if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
1528                /* if exactly at end of disk, return an EOF */
1529                if (bp->b_blkno == maxsz) {
1530                        bp->b_resid = bp->b_bcount;
1531                        return(0);
1532                }
1533                /* or truncate if part of it fits */
1534                sz = maxsz - bp->b_blkno;
1535                if (sz <= 0) {
1536                        bp->b_error = EINVAL;
1537                        goto bad;
1538                }
1539                bp->b_bcount = sz << DEV_BSHIFT;
1540        }
1541
1542        /* calculate cylinder for disksort to order transfers with */
1543        bp->b_pblkno = bp->b_blkno + p->p_offset;
1544        bp->b_cylin = bp->b_pblkno / lp->d_secpercyl;
1545        return(1);
1546
1547bad:
1548        bp->b_flags |= B_ERROR;
1549        return(-1);
1550}
1551
1552