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