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