machdep.c revision 3907
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.80 1994/10/25 08:58:33 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/proc.h>
49#include <sys/user.h>
50#include <sys/buf.h>
51#include <sys/reboot.h>
52#include <sys/conf.h>
53#include <sys/file.h>
54#include <sys/callout.h>
55#include <sys/malloc.h>
56#include <sys/mbuf.h>
57#include <sys/msgbuf.h>
58#include <sys/ioctl.h>
59#include <sys/sysent.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 <sys/msg.h>
69#endif
70
71#ifdef SYSVSEM
72#include <sys/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
82#include <net/netisr.h>
83
84extern vm_offset_t avail_start, avail_end;
85
86#include <machine/cpu.h>
87#include <machine/reg.h>
88#include <machine/psl.h>
89#include <machine/specialreg.h>
90#include <machine/sysarch.h>
91#include <machine/cons.h>
92#include <machine/devconf.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, disable_rtc_set;	/* from	clock.c	*/
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 unsigned i;
164	register caddr_t v;
165	extern void (*netisrs[32])(void);
166	vm_offset_t maxaddr;
167	vm_size_t size = 0;
168	int firstaddr;
169#ifdef BOUNCE_BUFFERS
170	vm_offset_t minaddr;
171#endif /* BOUNCE_BUFFERS */
172
173	/*
174	 * Initialize error message buffer (at end of core).
175	 */
176
177	/* avail_end was pre-decremented in init_386() to compensate */
178	for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
179		pmap_enter(pmap_kernel(), (vm_offset_t)msgbufp,
180			   avail_end + i * NBPG,
181			   VM_PROT_ALL, TRUE);
182	msgbufmapped = 1;
183
184	/*
185	 * Good {morning,afternoon,evening,night}.
186	 */
187	printf(version);
188	startrtclock();
189	identifycpu();
190	printf("real memory  = %d (%d pages)\n", ptoa(physmem), physmem);
191	if (badpages)
192		printf("bad memory   = %d (%d pages)\n", ptoa(badpages), badpages);
193
194	/*
195	 * Quickly wire in netisrs.
196	 */
197#define DONET(isr, n) do { extern void isr(void); netisrs[n] = isr; } while(0)
198#ifdef INET
199#if NETHER > 0
200	DONET(arpintr, NETISR_ARP);
201#endif
202	DONET(ipintr, NETISR_IP);
203#endif
204#ifdef NS
205	DONET(nsintr, NETISR_NS);
206#endif
207#ifdef ISO
208	DONET(clnlintr, NETISR_ISO);
209#endif
210#ifdef CCITT
211	DONET(ccittintr, NETISR_CCITT);
212#endif
213#undef DONET
214
215	/*
216	 * Allocate space for system data structures.
217	 * The first available kernel virtual address is in "v".
218	 * As pages of kernel virtual memory are allocated, "v" is incremented.
219	 * As pages of memory are allocated and cleared,
220	 * "firstaddr" is incremented.
221	 * An index into the kernel page table corresponding to the
222	 * virtual memory address maintained in "v" is kept in "mapaddr".
223	 */
224
225	/*
226	 * Make two passes.  The first pass calculates how much memory is
227	 * needed and allocates it.  The second pass assigns virtual
228	 * addresses to the various data structures.
229	 */
230	firstaddr = 0;
231again:
232	v = (caddr_t)firstaddr;
233
234#define	valloc(name, type, num) \
235	    (name) = (type *)v; v = (caddr_t)((name)+(num))
236#define	valloclim(name, type, num, lim) \
237	    (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
238	valloc(callout, struct callout, ncallout);
239#ifdef SYSVSHM
240	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
241#endif
242#ifdef SYSVSEM
243	valloc(sema, struct semid_ds, seminfo.semmni);
244	valloc(sem, struct sem, seminfo.semmns);
245	/* This is pretty disgusting! */
246	valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
247#endif
248#ifdef SYSVMSG
249	valloc(msgpool, char, msginfo.msgmax);
250	valloc(msgmaps, struct msgmap, msginfo.msgseg);
251	valloc(msghdrs, struct msg, msginfo.msgtql);
252	valloc(msqids, struct msqid_ds, msginfo.msgmni);
253#endif
254	/*
255	 * Determine how many buffers to allocate.
256	 * Use 20% of memory of memory beyond the first 2MB
257	 * Insure a minimum of 16 fs buffers.
258	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
259	 */
260	if (bufpages == 0)
261		bufpages = ((physmem << PGSHIFT) - 2048*1024) / NBPG / 6;
262	if (bufpages < 64)
263		bufpages = 64;
264
265	/*
266	 * We must still limit the maximum number of buffers to be no
267	 * more than 750 because we'll run out of kernel VM otherwise.
268	 */
269	bufpages = min(bufpages, 1500);
270	if (nbuf == 0) {
271		nbuf = bufpages / 2;
272		if (nbuf < 32)
273			nbuf = 32;
274	}
275	freebufspace = bufpages * NBPG;
276	if (nswbuf == 0) {
277		nswbuf = (nbuf / 2) &~ 1;	/* force even */
278		if (nswbuf > 64)
279			nswbuf = 64;		/* sanity */
280	}
281	valloc(swbuf, struct buf, nswbuf);
282	valloc(buf, struct buf, nbuf);
283
284#ifdef BOUNCE_BUFFERS
285	/*
286	 * If there is more than 16MB of memory, allocate some bounce buffers
287	 */
288	if (Maxmem > 4096) {
289		if (bouncepages == 0)
290			bouncepages = 96;	/* largest physio size + extra */
291		v = (caddr_t)((vm_offset_t)((vm_offset_t)v + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
292		valloc(bouncememory, char, bouncepages * PAGE_SIZE);
293	}
294#endif
295
296	/*
297	 * End of first pass, size has been calculated so allocate memory
298	 */
299	if (firstaddr == 0) {
300		size = (vm_size_t)(v - firstaddr);
301		firstaddr = (int)kmem_alloc(kernel_map, round_page(size));
302		if (firstaddr == 0)
303			panic("startup: no room for tables");
304		goto again;
305	}
306
307	/*
308	 * End of second pass, addresses have been assigned
309	 */
310	if ((vm_size_t)(v - firstaddr) != size)
311		panic("startup: table size inconsistency");
312
313#ifdef BOUNCE_BUFFERS
314	clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva,
315			(nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) +
316				maxbkva + pager_map_size, TRUE);
317	io_map = kmem_suballoc(clean_map, &minaddr, &maxaddr, maxbkva, FALSE);
318#else
319	clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva,
320			(nbuf*MAXBSIZE) + (nswbuf*MAXPHYS) + pager_map_size, TRUE);
321#endif
322	buffer_map = kmem_suballoc(clean_map, &buffer_sva, &buffer_eva,
323				(nbuf*MAXBSIZE), TRUE);
324	pager_map = kmem_suballoc(clean_map, &pager_sva, &pager_eva,
325				(nswbuf*MAXPHYS) + pager_map_size, TRUE);
326
327	/*
328	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
329	 * we use the more space efficient malloc in place of kmem_alloc.
330	 */
331	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
332				   M_MBUF, M_NOWAIT);
333	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
334	mb_map = kmem_suballoc(kmem_map, (vm_offset_t *)&mbutl, &maxaddr,
335			       VM_MBUF_SIZE, FALSE);
336	/*
337	 * Initialize callouts
338	 */
339	callfree = callout;
340	for (i = 1; i < ncallout; i++)
341		callout[i-1].c_next = &callout[i];
342#ifdef USERCONFIG
343        if (boothowto & RB_CONFIG)
344		userconfig();
345#endif
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%lx",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;
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 (cncheckc()) /* 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 %lx, offset %ld\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	case CPU_DISRTCSET:
924		return (sysctl_int(oldp, oldlenp, newp,	newlen,	&disable_rtc_set));
925	default:
926		return (EOPNOTSUPP);
927	}
928	/* NOTREACHED */
929}
930
931/*
932 * Initialize 386 and configure to run kernel
933 */
934
935/*
936 * Initialize segments & interrupt table
937 */
938
939union descriptor gdt[NGDT];
940union descriptor ldt[NLDT];		/* local descriptor table */
941struct gate_descriptor idt[NIDT];	/* interrupt descriptor table */
942
943int _default_ldt, currentldt;
944
945struct	i386tss	tss, panic_tss;
946
947extern  struct user *proc0paddr;
948
949/* software prototypes -- in more palatable form */
950struct soft_segment_descriptor gdt_segs[] = {
951/* GNULL_SEL	0 Null Descriptor */
952{	0x0,			/* segment base address  */
953	0x0,			/* length */
954	0,			/* segment type */
955	0,			/* segment descriptor priority level */
956	0,			/* segment descriptor present */
957	0, 0,
958	0,			/* default 32 vs 16 bit size */
959	0  			/* limit granularity (byte/page units)*/ },
960/* GCODE_SEL	1 Code Descriptor for kernel */
961{	0x0,			/* segment base address  */
962	0xfffff,		/* length - all address space */
963	SDT_MEMERA,		/* segment type */
964	0,			/* segment descriptor priority level */
965	1,			/* segment descriptor present */
966	0, 0,
967	1,			/* default 32 vs 16 bit size */
968	1  			/* limit granularity (byte/page units)*/ },
969/* GDATA_SEL	2 Data Descriptor for kernel */
970{	0x0,			/* segment base address  */
971	0xfffff,		/* length - all address space */
972	SDT_MEMRWA,		/* segment type */
973	0,			/* segment descriptor priority level */
974	1,			/* segment descriptor present */
975	0, 0,
976	1,			/* default 32 vs 16 bit size */
977	1  			/* limit granularity (byte/page units)*/ },
978/* GLDT_SEL	3 LDT Descriptor */
979{	(int) ldt,		/* segment base address  */
980	sizeof(ldt)-1,		/* length - all address space */
981	SDT_SYSLDT,		/* segment type */
982	0,			/* segment descriptor priority level */
983	1,			/* segment descriptor present */
984	0, 0,
985	0,			/* unused - default 32 vs 16 bit size */
986	0  			/* limit granularity (byte/page units)*/ },
987/* GTGATE_SEL	4 Null Descriptor - Placeholder */
988{	0x0,			/* segment base address  */
989	0x0,			/* length - all address space */
990	0,			/* segment type */
991	0,			/* segment descriptor priority level */
992	0,			/* segment descriptor present */
993	0, 0,
994	0,			/* default 32 vs 16 bit size */
995	0  			/* limit granularity (byte/page units)*/ },
996/* GPANIC_SEL	5 Panic Tss Descriptor */
997{	(int) &panic_tss,	/* segment base address  */
998	sizeof(tss)-1,		/* length - all address space */
999	SDT_SYS386TSS,		/* segment type */
1000	0,			/* segment descriptor priority level */
1001	1,			/* segment descriptor present */
1002	0, 0,
1003	0,			/* unused - default 32 vs 16 bit size */
1004	0  			/* limit granularity (byte/page units)*/ },
1005/* GPROC0_SEL	6 Proc 0 Tss Descriptor */
1006{	(int) kstack,		/* segment base address  */
1007	sizeof(tss)-1,		/* length - all address space */
1008	SDT_SYS386TSS,		/* segment type */
1009	0,			/* segment descriptor priority level */
1010	1,			/* segment descriptor present */
1011	0, 0,
1012	0,			/* unused - default 32 vs 16 bit size */
1013	0  			/* limit granularity (byte/page units)*/ },
1014/* GUSERLDT_SEL	7 User LDT Descriptor per process */
1015{	(int) ldt,		/* segment base address  */
1016	(512 * sizeof(union descriptor)-1),		/* length */
1017	SDT_SYSLDT,		/* segment type */
1018	0,			/* segment descriptor priority level */
1019	1,			/* segment descriptor present */
1020	0, 0,
1021	0,			/* unused - default 32 vs 16 bit size */
1022	0  			/* limit granularity (byte/page units)*/ },
1023/* GAPMCODE32_SEL 8 APM BIOS 32-bit interface (32bit Code) */
1024{	0,			/* segment base address (overwritten by APM)  */
1025	0xfffff,		/* length */
1026	SDT_MEMERA,		/* segment type */
1027	0,			/* segment descriptor priority level */
1028	1,			/* segment descriptor present */
1029	0, 0,
1030	1,			/* default 32 vs 16 bit size */
1031	1  			/* limit granularity (byte/page units)*/ },
1032/* GAPMCODE16_SEL 9 APM BIOS 32-bit interface (16bit Code) */
1033{	0,			/* segment base address (overwritten by APM)  */
1034	0xfffff,		/* length */
1035	SDT_MEMERA,		/* segment type */
1036	0,			/* segment descriptor priority level */
1037	1,			/* segment descriptor present */
1038	0, 0,
1039	0,			/* default 32 vs 16 bit size */
1040	1  			/* limit granularity (byte/page units)*/ },
1041/* GAPMDATA_SEL	10 APM BIOS 32-bit interface (Data) */
1042{	0,			/* segment base address (overwritten by APM) */
1043	0xfffff,		/* length */
1044	SDT_MEMRWA,		/* segment type */
1045	0,			/* segment descriptor priority level */
1046	1,			/* segment descriptor present */
1047	0, 0,
1048	1,			/* default 32 vs 16 bit size */
1049	1  			/* limit granularity (byte/page units)*/ },
1050};
1051
1052struct soft_segment_descriptor ldt_segs[] = {
1053	/* Null Descriptor - overwritten by call gate */
1054{	0x0,			/* segment base address  */
1055	0x0,			/* length - all address space */
1056	0,			/* segment type */
1057	0,			/* segment descriptor priority level */
1058	0,			/* segment descriptor present */
1059	0, 0,
1060	0,			/* default 32 vs 16 bit size */
1061	0  			/* limit granularity (byte/page units)*/ },
1062	/* Null Descriptor - overwritten by call gate */
1063{	0x0,			/* segment base address  */
1064	0x0,			/* length - all address space */
1065	0,			/* segment type */
1066	0,			/* segment descriptor priority level */
1067	0,			/* segment descriptor present */
1068	0, 0,
1069	0,			/* default 32 vs 16 bit size */
1070	0  			/* limit granularity (byte/page units)*/ },
1071	/* Null Descriptor - overwritten by call gate */
1072{	0x0,			/* segment base address  */
1073	0x0,			/* length - all address space */
1074	0,			/* segment type */
1075	0,			/* segment descriptor priority level */
1076	0,			/* segment descriptor present */
1077	0, 0,
1078	0,			/* default 32 vs 16 bit size */
1079	0  			/* limit granularity (byte/page units)*/ },
1080	/* Code Descriptor for user */
1081{	0x0,			/* segment base address  */
1082	0xfffff,		/* length - all address space */
1083	SDT_MEMERA,		/* segment type */
1084	SEL_UPL,		/* segment descriptor priority level */
1085	1,			/* segment descriptor present */
1086	0, 0,
1087	1,			/* default 32 vs 16 bit size */
1088	1  			/* limit granularity (byte/page units)*/ },
1089	/* Data Descriptor for user */
1090{	0x0,			/* segment base address  */
1091	0xfffff,		/* length - all address space */
1092	SDT_MEMRWA,		/* segment type */
1093	SEL_UPL,		/* segment descriptor priority level */
1094	1,			/* segment descriptor present */
1095	0, 0,
1096	1,			/* default 32 vs 16 bit size */
1097	1  			/* limit granularity (byte/page units)*/ } };
1098
1099void
1100setidt(idx, func, typ, dpl)
1101	int idx;
1102	void (*func)();
1103	int typ;
1104	int dpl;
1105{
1106	struct gate_descriptor *ip = idt + idx;
1107
1108	ip->gd_looffset = (int)func;
1109	ip->gd_selector = 8;
1110	ip->gd_stkcpy = 0;
1111	ip->gd_xx = 0;
1112	ip->gd_type = typ;
1113	ip->gd_dpl = dpl;
1114	ip->gd_p = 1;
1115	ip->gd_hioffset = ((int)func)>>16 ;
1116}
1117
1118#define	IDTVEC(name)	__CONCAT(X,name)
1119typedef void idtvec_t();
1120
1121extern idtvec_t
1122	IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
1123	IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
1124	IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
1125	IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(rsvd0),
1126	IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4),
1127	IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8),
1128	IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12),
1129	IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(syscall);
1130
1131int _gsel_tss;
1132
1133/* added sdtossd() by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp> */
1134int
1135sdtossd(sd, ssd)
1136	struct segment_descriptor *sd;
1137	struct soft_segment_descriptor *ssd;
1138{
1139	ssd->ssd_base  = (sd->sd_hibase << 24) | sd->sd_lobase;
1140	ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit;
1141	ssd->ssd_type  = sd->sd_type;
1142	ssd->ssd_dpl   = sd->sd_dpl;
1143	ssd->ssd_p     = sd->sd_p;
1144	ssd->ssd_def32 = sd->sd_def32;
1145	ssd->ssd_gran  = sd->sd_gran;
1146	return 0;
1147}
1148
1149void
1150init386(first)
1151	int first;
1152{
1153	extern lgdt(), lidt(), lldt();
1154	int x;
1155	unsigned biosbasemem, biosextmem;
1156	struct gate_descriptor *gdp;
1157	extern int sigcode,szsigcode;
1158	/* table descriptors - used to load tables by microp */
1159	struct region_descriptor r_gdt, r_idt;
1160	int	pagesinbase, pagesinext;
1161	int	target_page;
1162	extern struct pte *CMAP1;
1163	extern caddr_t CADDR1;
1164
1165	proc0.p_addr = proc0paddr;
1166
1167	/*
1168	 * Initialize the console before we print anything out.
1169	 */
1170
1171	cninit ();
1172
1173	/*
1174	 * make gdt memory segments, the code segment goes up to end of the
1175	 * page with etext in it, the data segment goes to the end of
1176	 * the address space
1177	 */
1178	gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1 /* i386_btop(i386_round_page(&etext)) - 1 */;
1179	gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1;
1180	for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
1181
1182	/* make ldt memory segments */
1183	/*
1184	 * The data segment limit must not cover the user area because we
1185	 * don't want the user area to be writable in copyout() etc. (page
1186	 * level protection is lost in kernel mode on 386's).  Also, we
1187	 * don't want the user area to be writable directly (page level
1188	 * protection of the user area is not available on 486's with
1189	 * CR0_WP set, because there is no user-read/kernel-write mode).
1190	 *
1191	 * XXX - VM_MAXUSER_ADDRESS is an end address, not a max.  And it
1192	 * should be spelled ...MAX_USER...
1193	 */
1194#define VM_END_USER_RW_ADDRESS	VM_MAXUSER_ADDRESS
1195	/*
1196	 * The code segment limit has to cover the user area until we move
1197	 * the signal trampoline out of the user area.  This is safe because
1198	 * the code segment cannot be written to directly.
1199	 */
1200#define VM_END_USER_R_ADDRESS	(VM_END_USER_RW_ADDRESS + UPAGES * NBPG)
1201	ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1;
1202	ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1;
1203	/* Note. eventually want private ldts per process */
1204	for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
1205
1206	/* exceptions */
1207	setidt(0, &IDTVEC(div),  SDT_SYS386TGT, SEL_KPL);
1208	setidt(1, &IDTVEC(dbg),  SDT_SYS386TGT, SEL_KPL);
1209	setidt(2, &IDTVEC(nmi),  SDT_SYS386TGT, SEL_KPL);
1210 	setidt(3, &IDTVEC(bpt),  SDT_SYS386TGT, SEL_UPL);
1211	setidt(4, &IDTVEC(ofl),  SDT_SYS386TGT, SEL_UPL);
1212	setidt(5, &IDTVEC(bnd),  SDT_SYS386TGT, SEL_KPL);
1213	setidt(6, &IDTVEC(ill),  SDT_SYS386TGT, SEL_KPL);
1214	setidt(7, &IDTVEC(dna),  SDT_SYS386TGT, SEL_KPL);
1215	setidt(8, &IDTVEC(dble),  SDT_SYS386TGT, SEL_KPL);
1216	setidt(9, &IDTVEC(fpusegm),  SDT_SYS386TGT, SEL_KPL);
1217	setidt(10, &IDTVEC(tss),  SDT_SYS386TGT, SEL_KPL);
1218	setidt(11, &IDTVEC(missing),  SDT_SYS386TGT, SEL_KPL);
1219	setidt(12, &IDTVEC(stk),  SDT_SYS386TGT, SEL_KPL);
1220	setidt(13, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL);
1221	setidt(14, &IDTVEC(page),  SDT_SYS386TGT, SEL_KPL);
1222	setidt(15, &IDTVEC(rsvd),  SDT_SYS386TGT, SEL_KPL);
1223	setidt(16, &IDTVEC(fpu),  SDT_SYS386TGT, SEL_KPL);
1224	setidt(17, &IDTVEC(rsvd0),  SDT_SYS386TGT, SEL_KPL);
1225	setidt(18, &IDTVEC(rsvd1),  SDT_SYS386TGT, SEL_KPL);
1226	setidt(19, &IDTVEC(rsvd2),  SDT_SYS386TGT, SEL_KPL);
1227	setidt(20, &IDTVEC(rsvd3),  SDT_SYS386TGT, SEL_KPL);
1228	setidt(21, &IDTVEC(rsvd4),  SDT_SYS386TGT, SEL_KPL);
1229	setidt(22, &IDTVEC(rsvd5),  SDT_SYS386TGT, SEL_KPL);
1230	setidt(23, &IDTVEC(rsvd6),  SDT_SYS386TGT, SEL_KPL);
1231	setidt(24, &IDTVEC(rsvd7),  SDT_SYS386TGT, SEL_KPL);
1232	setidt(25, &IDTVEC(rsvd8),  SDT_SYS386TGT, SEL_KPL);
1233	setidt(26, &IDTVEC(rsvd9),  SDT_SYS386TGT, SEL_KPL);
1234	setidt(27, &IDTVEC(rsvd10),  SDT_SYS386TGT, SEL_KPL);
1235	setidt(28, &IDTVEC(rsvd11),  SDT_SYS386TGT, SEL_KPL);
1236	setidt(29, &IDTVEC(rsvd12),  SDT_SYS386TGT, SEL_KPL);
1237	setidt(30, &IDTVEC(rsvd13),  SDT_SYS386TGT, SEL_KPL);
1238	setidt(31, &IDTVEC(rsvd14),  SDT_SYS386TGT, SEL_KPL);
1239
1240#include	"isa.h"
1241#if	NISA >0
1242	isa_defaultirq();
1243#endif
1244
1245	r_gdt.rd_limit = sizeof(gdt) - 1;
1246	r_gdt.rd_base =  (int) gdt;
1247	lgdt(&r_gdt);
1248
1249	r_idt.rd_limit = sizeof(idt) - 1;
1250	r_idt.rd_base = (int) idt;
1251	lidt(&r_idt);
1252
1253	_default_ldt = GSEL(GLDT_SEL, SEL_KPL);
1254	lldt(_default_ldt);
1255	currentldt = _default_ldt;
1256
1257#ifdef DDB
1258	kdb_init();
1259	if (boothowto & RB_KDB)
1260		Debugger("Boot flags requested debugger");
1261#endif
1262
1263	/* Use BIOS values stored in RTC CMOS RAM, since probing
1264	 * breaks certain 386 AT relics.
1265	 */
1266	biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8);
1267	biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8);
1268
1269	/*
1270	 * If BIOS tells us that it has more than 640k in the basemem,
1271	 *	don't believe it - set it to 640k.
1272	 */
1273	if (biosbasemem > 640)
1274		biosbasemem = 640;
1275
1276	/*
1277	 * Some 386 machines might give us a bogus number for extended
1278	 *	mem. If this happens, stop now.
1279	 */
1280#ifndef LARGEMEM
1281	if (biosextmem > 65536) {
1282		panic("extended memory beyond limit of 64MB");
1283		/* NOTREACHED */
1284	}
1285#endif
1286
1287	pagesinbase = biosbasemem * 1024 / NBPG;
1288	pagesinext = biosextmem * 1024 / NBPG;
1289
1290	/*
1291	 * Special hack for chipsets that still remap the 384k hole when
1292	 *	there's 16MB of memory - this really confuses people that
1293	 *	are trying to use bus mastering ISA controllers with the
1294	 *	"16MB limit"; they only have 16MB, but the remapping puts
1295	 *	them beyond the limit.
1296	 * XXX - this should be removed when bounce buffers are
1297	 *	implemented.
1298	 */
1299	/*
1300	 * If extended memory is between 15-16MB (16-17MB phys address range),
1301	 *	chop it to 15MB.
1302	 */
1303	if ((pagesinext > 3840) && (pagesinext < 4096))
1304		pagesinext = 3840;
1305
1306	/*
1307	 * Maxmem isn't the "maximum memory", it's the highest page of
1308	 * of the physical address space. It should be "Maxphyspage".
1309	 */
1310	Maxmem = pagesinext + 0x100000/PAGE_SIZE;
1311
1312#ifdef MAXMEM
1313	if (MAXMEM/4 < Maxmem)
1314		Maxmem = MAXMEM/4;
1315#endif
1316	/*
1317	 * Calculate number of physical pages, but account for Maxmem
1318	 *	adjustment above.
1319	 */
1320	physmem = pagesinbase + Maxmem - 0x100000/PAGE_SIZE;
1321
1322	/* call pmap initialization to make new kernel address space */
1323	pmap_bootstrap (first, 0);
1324
1325	/*
1326	 * Do simple memory test over range of extended memory that BIOS
1327	 *	indicates exists. Adjust Maxmem to the highest page of
1328	 *	good memory.
1329	 */
1330	printf("Testing memory (%dMB)...", ptoa(Maxmem)/1024/1024);
1331
1332	for (target_page = Maxmem - 1; target_page >= atop(first); target_page--) {
1333
1334		/*
1335		 * map page into kernel: valid, read/write, non-cacheable
1336		 */
1337		*(int *)CMAP1 = PG_V | PG_KW | PG_N | ptoa(target_page);
1338		pmap_update();
1339
1340		/*
1341		 * Test for alternating 1's and 0's
1342		 */
1343		filli(0xaaaaaaaa, CADDR1, PAGE_SIZE/sizeof(int));
1344		if (test_page((int *)CADDR1, 0xaaaaaaaa)) {
1345			Maxmem = target_page;
1346			badpages++;
1347			continue;
1348		}
1349		/*
1350		 * Test for alternating 0's and 1's
1351		 */
1352		filli(0x55555555, CADDR1, PAGE_SIZE/sizeof(int));
1353		if (test_page((int *)CADDR1, 0x55555555)) {
1354			Maxmem = target_page;
1355			badpages++;
1356			continue;
1357		}
1358		/*
1359		 * Test for all 1's
1360		 */
1361		filli(0xffffffff, CADDR1, PAGE_SIZE/sizeof(int));
1362		if (test_page((int *)CADDR1, 0xffffffff)) {
1363			Maxmem = target_page;
1364			badpages++;
1365			continue;
1366		}
1367		/*
1368		 * Test zeroing of page
1369		 */
1370		bzero(CADDR1, PAGE_SIZE);
1371		if (test_page((int *)CADDR1, 0)) {
1372			/*
1373			 * test of page failed
1374			 */
1375			Maxmem = target_page;
1376			badpages++;
1377			continue;
1378		}
1379	}
1380	printf("done.\n");
1381
1382	*(int *)CMAP1 = 0;
1383	pmap_update();
1384
1385	avail_end = (Maxmem << PAGE_SHIFT)
1386		    - i386_round_page(sizeof(struct msgbuf));
1387
1388	/*
1389	 * Initialize pointers to the two chunks of memory; for use
1390	 *	later in vm_page_startup.
1391	 */
1392	/* avail_start is initialized in pmap_bootstrap */
1393	x = 0;
1394	if (pagesinbase > 1) {
1395		phys_avail[x++] = NBPG;		/* skip first page of memory */
1396		phys_avail[x++] = pagesinbase * NBPG;	/* memory up to the ISA hole */
1397	}
1398	phys_avail[x++] = avail_start;	/* memory up to the end */
1399	phys_avail[x++] = avail_end;
1400	phys_avail[x++] = 0;		/* no more chunks */
1401	phys_avail[x++] = 0;
1402
1403	/* now running on new page tables, configured,and u/iom is accessible */
1404
1405	/* make a initial tss so microp can get interrupt stack on syscall! */
1406	proc0.p_addr->u_pcb.pcb_tss.tss_esp0 = (int) kstack + UPAGES*NBPG;
1407	proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
1408	_gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
1409
1410	((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt =
1411		(sizeof(tss))<<16;
1412
1413	ltr(_gsel_tss);
1414
1415	/* make a call gate to reenter kernel with */
1416	gdp = &ldt[LSYS5CALLS_SEL].gd;
1417
1418	x = (int) &IDTVEC(syscall);
1419	gdp->gd_looffset = x++;
1420	gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
1421	gdp->gd_stkcpy = 1;
1422	gdp->gd_type = SDT_SYS386CGT;
1423	gdp->gd_dpl = SEL_UPL;
1424	gdp->gd_p = 1;
1425	gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16;
1426
1427	/* transfer to user mode */
1428
1429	_ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
1430	_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
1431
1432	/* setup proc 0's pcb */
1433	bcopy(&sigcode, proc0.p_addr->u_pcb.pcb_sigc, szsigcode);
1434	proc0.p_addr->u_pcb.pcb_flags = 0;
1435	proc0.p_addr->u_pcb.pcb_ptd = IdlePTD;
1436}
1437
1438int
1439test_page(address, pattern)
1440	int *address;
1441	int pattern;
1442{
1443	int *x;
1444
1445	for (x = address; x < (int *)((char *)address + PAGE_SIZE); x++) {
1446		if (*x != pattern)
1447			return (1);
1448	}
1449	return(0);
1450}
1451
1452/*
1453 * The registers are in the frame; the frame is in the user area of
1454 * the process in question; when the process is active, the registers
1455 * are in "the kernel stack"; when it's not, they're still there, but
1456 * things get flipped around.  So, since p->p_md.md_regs is the whole address
1457 * of the register set, take its offset from the kernel stack, and
1458 * index into the user block.  Don't you just *love* virtual memory?
1459 * (I'm starting to think seymour is right...)
1460 */
1461
1462int
1463ptrace_set_pc (struct proc *p, unsigned int addr) {
1464	void *regs = (char*)p->p_addr +
1465		((char*) p->p_md.md_regs - (char*) kstack);
1466
1467	((struct trapframe *)regs)->tf_eip = addr;
1468	return 0;
1469}
1470
1471int
1472ptrace_single_step (struct proc *p) {
1473	void *regs = (char*)p->p_addr +
1474		((char*) p->p_md.md_regs - (char*) kstack);
1475
1476	((struct trapframe *)regs)->tf_eflags |= PSL_T;
1477	return 0;
1478}
1479
1480/*
1481 * Copy the registers to user-space.
1482 */
1483
1484int
1485ptrace_getregs (struct proc *p, unsigned int *addr) {
1486	int error;
1487	struct reg regs = {0};
1488
1489	error = fill_regs (p, &regs);
1490	if (error)
1491		return error;
1492
1493	return copyout (&regs, addr, sizeof (regs));
1494}
1495
1496int
1497ptrace_setregs (struct proc *p, unsigned int *addr) {
1498	int error;
1499	struct reg regs = {0};
1500
1501	error = copyin (addr, &regs, sizeof(regs));
1502	if (error)
1503		return error;
1504
1505	return set_regs (p, &regs);
1506}
1507
1508int
1509fill_regs(struct proc *p, struct reg *regs) {
1510	struct trapframe *tp;
1511	void *ptr = (char*)p->p_addr +
1512		((char*) p->p_md.md_regs - (char*) kstack);
1513
1514	tp = ptr;
1515	regs->r_es = tp->tf_es;
1516	regs->r_ds = tp->tf_ds;
1517	regs->r_edi = tp->tf_edi;
1518	regs->r_esi = tp->tf_esi;
1519	regs->r_ebp = tp->tf_ebp;
1520	regs->r_ebx = tp->tf_ebx;
1521	regs->r_edx = tp->tf_edx;
1522	regs->r_ecx = tp->tf_ecx;
1523	regs->r_eax = tp->tf_eax;
1524	regs->r_eip = tp->tf_eip;
1525	regs->r_cs = tp->tf_cs;
1526	regs->r_eflags = tp->tf_eflags;
1527	regs->r_esp = tp->tf_esp;
1528	regs->r_ss = tp->tf_ss;
1529	return 0;
1530}
1531
1532int
1533set_regs (struct proc *p, struct reg *regs) {
1534	struct trapframe *tp;
1535	void *ptr = (char*)p->p_addr +
1536		((char*) p->p_md.md_regs - (char*) kstack);
1537
1538	tp = ptr;
1539	tp->tf_es = regs->r_es;
1540	tp->tf_ds = regs->r_ds;
1541	tp->tf_edi = regs->r_edi;
1542	tp->tf_esi = regs->r_esi;
1543	tp->tf_ebp = regs->r_ebp;
1544	tp->tf_ebx = regs->r_ebx;
1545	tp->tf_edx = regs->r_edx;
1546	tp->tf_ecx = regs->r_ecx;
1547	tp->tf_eax = regs->r_eax;
1548	tp->tf_eip = regs->r_eip;
1549	tp->tf_cs = regs->r_cs;
1550	tp->tf_eflags = regs->r_eflags;
1551	tp->tf_esp = regs->r_esp;
1552	tp->tf_ss = regs->r_ss;
1553	return 0;
1554}
1555
1556#ifndef DDB
1557void
1558Debugger(const char *msg)
1559{
1560	printf("Debugger(\"%s\") called.\n", msg);
1561}
1562#endif /* no DDB */
1563
1564#include <sys/disklabel.h>
1565#define b_cylin	b_resid
1566#define dkpart(dev)              (minor(dev) & 7)
1567/*
1568 * Determine the size of the transfer, and make sure it is
1569 * within the boundaries of the partition. Adjust transfer
1570 * if needed, and signal errors or early completion.
1571 */
1572int
1573bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel)
1574{
1575        struct partition *p = lp->d_partitions + dkpart(bp->b_dev);
1576        int labelsect = lp->d_partitions[0].p_offset;
1577        int maxsz = p->p_size,
1578                sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
1579
1580        /* overwriting disk label ? */
1581        /* XXX should also protect bootstrap in first 8K */
1582        if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect &&
1583#if LABELSECTOR != 0
1584            bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect &&
1585#endif
1586            (bp->b_flags & B_READ) == 0 && wlabel == 0) {
1587                bp->b_error = EROFS;
1588                goto bad;
1589        }
1590
1591#if     defined(DOSBBSECTOR) && defined(notyet)
1592        /* overwriting master boot record? */
1593        if (bp->b_blkno + p->p_offset <= DOSBBSECTOR &&
1594            (bp->b_flags & B_READ) == 0 && wlabel == 0) {
1595                bp->b_error = EROFS;
1596                goto bad;
1597        }
1598#endif
1599
1600        /* beyond partition? */
1601        if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
1602                /* if exactly at end of disk, return an EOF */
1603                if (bp->b_blkno == maxsz) {
1604                        bp->b_resid = bp->b_bcount;
1605                        return(0);
1606                }
1607                /* or truncate if part of it fits */
1608                sz = maxsz - bp->b_blkno;
1609                if (sz <= 0) {
1610                        bp->b_error = EINVAL;
1611                        goto bad;
1612                }
1613                bp->b_bcount = sz << DEV_BSHIFT;
1614        }
1615
1616        /* calculate cylinder for disksort to order transfers with */
1617        bp->b_pblkno = bp->b_blkno + p->p_offset;
1618        bp->b_cylin = bp->b_pblkno / lp->d_secpercyl;
1619        return(1);
1620
1621bad:
1622        bp->b_flags |= B_ERROR;
1623        return(-1);
1624}
1625
1626int
1627disk_externalize(int drive, void *userp, size_t *maxlen)
1628{
1629	if(*maxlen < sizeof drive) {
1630		return ENOMEM;
1631	}
1632
1633	*maxlen -= sizeof drive;
1634	return copyout(&drive, userp, sizeof drive);
1635}
1636
1637