machdep.c revision 4038
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.83 1994/10/28 12:41:50 jkh 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	int error;
913
914	/* all sysctl names at this level are terminal */
915	if (namelen != 1)
916		return (ENOTDIR);               /* overloaded */
917
918	switch (name[0]) {
919	case CPU_CONSDEV:
920		return (sysctl_rdstruct(oldp, oldlenp, newp, &cn_tty->t_dev,
921		   sizeof cn_tty->t_dev));
922	case CPU_ADJKERNTZ:
923		error = sysctl_int(oldp, oldlenp, newp, newlen, &adjkerntz);
924		if (!error && newp)
925			resettodr();
926		return error;
927	case CPU_DISRTCSET:
928		return (sysctl_int(oldp, oldlenp, newp,	newlen,	&disable_rtc_set));
929	default:
930		return (EOPNOTSUPP);
931	}
932	/* NOTREACHED */
933}
934
935/*
936 * Initialize 386 and configure to run kernel
937 */
938
939/*
940 * Initialize segments & interrupt table
941 */
942
943union descriptor gdt[NGDT];
944union descriptor ldt[NLDT];		/* local descriptor table */
945struct gate_descriptor idt[NIDT];	/* interrupt descriptor table */
946
947int _default_ldt, currentldt;
948
949struct	i386tss	tss, panic_tss;
950
951extern  struct user *proc0paddr;
952
953/* software prototypes -- in more palatable form */
954struct soft_segment_descriptor gdt_segs[] = {
955/* GNULL_SEL	0 Null Descriptor */
956{	0x0,			/* segment base address  */
957	0x0,			/* length */
958	0,			/* segment type */
959	0,			/* segment descriptor priority level */
960	0,			/* segment descriptor present */
961	0, 0,
962	0,			/* default 32 vs 16 bit size */
963	0  			/* limit granularity (byte/page units)*/ },
964/* GCODE_SEL	1 Code Descriptor for kernel */
965{	0x0,			/* segment base address  */
966	0xfffff,		/* length - all address space */
967	SDT_MEMERA,		/* segment type */
968	0,			/* segment descriptor priority level */
969	1,			/* segment descriptor present */
970	0, 0,
971	1,			/* default 32 vs 16 bit size */
972	1  			/* limit granularity (byte/page units)*/ },
973/* GDATA_SEL	2 Data Descriptor for kernel */
974{	0x0,			/* segment base address  */
975	0xfffff,		/* length - all address space */
976	SDT_MEMRWA,		/* segment type */
977	0,			/* segment descriptor priority level */
978	1,			/* segment descriptor present */
979	0, 0,
980	1,			/* default 32 vs 16 bit size */
981	1  			/* limit granularity (byte/page units)*/ },
982/* GLDT_SEL	3 LDT Descriptor */
983{	(int) ldt,		/* segment base address  */
984	sizeof(ldt)-1,		/* length - all address space */
985	SDT_SYSLDT,		/* segment type */
986	0,			/* segment descriptor priority level */
987	1,			/* segment descriptor present */
988	0, 0,
989	0,			/* unused - default 32 vs 16 bit size */
990	0  			/* limit granularity (byte/page units)*/ },
991/* GTGATE_SEL	4 Null Descriptor - Placeholder */
992{	0x0,			/* segment base address  */
993	0x0,			/* length - all address space */
994	0,			/* segment type */
995	0,			/* segment descriptor priority level */
996	0,			/* segment descriptor present */
997	0, 0,
998	0,			/* default 32 vs 16 bit size */
999	0  			/* limit granularity (byte/page units)*/ },
1000/* GPANIC_SEL	5 Panic Tss Descriptor */
1001{	(int) &panic_tss,	/* segment base address  */
1002	sizeof(tss)-1,		/* length - all address space */
1003	SDT_SYS386TSS,		/* segment type */
1004	0,			/* segment descriptor priority level */
1005	1,			/* segment descriptor present */
1006	0, 0,
1007	0,			/* unused - default 32 vs 16 bit size */
1008	0  			/* limit granularity (byte/page units)*/ },
1009/* GPROC0_SEL	6 Proc 0 Tss Descriptor */
1010{	(int) kstack,		/* segment base address  */
1011	sizeof(tss)-1,		/* length - all address space */
1012	SDT_SYS386TSS,		/* segment type */
1013	0,			/* segment descriptor priority level */
1014	1,			/* segment descriptor present */
1015	0, 0,
1016	0,			/* unused - default 32 vs 16 bit size */
1017	0  			/* limit granularity (byte/page units)*/ },
1018/* GUSERLDT_SEL	7 User LDT Descriptor per process */
1019{	(int) ldt,		/* segment base address  */
1020	(512 * sizeof(union descriptor)-1),		/* length */
1021	SDT_SYSLDT,		/* segment type */
1022	0,			/* segment descriptor priority level */
1023	1,			/* segment descriptor present */
1024	0, 0,
1025	0,			/* unused - default 32 vs 16 bit size */
1026	0  			/* limit granularity (byte/page units)*/ },
1027/* GAPMCODE32_SEL 8 APM BIOS 32-bit interface (32bit Code) */
1028{	0,			/* segment base address (overwritten by APM)  */
1029	0xfffff,		/* length */
1030	SDT_MEMERA,		/* segment type */
1031	0,			/* segment descriptor priority level */
1032	1,			/* segment descriptor present */
1033	0, 0,
1034	1,			/* default 32 vs 16 bit size */
1035	1  			/* limit granularity (byte/page units)*/ },
1036/* GAPMCODE16_SEL 9 APM BIOS 32-bit interface (16bit Code) */
1037{	0,			/* segment base address (overwritten by APM)  */
1038	0xfffff,		/* length */
1039	SDT_MEMERA,		/* segment type */
1040	0,			/* segment descriptor priority level */
1041	1,			/* segment descriptor present */
1042	0, 0,
1043	0,			/* default 32 vs 16 bit size */
1044	1  			/* limit granularity (byte/page units)*/ },
1045/* GAPMDATA_SEL	10 APM BIOS 32-bit interface (Data) */
1046{	0,			/* segment base address (overwritten by APM) */
1047	0xfffff,		/* length */
1048	SDT_MEMRWA,		/* segment type */
1049	0,			/* segment descriptor priority level */
1050	1,			/* segment descriptor present */
1051	0, 0,
1052	1,			/* default 32 vs 16 bit size */
1053	1  			/* limit granularity (byte/page units)*/ },
1054};
1055
1056struct soft_segment_descriptor ldt_segs[] = {
1057	/* Null Descriptor - overwritten by call gate */
1058{	0x0,			/* segment base address  */
1059	0x0,			/* length - all address space */
1060	0,			/* segment type */
1061	0,			/* segment descriptor priority level */
1062	0,			/* segment descriptor present */
1063	0, 0,
1064	0,			/* default 32 vs 16 bit size */
1065	0  			/* limit granularity (byte/page units)*/ },
1066	/* Null Descriptor - overwritten by call gate */
1067{	0x0,			/* segment base address  */
1068	0x0,			/* length - all address space */
1069	0,			/* segment type */
1070	0,			/* segment descriptor priority level */
1071	0,			/* segment descriptor present */
1072	0, 0,
1073	0,			/* default 32 vs 16 bit size */
1074	0  			/* limit granularity (byte/page units)*/ },
1075	/* Null Descriptor - overwritten by call gate */
1076{	0x0,			/* segment base address  */
1077	0x0,			/* length - all address space */
1078	0,			/* segment type */
1079	0,			/* segment descriptor priority level */
1080	0,			/* segment descriptor present */
1081	0, 0,
1082	0,			/* default 32 vs 16 bit size */
1083	0  			/* limit granularity (byte/page units)*/ },
1084	/* Code Descriptor for user */
1085{	0x0,			/* segment base address  */
1086	0xfffff,		/* length - all address space */
1087	SDT_MEMERA,		/* segment type */
1088	SEL_UPL,		/* segment descriptor priority level */
1089	1,			/* segment descriptor present */
1090	0, 0,
1091	1,			/* default 32 vs 16 bit size */
1092	1  			/* limit granularity (byte/page units)*/ },
1093	/* Data Descriptor for user */
1094{	0x0,			/* segment base address  */
1095	0xfffff,		/* length - all address space */
1096	SDT_MEMRWA,		/* segment type */
1097	SEL_UPL,		/* segment descriptor priority level */
1098	1,			/* segment descriptor present */
1099	0, 0,
1100	1,			/* default 32 vs 16 bit size */
1101	1  			/* limit granularity (byte/page units)*/ } };
1102
1103void
1104setidt(idx, func, typ, dpl)
1105	int idx;
1106	void (*func)();
1107	int typ;
1108	int dpl;
1109{
1110	struct gate_descriptor *ip = idt + idx;
1111
1112	ip->gd_looffset = (int)func;
1113	ip->gd_selector = 8;
1114	ip->gd_stkcpy = 0;
1115	ip->gd_xx = 0;
1116	ip->gd_type = typ;
1117	ip->gd_dpl = dpl;
1118	ip->gd_p = 1;
1119	ip->gd_hioffset = ((int)func)>>16 ;
1120}
1121
1122#define	IDTVEC(name)	__CONCAT(X,name)
1123typedef void idtvec_t();
1124
1125extern idtvec_t
1126	IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
1127	IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(dble), IDTVEC(fpusegm),
1128	IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
1129	IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(rsvd0),
1130	IDTVEC(rsvd1), IDTVEC(rsvd2), IDTVEC(rsvd3), IDTVEC(rsvd4),
1131	IDTVEC(rsvd5), IDTVEC(rsvd6), IDTVEC(rsvd7), IDTVEC(rsvd8),
1132	IDTVEC(rsvd9), IDTVEC(rsvd10), IDTVEC(rsvd11), IDTVEC(rsvd12),
1133	IDTVEC(rsvd13), IDTVEC(rsvd14), IDTVEC(syscall);
1134
1135int _gsel_tss;
1136
1137/* added sdtossd() by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp> */
1138int
1139sdtossd(sd, ssd)
1140	struct segment_descriptor *sd;
1141	struct soft_segment_descriptor *ssd;
1142{
1143	ssd->ssd_base  = (sd->sd_hibase << 24) | sd->sd_lobase;
1144	ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit;
1145	ssd->ssd_type  = sd->sd_type;
1146	ssd->ssd_dpl   = sd->sd_dpl;
1147	ssd->ssd_p     = sd->sd_p;
1148	ssd->ssd_def32 = sd->sd_def32;
1149	ssd->ssd_gran  = sd->sd_gran;
1150	return 0;
1151}
1152
1153void
1154init386(first)
1155	int first;
1156{
1157	extern lgdt(), lidt(), lldt();
1158	int x;
1159	unsigned biosbasemem, biosextmem;
1160	struct gate_descriptor *gdp;
1161	extern int sigcode,szsigcode;
1162	/* table descriptors - used to load tables by microp */
1163	struct region_descriptor r_gdt, r_idt;
1164	int	pagesinbase, pagesinext;
1165	int	target_page;
1166	extern struct pte *CMAP1;
1167	extern caddr_t CADDR1;
1168
1169	proc0.p_addr = proc0paddr;
1170
1171	/*
1172	 * Initialize the console before we print anything out.
1173	 */
1174
1175	cninit ();
1176
1177	/*
1178	 * make gdt memory segments, the code segment goes up to end of the
1179	 * page with etext in it, the data segment goes to the end of
1180	 * the address space
1181	 */
1182	gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1 /* i386_btop(i386_round_page(&etext)) - 1 */;
1183	gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1;
1184	for (x=0; x < NGDT; x++) ssdtosd(gdt_segs+x, gdt+x);
1185
1186	/* make ldt memory segments */
1187	/*
1188	 * The data segment limit must not cover the user area because we
1189	 * don't want the user area to be writable in copyout() etc. (page
1190	 * level protection is lost in kernel mode on 386's).  Also, we
1191	 * don't want the user area to be writable directly (page level
1192	 * protection of the user area is not available on 486's with
1193	 * CR0_WP set, because there is no user-read/kernel-write mode).
1194	 *
1195	 * XXX - VM_MAXUSER_ADDRESS is an end address, not a max.  And it
1196	 * should be spelled ...MAX_USER...
1197	 */
1198#define VM_END_USER_RW_ADDRESS	VM_MAXUSER_ADDRESS
1199	/*
1200	 * The code segment limit has to cover the user area until we move
1201	 * the signal trampoline out of the user area.  This is safe because
1202	 * the code segment cannot be written to directly.
1203	 */
1204#define VM_END_USER_R_ADDRESS	(VM_END_USER_RW_ADDRESS + UPAGES * NBPG)
1205	ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1;
1206	ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1;
1207	/* Note. eventually want private ldts per process */
1208	for (x=0; x < 5; x++) ssdtosd(ldt_segs+x, ldt+x);
1209
1210	/* exceptions */
1211	setidt(0, &IDTVEC(div),  SDT_SYS386TGT, SEL_KPL);
1212	setidt(1, &IDTVEC(dbg),  SDT_SYS386TGT, SEL_KPL);
1213	setidt(2, &IDTVEC(nmi),  SDT_SYS386TGT, SEL_KPL);
1214 	setidt(3, &IDTVEC(bpt),  SDT_SYS386TGT, SEL_UPL);
1215	setidt(4, &IDTVEC(ofl),  SDT_SYS386TGT, SEL_UPL);
1216	setidt(5, &IDTVEC(bnd),  SDT_SYS386TGT, SEL_KPL);
1217	setidt(6, &IDTVEC(ill),  SDT_SYS386TGT, SEL_KPL);
1218	setidt(7, &IDTVEC(dna),  SDT_SYS386TGT, SEL_KPL);
1219	setidt(8, &IDTVEC(dble),  SDT_SYS386TGT, SEL_KPL);
1220	setidt(9, &IDTVEC(fpusegm),  SDT_SYS386TGT, SEL_KPL);
1221	setidt(10, &IDTVEC(tss),  SDT_SYS386TGT, SEL_KPL);
1222	setidt(11, &IDTVEC(missing),  SDT_SYS386TGT, SEL_KPL);
1223	setidt(12, &IDTVEC(stk),  SDT_SYS386TGT, SEL_KPL);
1224	setidt(13, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL);
1225	setidt(14, &IDTVEC(page),  SDT_SYS386TGT, SEL_KPL);
1226	setidt(15, &IDTVEC(rsvd),  SDT_SYS386TGT, SEL_KPL);
1227	setidt(16, &IDTVEC(fpu),  SDT_SYS386TGT, SEL_KPL);
1228	setidt(17, &IDTVEC(rsvd0),  SDT_SYS386TGT, SEL_KPL);
1229	setidt(18, &IDTVEC(rsvd1),  SDT_SYS386TGT, SEL_KPL);
1230	setidt(19, &IDTVEC(rsvd2),  SDT_SYS386TGT, SEL_KPL);
1231	setidt(20, &IDTVEC(rsvd3),  SDT_SYS386TGT, SEL_KPL);
1232	setidt(21, &IDTVEC(rsvd4),  SDT_SYS386TGT, SEL_KPL);
1233	setidt(22, &IDTVEC(rsvd5),  SDT_SYS386TGT, SEL_KPL);
1234	setidt(23, &IDTVEC(rsvd6),  SDT_SYS386TGT, SEL_KPL);
1235	setidt(24, &IDTVEC(rsvd7),  SDT_SYS386TGT, SEL_KPL);
1236	setidt(25, &IDTVEC(rsvd8),  SDT_SYS386TGT, SEL_KPL);
1237	setidt(26, &IDTVEC(rsvd9),  SDT_SYS386TGT, SEL_KPL);
1238	setidt(27, &IDTVEC(rsvd10),  SDT_SYS386TGT, SEL_KPL);
1239	setidt(28, &IDTVEC(rsvd11),  SDT_SYS386TGT, SEL_KPL);
1240	setidt(29, &IDTVEC(rsvd12),  SDT_SYS386TGT, SEL_KPL);
1241	setidt(30, &IDTVEC(rsvd13),  SDT_SYS386TGT, SEL_KPL);
1242	setidt(31, &IDTVEC(rsvd14),  SDT_SYS386TGT, SEL_KPL);
1243
1244#include	"isa.h"
1245#if	NISA >0
1246	isa_defaultirq();
1247#endif
1248
1249	r_gdt.rd_limit = sizeof(gdt) - 1;
1250	r_gdt.rd_base =  (int) gdt;
1251	lgdt(&r_gdt);
1252
1253	r_idt.rd_limit = sizeof(idt) - 1;
1254	r_idt.rd_base = (int) idt;
1255	lidt(&r_idt);
1256
1257	_default_ldt = GSEL(GLDT_SEL, SEL_KPL);
1258	lldt(_default_ldt);
1259	currentldt = _default_ldt;
1260
1261#ifdef DDB
1262	kdb_init();
1263	if (boothowto & RB_KDB)
1264		Debugger("Boot flags requested debugger");
1265#endif
1266
1267	/* Use BIOS values stored in RTC CMOS RAM, since probing
1268	 * breaks certain 386 AT relics.
1269	 */
1270	biosbasemem = rtcin(RTC_BASELO)+ (rtcin(RTC_BASEHI)<<8);
1271	biosextmem = rtcin(RTC_EXTLO)+ (rtcin(RTC_EXTHI)<<8);
1272
1273	/*
1274	 * If BIOS tells us that it has more than 640k in the basemem,
1275	 *	don't believe it - set it to 640k.
1276	 */
1277	if (biosbasemem > 640)
1278		biosbasemem = 640;
1279
1280	/*
1281	 * Some 386 machines might give us a bogus number for extended
1282	 *	mem. If this happens, stop now.
1283	 */
1284#ifndef LARGEMEM
1285	if (biosextmem > 65536) {
1286		panic("extended memory beyond limit of 64MB");
1287		/* NOTREACHED */
1288	}
1289#endif
1290
1291	pagesinbase = biosbasemem * 1024 / NBPG;
1292	pagesinext = biosextmem * 1024 / NBPG;
1293
1294	/*
1295	 * Special hack for chipsets that still remap the 384k hole when
1296	 *	there's 16MB of memory - this really confuses people that
1297	 *	are trying to use bus mastering ISA controllers with the
1298	 *	"16MB limit"; they only have 16MB, but the remapping puts
1299	 *	them beyond the limit.
1300	 * XXX - this should be removed when bounce buffers are
1301	 *	implemented.
1302	 */
1303	/*
1304	 * If extended memory is between 15-16MB (16-17MB phys address range),
1305	 *	chop it to 15MB.
1306	 */
1307	if ((pagesinext > 3840) && (pagesinext < 4096))
1308		pagesinext = 3840;
1309
1310	/*
1311	 * Maxmem isn't the "maximum memory", it's the highest page of
1312	 * of the physical address space. It should be "Maxphyspage".
1313	 */
1314	Maxmem = pagesinext + 0x100000/PAGE_SIZE;
1315
1316#ifdef MAXMEM
1317	if (MAXMEM/4 < Maxmem)
1318		Maxmem = MAXMEM/4;
1319#endif
1320	/*
1321	 * Calculate number of physical pages, but account for Maxmem
1322	 *	adjustment above.
1323	 */
1324	physmem = pagesinbase + Maxmem - 0x100000/PAGE_SIZE;
1325
1326	/* call pmap initialization to make new kernel address space */
1327	pmap_bootstrap (first, 0);
1328
1329	/*
1330	 * Do simple memory test over range of extended memory that BIOS
1331	 *	indicates exists. Adjust Maxmem to the highest page of
1332	 *	good memory.
1333	 */
1334	printf("Testing memory (%dMB)...", ptoa(Maxmem)/1024/1024);
1335
1336	for (target_page = Maxmem - 1; target_page >= atop(first); target_page--) {
1337
1338		/*
1339		 * map page into kernel: valid, read/write, non-cacheable
1340		 */
1341		*(int *)CMAP1 = PG_V | PG_KW | PG_N | ptoa(target_page);
1342		pmap_update();
1343
1344		/*
1345		 * Test for alternating 1's and 0's
1346		 */
1347		filli(0xaaaaaaaa, CADDR1, PAGE_SIZE/sizeof(int));
1348		if (test_page((int *)CADDR1, 0xaaaaaaaa)) {
1349			Maxmem = target_page;
1350			badpages++;
1351			continue;
1352		}
1353		/*
1354		 * Test for alternating 0's and 1's
1355		 */
1356		filli(0x55555555, CADDR1, PAGE_SIZE/sizeof(int));
1357		if (test_page((int *)CADDR1, 0x55555555)) {
1358			Maxmem = target_page;
1359			badpages++;
1360			continue;
1361		}
1362		/*
1363		 * Test for all 1's
1364		 */
1365		filli(0xffffffff, CADDR1, PAGE_SIZE/sizeof(int));
1366		if (test_page((int *)CADDR1, 0xffffffff)) {
1367			Maxmem = target_page;
1368			badpages++;
1369			continue;
1370		}
1371		/*
1372		 * Test zeroing of page
1373		 */
1374		bzero(CADDR1, PAGE_SIZE);
1375		if (test_page((int *)CADDR1, 0)) {
1376			/*
1377			 * test of page failed
1378			 */
1379			Maxmem = target_page;
1380			badpages++;
1381			continue;
1382		}
1383	}
1384	printf("done.\n");
1385
1386	*(int *)CMAP1 = 0;
1387	pmap_update();
1388
1389	avail_end = (Maxmem << PAGE_SHIFT)
1390		    - i386_round_page(sizeof(struct msgbuf));
1391
1392	/*
1393	 * Initialize pointers to the two chunks of memory; for use
1394	 *	later in vm_page_startup.
1395	 */
1396	/* avail_start is initialized in pmap_bootstrap */
1397	x = 0;
1398	if (pagesinbase > 1) {
1399		phys_avail[x++] = NBPG;		/* skip first page of memory */
1400		phys_avail[x++] = pagesinbase * NBPG;	/* memory up to the ISA hole */
1401	}
1402	phys_avail[x++] = avail_start;	/* memory up to the end */
1403	phys_avail[x++] = avail_end;
1404	phys_avail[x++] = 0;		/* no more chunks */
1405	phys_avail[x++] = 0;
1406
1407	/* now running on new page tables, configured,and u/iom is accessible */
1408
1409	/* make a initial tss so microp can get interrupt stack on syscall! */
1410	proc0.p_addr->u_pcb.pcb_tss.tss_esp0 = (int) kstack + UPAGES*NBPG;
1411	proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
1412	_gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
1413
1414	((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt =
1415		(sizeof(tss))<<16;
1416
1417	ltr(_gsel_tss);
1418
1419	/* make a call gate to reenter kernel with */
1420	gdp = &ldt[LSYS5CALLS_SEL].gd;
1421
1422	x = (int) &IDTVEC(syscall);
1423	gdp->gd_looffset = x++;
1424	gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
1425	gdp->gd_stkcpy = 1;
1426	gdp->gd_type = SDT_SYS386CGT;
1427	gdp->gd_dpl = SEL_UPL;
1428	gdp->gd_p = 1;
1429	gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16;
1430
1431	/* transfer to user mode */
1432
1433	_ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
1434	_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
1435
1436	/* setup proc 0's pcb */
1437	bcopy(&sigcode, proc0.p_addr->u_pcb.pcb_sigc, szsigcode);
1438	proc0.p_addr->u_pcb.pcb_flags = 0;
1439	proc0.p_addr->u_pcb.pcb_ptd = IdlePTD;
1440}
1441
1442int
1443test_page(address, pattern)
1444	int *address;
1445	int pattern;
1446{
1447	int *x;
1448
1449	for (x = address; x < (int *)((char *)address + PAGE_SIZE); x++) {
1450		if (*x != pattern)
1451			return (1);
1452	}
1453	return(0);
1454}
1455
1456/*
1457 * The registers are in the frame; the frame is in the user area of
1458 * the process in question; when the process is active, the registers
1459 * are in "the kernel stack"; when it's not, they're still there, but
1460 * things get flipped around.  So, since p->p_md.md_regs is the whole address
1461 * of the register set, take its offset from the kernel stack, and
1462 * index into the user block.  Don't you just *love* virtual memory?
1463 * (I'm starting to think seymour is right...)
1464 */
1465
1466int
1467ptrace_set_pc (struct proc *p, unsigned int addr) {
1468	void *regs = (char*)p->p_addr +
1469		((char*) p->p_md.md_regs - (char*) kstack);
1470
1471	((struct trapframe *)regs)->tf_eip = addr;
1472	return 0;
1473}
1474
1475int
1476ptrace_single_step (struct proc *p) {
1477	void *regs = (char*)p->p_addr +
1478		((char*) p->p_md.md_regs - (char*) kstack);
1479
1480	((struct trapframe *)regs)->tf_eflags |= PSL_T;
1481	return 0;
1482}
1483
1484/*
1485 * Copy the registers to user-space.
1486 */
1487
1488int
1489ptrace_getregs (struct proc *p, unsigned int *addr) {
1490	int error;
1491	struct reg regs = {0};
1492
1493	error = fill_regs (p, &regs);
1494	if (error)
1495		return error;
1496
1497	return copyout (&regs, addr, sizeof (regs));
1498}
1499
1500int
1501ptrace_setregs (struct proc *p, unsigned int *addr) {
1502	int error;
1503	struct reg regs = {0};
1504
1505	error = copyin (addr, &regs, sizeof(regs));
1506	if (error)
1507		return error;
1508
1509	return set_regs (p, &regs);
1510}
1511
1512int
1513fill_regs(struct proc *p, struct reg *regs) {
1514	struct trapframe *tp;
1515	void *ptr = (char*)p->p_addr +
1516		((char*) p->p_md.md_regs - (char*) kstack);
1517
1518	tp = ptr;
1519	regs->r_es = tp->tf_es;
1520	regs->r_ds = tp->tf_ds;
1521	regs->r_edi = tp->tf_edi;
1522	regs->r_esi = tp->tf_esi;
1523	regs->r_ebp = tp->tf_ebp;
1524	regs->r_ebx = tp->tf_ebx;
1525	regs->r_edx = tp->tf_edx;
1526	regs->r_ecx = tp->tf_ecx;
1527	regs->r_eax = tp->tf_eax;
1528	regs->r_eip = tp->tf_eip;
1529	regs->r_cs = tp->tf_cs;
1530	regs->r_eflags = tp->tf_eflags;
1531	regs->r_esp = tp->tf_esp;
1532	regs->r_ss = tp->tf_ss;
1533	return 0;
1534}
1535
1536int
1537set_regs (struct proc *p, struct reg *regs) {
1538	struct trapframe *tp;
1539	void *ptr = (char*)p->p_addr +
1540		((char*) p->p_md.md_regs - (char*) kstack);
1541
1542	tp = ptr;
1543	tp->tf_es = regs->r_es;
1544	tp->tf_ds = regs->r_ds;
1545	tp->tf_edi = regs->r_edi;
1546	tp->tf_esi = regs->r_esi;
1547	tp->tf_ebp = regs->r_ebp;
1548	tp->tf_ebx = regs->r_ebx;
1549	tp->tf_edx = regs->r_edx;
1550	tp->tf_ecx = regs->r_ecx;
1551	tp->tf_eax = regs->r_eax;
1552	tp->tf_eip = regs->r_eip;
1553	tp->tf_cs = regs->r_cs;
1554	tp->tf_eflags = regs->r_eflags;
1555	tp->tf_esp = regs->r_esp;
1556	tp->tf_ss = regs->r_ss;
1557	return 0;
1558}
1559
1560#ifndef DDB
1561void
1562Debugger(const char *msg)
1563{
1564	printf("Debugger(\"%s\") called.\n", msg);
1565}
1566#endif /* no DDB */
1567
1568#include <sys/dkbad.h>
1569#include <sys/disklabel.h>
1570#define b_cylin	b_resid
1571/*
1572 * Determine the size of the transfer, and make sure it is
1573 * within the boundaries of the partition. Adjust transfer
1574 * if needed, and signal errors or early completion.
1575 */
1576int
1577bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel)
1578{
1579        struct partition *p = lp->d_partitions + dkpart(bp->b_dev);
1580        int labelsect = lp->d_partitions[0].p_offset;
1581        int maxsz = p->p_size,
1582                sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
1583
1584        /* overwriting disk label ? */
1585        /* XXX should also protect bootstrap in first 8K */
1586        if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect &&
1587#if LABELSECTOR != 0
1588            bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect &&
1589#endif
1590            (bp->b_flags & B_READ) == 0 && wlabel == 0) {
1591                bp->b_error = EROFS;
1592                goto bad;
1593        }
1594
1595#if     defined(DOSBBSECTOR) && defined(notyet)
1596        /* overwriting master boot record? */
1597        if (bp->b_blkno + p->p_offset <= DOSBBSECTOR &&
1598            (bp->b_flags & B_READ) == 0 && wlabel == 0) {
1599                bp->b_error = EROFS;
1600                goto bad;
1601        }
1602#endif
1603
1604        /* beyond partition? */
1605        if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
1606                /* if exactly at end of disk, return an EOF */
1607                if (bp->b_blkno == maxsz) {
1608                        bp->b_resid = bp->b_bcount;
1609                        return(0);
1610                }
1611                /* or truncate if part of it fits */
1612                sz = maxsz - bp->b_blkno;
1613                if (sz <= 0) {
1614                        bp->b_error = EINVAL;
1615                        goto bad;
1616                }
1617                bp->b_bcount = sz << DEV_BSHIFT;
1618        }
1619
1620        /* calculate cylinder for disksort to order transfers with */
1621        bp->b_pblkno = bp->b_blkno + p->p_offset;
1622        bp->b_cylin = bp->b_pblkno / lp->d_secpercyl;
1623        return(1);
1624
1625bad:
1626        bp->b_flags |= B_ERROR;
1627        return(-1);
1628}
1629
1630int
1631disk_externalize(int drive, void *userp, size_t *maxlen)
1632{
1633	if(*maxlen < sizeof drive) {
1634		return ENOMEM;
1635	}
1636
1637	*maxlen -= sizeof drive;
1638	return copyout(&drive, userp, sizeof drive);
1639}
1640
1641