]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/pc98/i386/machdep.c
Sync with sys/i386/i386/machdep.c revision 1.370.
[FreeBSD/FreeBSD.git] / sys / pc98 / i386 / machdep.c
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  * $FreeBSD$
39  */
40
41 #include "apm.h"
42 #include "ether.h"
43 #include "npx.h"
44 #include "opt_atalk.h"
45 #include "opt_compat.h"
46 #include "opt_cpu.h"
47 #include "opt_ddb.h"
48 #include "opt_inet.h"
49 #include "opt_ipx.h"
50 #include "opt_maxmem.h"
51 #include "opt_msgbuf.h"
52 #include "opt_perfmon.h"
53 #include "opt_smp.h"
54 #include "opt_sysvipc.h"
55 #include "opt_user_ldt.h"
56 #include "opt_userconfig.h"
57
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/sysproto.h>
61 #include <sys/signalvar.h>
62 #include <sys/kernel.h>
63 #include <sys/linker.h>
64 #include <sys/proc.h>
65 #include <sys/buf.h>
66 #include <sys/reboot.h>
67 #include <sys/callout.h>
68 #include <sys/malloc.h>
69 #include <sys/mbuf.h>
70 #include <sys/msgbuf.h>
71 #include <sys/sysent.h>
72 #include <sys/sysctl.h>
73 #include <sys/vmmeter.h>
74 #include <sys/bus.h>
75
76 #ifdef SYSVSHM
77 #include <sys/shm.h>
78 #endif
79
80 #ifdef SYSVMSG
81 #include <sys/msg.h>
82 #endif
83
84 #ifdef SYSVSEM
85 #include <sys/sem.h>
86 #endif
87
88 #include <vm/vm.h>
89 #include <vm/vm_param.h>
90 #include <vm/vm_prot.h>
91 #include <sys/lock.h>
92 #include <vm/vm_kern.h>
93 #include <vm/vm_object.h>
94 #include <vm/vm_page.h>
95 #include <vm/vm_map.h>
96 #include <vm/vm_pager.h>
97 #include <vm/vm_extern.h>
98
99 #include <sys/user.h>
100 #include <sys/exec.h>
101 #include <sys/cons.h>
102
103 #include <ddb/ddb.h>
104
105 #include <net/netisr.h>
106
107 #include <machine/cpu.h>
108 #include <machine/reg.h>
109 #include <machine/clock.h>
110 #include <machine/specialreg.h>
111 #include <machine/bootinfo.h>
112 #include <machine/ipl.h>
113 #include <machine/md_var.h>
114 #include <machine/pcb_ext.h>            /* pcb.h included via sys/user.h */
115 #ifdef SMP
116 #include <machine/smp.h>
117 #include <machine/globaldata.h>
118 #endif
119 #ifdef PERFMON
120 #include <machine/perfmon.h>
121 #endif
122
123 #ifdef OLD_BUS_ARCH
124 #include <i386/isa/isa_device.h>
125 #endif
126 #include <i386/isa/intr_machdep.h>
127 #ifdef PC98
128 #include <pc98/pc98/pc98_machdep.h>
129 #include <pc98/pc98/pc98.h>
130 #else
131 #include <i386/isa/rtc.h>
132 #endif
133 #include <machine/vm86.h>
134 #include <machine/random.h>
135 #include <sys/ptrace.h>
136 #include <machine/sigframe.h>
137
138 extern void init386 __P((int first));
139 extern void dblfault_handler __P((void));
140
141 extern void printcpuinfo(void); /* XXX header file */
142 extern void earlysetcpuclass(void);     /* same header file */
143 extern void finishidentcpu(void);
144 extern void panicifcpuunsupported(void);
145 extern void initializecpu(void);
146
147 static void cpu_startup __P((void *));
148 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
149
150 static MALLOC_DEFINE(M_MBUF, "mbuf", "mbuf");
151
152 #ifdef PC98
153 int     need_pre_dma_flush;     /* If 1, use wbinvd befor DMA transfer. */
154 int     need_post_dma_flush;    /* If 1, use invd after DMA transfer. */
155 #endif
156
157 int     _udatasel, _ucodesel;
158 u_int   atdevbase;
159
160 #if defined(SWTCH_OPTIM_STATS)
161 extern int swtch_optim_stats;
162 SYSCTL_INT(_debug, OID_AUTO, swtch_optim_stats,
163         CTLFLAG_RD, &swtch_optim_stats, 0, "");
164 SYSCTL_INT(_debug, OID_AUTO, tlb_flush_count,
165         CTLFLAG_RD, &tlb_flush_count, 0, "");
166 #endif
167
168 #ifdef PC98
169 static int      ispc98 = 1;
170 #else
171 static int      ispc98 = 0;
172 #endif
173 SYSCTL_INT(_machdep, OID_AUTO, ispc98, CTLFLAG_RD, &ispc98, 0, "");
174
175 int physmem = 0;
176 int cold = 1;
177
178 static int
179 sysctl_hw_physmem SYSCTL_HANDLER_ARGS
180 {
181         int error = sysctl_handle_int(oidp, 0, ctob(physmem), req);
182         return (error);
183 }
184
185 SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_INT|CTLFLAG_RD,
186         0, 0, sysctl_hw_physmem, "I", "");
187
188 static int
189 sysctl_hw_usermem SYSCTL_HANDLER_ARGS
190 {
191         int error = sysctl_handle_int(oidp, 0,
192                 ctob(physmem - cnt.v_wire_count), req);
193         return (error);
194 }
195
196 SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_INT|CTLFLAG_RD,
197         0, 0, sysctl_hw_usermem, "I", "");
198
199 static int
200 sysctl_hw_availpages SYSCTL_HANDLER_ARGS
201 {
202         int error = sysctl_handle_int(oidp, 0,
203                 i386_btop(avail_end - avail_start), req);
204         return (error);
205 }
206
207 SYSCTL_PROC(_hw, OID_AUTO, availpages, CTLTYPE_INT|CTLFLAG_RD,
208         0, 0, sysctl_hw_availpages, "I", "");
209
210 static int
211 sysctl_machdep_msgbuf SYSCTL_HANDLER_ARGS
212 {
213         int error;
214
215         /* Unwind the buffer, so that it's linear (possibly starting with
216          * some initial nulls).
217          */
218         error=sysctl_handle_opaque(oidp,msgbufp->msg_ptr+msgbufp->msg_bufr,
219                 msgbufp->msg_size-msgbufp->msg_bufr,req);
220         if(error) return(error);
221         if(msgbufp->msg_bufr>0) {
222                 error=sysctl_handle_opaque(oidp,msgbufp->msg_ptr,
223                         msgbufp->msg_bufr,req);
224         }
225         return(error);
226 }
227
228 SYSCTL_PROC(_machdep, OID_AUTO, msgbuf, CTLTYPE_STRING|CTLFLAG_RD,
229         0, 0, sysctl_machdep_msgbuf, "A","Contents of kernel message buffer");
230
231 static int msgbuf_clear;
232
233 static int
234 sysctl_machdep_msgbuf_clear SYSCTL_HANDLER_ARGS
235 {
236         int error;
237         error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2,
238                 req);
239         if (!error && req->newptr) {
240                 /* Clear the buffer and reset write pointer */
241                 bzero(msgbufp->msg_ptr,msgbufp->msg_size);
242                 msgbufp->msg_bufr=msgbufp->msg_bufx=0;
243                 msgbuf_clear=0;
244         }
245         return (error);
246 }
247
248 SYSCTL_PROC(_machdep, OID_AUTO, msgbuf_clear, CTLTYPE_INT|CTLFLAG_RW,
249         &msgbuf_clear, 0, sysctl_machdep_msgbuf_clear, "I",
250         "Clear kernel message buffer");
251
252 int bootverbose = 0, Maxmem = 0;
253 #ifdef PC98
254 int Maxmem_under16M = 0;
255 #endif
256 long dumplo;
257
258 vm_offset_t phys_avail[10];
259
260 /* must be 2 less so 0 0 can signal end of chunks */
261 #define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(vm_offset_t)) - 2)
262
263 static vm_offset_t buffer_sva, buffer_eva;
264 vm_offset_t clean_sva, clean_eva;
265 static vm_offset_t pager_sva, pager_eva;
266
267 #define offsetof(type, member)  ((size_t)(&((type *)0)->member))
268
269 static void
270 cpu_startup(dummy)
271         void *dummy;
272 {
273         register unsigned i;
274         register caddr_t v;
275         vm_offset_t maxaddr;
276         vm_size_t size = 0;
277         int firstaddr;
278         vm_offset_t minaddr;
279
280         if (boothowto & RB_VERBOSE)
281                 bootverbose++;
282
283         /*
284          * Good {morning,afternoon,evening,night}.
285          */
286         printf(version);
287         earlysetcpuclass();
288         startrtclock();
289         printcpuinfo();
290         panicifcpuunsupported();
291 #ifdef PERFMON
292         perfmon_init();
293 #endif
294         printf("real memory  = %u (%uK bytes)\n", ptoa(Maxmem), ptoa(Maxmem) / 1024);
295         /*
296          * Display any holes after the first chunk of extended memory.
297          */
298         if (bootverbose) {
299                 int indx;
300
301                 printf("Physical memory chunk(s):\n");
302                 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
303                         int size1 = phys_avail[indx + 1] - phys_avail[indx];
304
305                         printf("0x%08x - 0x%08x, %u bytes (%u pages)\n",
306                             phys_avail[indx], phys_avail[indx + 1] - 1, size1,
307                             size1 / PAGE_SIZE);
308                 }
309         }
310
311         /*
312          * Calculate callout wheel size
313          */
314         for (callwheelsize = 1, callwheelbits = 0;
315              callwheelsize < ncallout;
316              callwheelsize <<= 1, ++callwheelbits)
317                 ;
318         callwheelmask = callwheelsize - 1;
319
320         /*
321          * Allocate space for system data structures.
322          * The first available kernel virtual address is in "v".
323          * As pages of kernel virtual memory are allocated, "v" is incremented.
324          * As pages of memory are allocated and cleared,
325          * "firstaddr" is incremented.
326          * An index into the kernel page table corresponding to the
327          * virtual memory address maintained in "v" is kept in "mapaddr".
328          */
329
330         /*
331          * Make two passes.  The first pass calculates how much memory is
332          * needed and allocates it.  The second pass assigns virtual
333          * addresses to the various data structures.
334          */
335         firstaddr = 0;
336 again:
337         v = (caddr_t)firstaddr;
338
339 #define valloc(name, type, num) \
340             (name) = (type *)v; v = (caddr_t)((name)+(num))
341 #define valloclim(name, type, num, lim) \
342             (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
343
344         valloc(callout, struct callout, ncallout);
345         valloc(callwheel, struct callout_tailq, callwheelsize);
346 #ifdef SYSVSHM
347         valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
348 #endif
349 #ifdef SYSVSEM
350         valloc(sema, struct semid_ds, seminfo.semmni);
351         valloc(sem, struct sem, seminfo.semmns);
352         /* This is pretty disgusting! */
353         valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
354 #endif
355 #ifdef SYSVMSG
356         valloc(msgpool, char, msginfo.msgmax);
357         valloc(msgmaps, struct msgmap, msginfo.msgseg);
358         valloc(msghdrs, struct msg, msginfo.msgtql);
359         valloc(msqids, struct msqid_ds, msginfo.msgmni);
360 #endif
361
362         if (nbuf == 0) {
363                 nbuf = 30;
364                 if (physmem > 1024)
365                         nbuf += min((physmem - 1024) / 8, 2048);
366                 if (physmem > 16384)
367                         nbuf += (physmem - 16384) / 20;
368         }
369         nswbuf = max(min(nbuf/4, 256), 16);
370
371         valloc(swbuf, struct buf, nswbuf);
372         valloc(buf, struct buf, nbuf);
373         v = bufhashinit(v);
374
375         /*
376          * End of first pass, size has been calculated so allocate memory
377          */
378         if (firstaddr == 0) {
379                 size = (vm_size_t)(v - firstaddr);
380                 firstaddr = (int)kmem_alloc(kernel_map, round_page(size));
381                 if (firstaddr == 0)
382                         panic("startup: no room for tables");
383                 goto again;
384         }
385
386         /*
387          * End of second pass, addresses have been assigned
388          */
389         if ((vm_size_t)(v - firstaddr) != size)
390                 panic("startup: table size inconsistency");
391
392         clean_map = kmem_suballoc(kernel_map, &clean_sva, &clean_eva,
393                         (nbuf*BKVASIZE) + (nswbuf*MAXPHYS) + pager_map_size);
394         buffer_map = kmem_suballoc(clean_map, &buffer_sva, &buffer_eva,
395                                 (nbuf*BKVASIZE));
396         pager_map = kmem_suballoc(clean_map, &pager_sva, &pager_eva,
397                                 (nswbuf*MAXPHYS) + pager_map_size);
398         pager_map->system_map = 1;
399         exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
400                                 (16*(ARG_MAX+(PAGE_SIZE*3))));
401
402         /*
403          * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
404          * we use the more space efficient malloc in place of kmem_alloc.
405          */
406         {
407                 vm_offset_t mb_map_size;
408
409                 mb_map_size = nmbufs * MSIZE + nmbclusters * MCLBYTES;
410                 mb_map_size = roundup2(mb_map_size, max(MCLBYTES, PAGE_SIZE));
411                 mclrefcnt = malloc(mb_map_size / MCLBYTES, M_MBUF, M_NOWAIT);
412                 bzero(mclrefcnt, mb_map_size / MCLBYTES);
413                 mb_map = kmem_suballoc(kmem_map, (vm_offset_t *)&mbutl, &maxaddr,
414                         mb_map_size);
415                 mb_map->system_map = 1;
416         }
417
418         /*
419          * Initialize callouts
420          */
421         SLIST_INIT(&callfree);
422         for (i = 0; i < ncallout; i++) {
423                 callout_init(&callout[i]);
424                 callout[i].c_flags = CALLOUT_LOCAL_ALLOC;
425                 SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle);
426         }
427
428         for (i = 0; i < callwheelsize; i++) {
429                 TAILQ_INIT(&callwheel[i]);
430         }
431
432 #if defined(USERCONFIG)
433         userconfig();
434         cninit();               /* the preferred console may have changed */
435 #endif
436
437         printf("avail memory = %u (%uK bytes)\n", ptoa(cnt.v_free_count),
438             ptoa(cnt.v_free_count) / 1024);
439
440         /*
441          * Set up buffers, so they can be used to read disk labels.
442          */
443         bufinit();
444         vm_pager_bufferinit();
445
446 #ifdef SMP
447         /*
448          * OK, enough kmem_alloc/malloc state should be up, lets get on with it!
449          */
450         mp_start();                     /* fire up the APs and APICs */
451         mp_announce();
452 #endif  /* SMP */
453 }
454
455 int
456 register_netisr(num, handler)
457         int num;
458         netisr_t *handler;
459 {
460         
461         if (num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs)) ) {
462                 printf("register_netisr: bad isr number: %d\n", num);
463                 return (EINVAL);
464         }
465         netisrs[num] = handler;
466         return (0);
467 }
468
469 void
470 netisr_sysinit(data)
471         void *data;
472 {
473         const struct netisrtab *nit;
474
475         nit = (const struct netisrtab *)data;
476         register_netisr(nit->nit_num, nit->nit_isr);
477 }
478
479 /*
480  * Send an interrupt to process.
481  *
482  * Stack is set up to allow sigcode stored
483  * at top to call routine, followed by kcall
484  * to sigreturn routine below.  After sigreturn
485  * resets the signal mask, the stack, and the
486  * frame pointer, it returns to the user
487  * specified pc, psl.
488  */
489 static void
490 osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
491 {
492         register struct proc *p = curproc;
493         register struct trapframe *regs;
494         register struct osigframe *fp;
495         struct osigframe sf;
496         struct sigacts *psp = p->p_sigacts;
497         int oonstack;
498
499         regs = p->p_md.md_regs;
500         oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
501
502         /* Allocate and validate space for the signal handler context. */
503         if ((p->p_flag & P_ALTSTACK) && !oonstack &&
504             SIGISMEMBER(psp->ps_sigonstack, sig)) {
505                 fp = (struct osigframe *)(p->p_sigstk.ss_sp +
506                     p->p_sigstk.ss_size - sizeof(struct osigframe));
507                 p->p_sigstk.ss_flags |= SS_ONSTACK;
508         }
509         else
510                 fp = (struct osigframe *)regs->tf_esp - 1;
511
512         /*
513          * grow() will return FALSE if the fp will not fit inside the stack
514          *      and the stack can not be grown. useracc will return FALSE
515          *      if access is denied.
516          */
517         if (grow_stack(p, (int)fp) == FALSE ||
518             useracc((caddr_t)fp, sizeof(struct osigframe), B_WRITE) == FALSE) {
519                 /*
520                  * Process has trashed its stack; give it an illegal
521                  * instruction to halt it in its tracks.
522                  */
523                 SIGACTION(p, SIGILL) = SIG_DFL;
524                 SIGDELSET(p->p_sigignore, SIGILL);
525                 SIGDELSET(p->p_sigcatch, SIGILL);
526                 SIGDELSET(p->p_sigmask, SIGILL);
527                 psignal(p, SIGILL);
528                 return;
529         }
530
531         /* Translate the signal if appropriate */
532         if (p->p_sysent->sv_sigtbl) {
533                 if (sig <= p->p_sysent->sv_sigsize)
534                         sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
535         }
536
537         /* Build the argument list for the signal handler. */
538         sf.sf_signum = sig;
539         sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
540         if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
541                 /* Signal handler installed with SA_SIGINFO. */
542                 sf.sf_arg2 = (register_t)&fp->sf_siginfo;
543                 sf.sf_siginfo.si_signo = sig;
544                 sf.sf_siginfo.si_code = code;
545                 sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher;
546         }
547         else {
548                 /* Old FreeBSD-style arguments. */
549                 sf.sf_arg2 = code;
550                 sf.sf_addr = (char *)regs->tf_err;
551                 sf.sf_ahu.sf_handler = catcher;
552         }
553
554         /* save scratch registers */
555         sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax;
556         sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx;
557         sf.sf_siginfo.si_sc.sc_ecx = regs->tf_ecx;
558         sf.sf_siginfo.si_sc.sc_edx = regs->tf_edx;
559         sf.sf_siginfo.si_sc.sc_esi = regs->tf_esi;
560         sf.sf_siginfo.si_sc.sc_edi = regs->tf_edi;
561         sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs;
562         sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds;
563         sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss;
564         sf.sf_siginfo.si_sc.sc_es = regs->tf_es;
565         sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs;
566         sf.sf_siginfo.si_sc.sc_gs = rgs();
567         sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp;
568
569         /* Build the signal context to be used by sigreturn. */
570         sf.sf_siginfo.si_sc.sc_onstack = oonstack;
571         SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask);
572         sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp;
573         sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp;
574         sf.sf_siginfo.si_sc.sc_pc = regs->tf_eip;
575         sf.sf_siginfo.si_sc.sc_ps = regs->tf_eflags;
576         sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno;
577         sf.sf_siginfo.si_sc.sc_err = regs->tf_err;
578
579         /*
580          * If we're a vm86 process, we want to save the segment registers.
581          * We also change eflags to be our emulated eflags, not the actual
582          * eflags.
583          */
584         if (regs->tf_eflags & PSL_VM) {
585                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
586                 struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
587
588                 sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs;
589                 sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs;
590                 sf.sf_siginfo.si_sc.sc_es = tf->tf_vm86_es;
591                 sf.sf_siginfo.si_sc.sc_ds = tf->tf_vm86_ds;
592
593                 if (vm86->vm86_has_vme == 0)
594                         sf.sf_siginfo.si_sc.sc_ps =
595                             (tf->tf_eflags & ~(PSL_VIF | PSL_VIP))
596                             | (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
597                 /* see sendsig for comment */
598                 tf->tf_eflags &= ~(PSL_VM|PSL_NT|PSL_T|PSL_VIF|PSL_VIP);
599         }
600
601         /* Copy the sigframe out to the user's stack. */
602         if (copyout(&sf, fp, sizeof(struct osigframe)) != 0) {
603                 /*
604                  * Something is wrong with the stack pointer.
605                  * ...Kill the process.
606                  */
607                 sigexit(p, SIGILL);
608         }
609
610         regs->tf_esp = (int)fp;
611         regs->tf_eip = PS_STRINGS - oszsigcode;
612         regs->tf_cs = _ucodesel;
613         regs->tf_ds = _udatasel;
614         regs->tf_es = _udatasel;
615         regs->tf_fs = _udatasel;
616         load_gs(_udatasel);
617         regs->tf_ss = _udatasel;
618 }
619
620 void
621 sendsig(catcher, sig, mask, code)
622         sig_t catcher;
623         int sig;
624         sigset_t *mask;
625         u_long code;
626 {
627         struct proc *p = curproc;
628         struct trapframe *regs;
629         struct sigacts *psp = p->p_sigacts;
630         struct sigframe sf, *sfp;
631         int oonstack;
632
633         if (SIGISMEMBER(psp->ps_osigset, sig)) {
634                 osendsig(catcher, sig, mask, code);
635                 return;
636         }
637
638         regs = p->p_md.md_regs;
639         oonstack = (p->p_sigstk.ss_flags & SS_ONSTACK) ? 1 : 0;
640
641         /* save user context */
642         bzero(&sf, sizeof(struct sigframe));
643         sf.sf_uc.uc_sigmask = *mask;
644         sf.sf_uc.uc_stack = p->p_sigstk;
645         sf.sf_uc.uc_mcontext.mc_onstack = oonstack;
646         sf.sf_uc.uc_mcontext.mc_gs = rgs();
647         bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(struct trapframe));
648
649         /* Allocate and validate space for the signal handler context. */
650         if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
651             SIGISMEMBER(psp->ps_sigonstack, sig)) {
652                 sfp = (struct sigframe *)(p->p_sigstk.ss_sp +
653                     p->p_sigstk.ss_size - sizeof(struct sigframe));
654                 p->p_sigstk.ss_flags |= SS_ONSTACK;
655         }
656         else
657                 sfp = (struct sigframe *)regs->tf_esp - 1;
658
659         /*
660          * grow() will return FALSE if the sfp will not fit inside the stack
661          * and the stack can not be grown. useracc will return FALSE if
662          * access is denied.
663          */
664         if (grow_stack(p, (int)sfp) == FALSE ||
665             useracc((caddr_t)sfp, sizeof(struct sigframe), B_WRITE) == FALSE) {
666                 /*
667                  * Process has trashed its stack; give it an illegal
668                  * instruction to halt it in its tracks.
669                  */
670 #ifdef DEBUG
671                 printf("process %d has trashed its stack\n", p->p_pid);
672 #endif
673                 SIGACTION(p, SIGILL) = SIG_DFL;
674                 SIGDELSET(p->p_sigignore, SIGILL);
675                 SIGDELSET(p->p_sigcatch, SIGILL);
676                 SIGDELSET(p->p_sigmask, SIGILL);
677                 psignal(p, SIGILL);
678                 return;
679         }
680
681         /* Translate the signal is appropriate */
682         if (p->p_sysent->sv_sigtbl) {
683                 if (sig <= p->p_sysent->sv_sigsize)
684                         sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
685         }
686
687         /* Build the argument list for the signal handler. */
688         sf.sf_signum = sig;
689         sf.sf_ucontext = (register_t)&sfp->sf_uc;
690         if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
691                 /* Signal handler installed with SA_SIGINFO. */
692                 sf.sf_siginfo = (register_t)&sfp->sf_si;
693                 sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
694
695                 /* fill siginfo structure */
696                 sf.sf_si.si_signo = sig;
697                 sf.sf_si.si_code = code;
698                 sf.sf_si.si_addr = (void*)regs->tf_err;
699         }
700         else {
701                 /* Old FreeBSD-style arguments. */
702                 sf.sf_siginfo = code;
703                 sf.sf_addr = (char *)regs->tf_err;
704                 sf.sf_ahu.sf_handler = catcher;
705         }
706
707         /*
708          * If we're a vm86 process, we want to save the segment registers.
709          * We also change eflags to be our emulated eflags, not the actual
710          * eflags.
711          */
712         if (regs->tf_eflags & PSL_VM) {
713                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
714                 struct vm86_kernel *vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
715
716                 sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
717                 sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
718                 sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es;
719                 sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds;
720
721                 if (vm86->vm86_has_vme == 0)
722                         sf.sf_uc.uc_mcontext.mc_eflags =
723                             (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
724                             (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
725
726                 /*
727                  * We should never have PSL_T set when returning from vm86
728                  * mode.  It may be set here if we deliver a signal before
729                  * getting to vm86 mode, so turn it off.
730                  *
731                  * Clear PSL_NT to inhibit T_TSSFLT faults on return from
732                  * syscalls made by the signal handler.  This just avoids
733                  * wasting time for our lazy fixup of such faults.  PSL_NT
734                  * does nothing in vm86 mode, but vm86 programs can set it
735                  * almost legitimately in probes for old cpu types.
736                  */
737                 tf->tf_eflags &= ~(PSL_VM|PSL_NT|PSL_T|PSL_VIF|PSL_VIP);
738         }
739
740         /*
741          * Copy the sigframe out to the user's stack.
742          */
743         if (copyout(&sf, sfp, sizeof(struct sigframe)) != 0) {
744                 /*
745                  * Something is wrong with the stack pointer.
746                  * ...Kill the process.
747                  */
748                 sigexit(p, SIGILL);
749         }
750
751         regs->tf_esp = (int)sfp;
752         regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
753         regs->tf_cs = _ucodesel;
754         regs->tf_ds = _udatasel;
755         regs->tf_es = _udatasel;
756         regs->tf_fs = _udatasel;
757         load_gs(_udatasel);
758         regs->tf_ss = _udatasel;
759 }
760
761 /*
762  * System call to cleanup state after a signal
763  * has been taken.  Reset signal mask and
764  * stack state from context left by sendsig (above).
765  * Return to previous pc and psl as specified by
766  * context left by sendsig. Check carefully to
767  * make sure that the user has not modified the
768  * state to gain improper privileges.
769  */
770 #define EFL_SECURE(ef, oef)     ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
771 #define CS_SECURE(cs)           (ISPL(cs) == SEL_UPL)
772
773 int
774 osigreturn(p, uap)
775         struct proc *p;
776         struct osigreturn_args /* {
777                 struct osigcontext *sigcntxp;
778         } */ *uap;
779 {
780         register struct osigcontext *scp;
781         register struct trapframe *regs = p->p_md.md_regs;
782         int eflags;
783
784         scp = uap->sigcntxp;
785
786         if (useracc((caddr_t)scp, sizeof (struct osigcontext), B_WRITE) == 0)
787                 return(EFAULT);
788
789         eflags = scp->sc_ps;
790         if (eflags & PSL_VM) {
791                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
792                 struct vm86_kernel *vm86;
793
794                 /*
795                  * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
796                  * set up the vm86 area, and we can't enter vm86 mode.
797                  */
798                 if (p->p_addr->u_pcb.pcb_ext == 0)
799                         return (EINVAL);
800                 vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
801                 if (vm86->vm86_inited == 0)
802                         return (EINVAL);
803
804                 /* go back to user mode if both flags are set */
805                 if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
806                         trapsignal(p, SIGBUS, 0);
807
808                 if (vm86->vm86_has_vme) {
809                         eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
810                             (eflags & VME_USERCHANGE) | PSL_VM;
811                 } else {
812                         vm86->vm86_eflags = eflags;     /* save VIF, VIP */
813                         eflags = (tf->tf_eflags & ~VM_USERCHANGE) |                                         (eflags & VM_USERCHANGE) | PSL_VM;
814                 }
815                 tf->tf_vm86_ds = scp->sc_ds;
816                 tf->tf_vm86_es = scp->sc_es;
817                 tf->tf_vm86_fs = scp->sc_fs;
818                 tf->tf_vm86_gs = scp->sc_gs;
819                 tf->tf_ds = _udatasel;
820                 tf->tf_es = _udatasel;
821                 tf->tf_fs = _udatasel;
822         } else {
823                 /*
824                  * Don't allow users to change privileged or reserved flags.
825                  */
826                 /*
827                  * XXX do allow users to change the privileged flag PSL_RF.
828                  * The cpu sets PSL_RF in tf_eflags for faults.  Debuggers
829                  * should sometimes set it there too.  tf_eflags is kept in
830                  * the signal context during signal handling and there is no
831                  * other place to remember it, so the PSL_RF bit may be
832                  * corrupted by the signal handler without us knowing.
833                  * Corruption of the PSL_RF bit at worst causes one more or
834                  * one less debugger trap, so allowing it is fairly harmless.
835                  */
836                 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
837                         return(EINVAL);
838                 }
839
840                 /*
841                  * Don't allow users to load a valid privileged %cs.  Let the
842                  * hardware check for invalid selectors, excess privilege in
843                  * other selectors, invalid %eip's and invalid %esp's.
844                  */
845                 if (!CS_SECURE(scp->sc_cs)) {
846                         trapsignal(p, SIGBUS, T_PROTFLT);
847                         return(EINVAL);
848                 }
849                 regs->tf_ds = scp->sc_ds;
850                 regs->tf_es = scp->sc_es;
851                 regs->tf_fs = scp->sc_fs;
852         }
853
854         /* restore scratch registers */
855         regs->tf_eax = scp->sc_eax;
856         regs->tf_ebx = scp->sc_ebx;
857         regs->tf_ecx = scp->sc_ecx;
858         regs->tf_edx = scp->sc_edx;
859         regs->tf_esi = scp->sc_esi;
860         regs->tf_edi = scp->sc_edi;
861         regs->tf_cs = scp->sc_cs;
862         regs->tf_ss = scp->sc_ss;
863         regs->tf_isp = scp->sc_isp;
864
865         if (scp->sc_onstack & 01)
866                 p->p_sigstk.ss_flags |= SS_ONSTACK;
867         else
868                 p->p_sigstk.ss_flags &= ~SS_ONSTACK;
869
870         SIGSETOLD(p->p_sigmask, scp->sc_mask);
871         SIG_CANTMASK(p->p_sigmask);
872         regs->tf_ebp = scp->sc_fp;
873         regs->tf_esp = scp->sc_sp;
874         regs->tf_eip = scp->sc_pc;
875         regs->tf_eflags = eflags;
876         return(EJUSTRETURN);
877 }
878
879 int
880 sigreturn(p, uap)
881         struct proc *p;
882         struct sigreturn_args /* {
883                 ucontext_t *sigcntxp;
884         } */ *uap;
885 {
886         struct trapframe *regs;
887         ucontext_t *ucp;
888         int cs, eflags;
889
890         if (((struct osigcontext *)uap->sigcntxp)->sc_trapno == 0x01d516)
891                 return osigreturn(p, (struct osigreturn_args *)uap);
892
893         regs = p->p_md.md_regs;
894         ucp = uap->sigcntxp;
895         eflags = ucp->uc_mcontext.mc_eflags;
896
897         if (useracc((caddr_t)ucp, sizeof(ucontext_t), B_WRITE) == 0)
898                 return(EFAULT);
899
900         if (eflags & PSL_VM) {
901                 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
902                 struct vm86_kernel *vm86;
903
904                 /*
905                  * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
906                  * set up the vm86 area, and we can't enter vm86 mode.
907                  */
908                 if (p->p_addr->u_pcb.pcb_ext == 0)
909                         return (EINVAL);
910                 vm86 = &p->p_addr->u_pcb.pcb_ext->ext_vm86;
911                 if (vm86->vm86_inited == 0)
912                         return (EINVAL);
913
914                 /* go back to user mode if both flags are set */
915                 if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
916                         trapsignal(p, SIGBUS, 0);
917
918                 if (vm86->vm86_has_vme) {
919                         eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
920                             (eflags & VME_USERCHANGE) | PSL_VM;
921                 } else {
922                         vm86->vm86_eflags = eflags;     /* save VIF, VIP */
923                         eflags = (tf->tf_eflags & ~VM_USERCHANGE) |                                         (eflags & VM_USERCHANGE) | PSL_VM;
924                 }
925                 bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe));
926                 tf->tf_eflags = eflags;
927                 tf->tf_vm86_ds = tf->tf_ds;
928                 tf->tf_vm86_es = tf->tf_es;
929                 tf->tf_vm86_fs = tf->tf_fs;
930                 tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs;
931                 tf->tf_ds = _udatasel;
932                 tf->tf_es = _udatasel;
933                 tf->tf_fs = _udatasel;
934         } else {
935                 /*
936                  * Don't allow users to change privileged or reserved flags.
937                  */
938                 /*
939                  * XXX do allow users to change the privileged flag PSL_RF.
940                  * The cpu sets PSL_RF in tf_eflags for faults.  Debuggers
941                  * should sometimes set it there too.  tf_eflags is kept in
942                  * the signal context during signal handling and there is no
943                  * other place to remember it, so the PSL_RF bit may be
944                  * corrupted by the signal handler without us knowing.
945                  * Corruption of the PSL_RF bit at worst causes one more or
946                  * one less debugger trap, so allowing it is fairly harmless.
947                  */
948                 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
949                         printf("sigreturn: eflags = 0x%x\n", eflags);
950                         return(EINVAL);
951                 }
952
953                 /*
954                  * Don't allow users to load a valid privileged %cs.  Let the
955                  * hardware check for invalid selectors, excess privilege in
956                  * other selectors, invalid %eip's and invalid %esp's.
957                  */
958                 cs = ucp->uc_mcontext.mc_cs;
959                 if (!CS_SECURE(cs)) {
960                         printf("sigreturn: cs = 0x%x\n", cs);
961                         trapsignal(p, SIGBUS, T_PROTFLT);
962                         return(EINVAL);
963                 }
964                 bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(struct trapframe));
965         }
966
967         if (ucp->uc_mcontext.mc_onstack & 1)
968                 p->p_sigstk.ss_flags |= SS_ONSTACK;
969         else
970                 p->p_sigstk.ss_flags &= ~SS_ONSTACK;
971
972         p->p_sigmask = ucp->uc_sigmask;
973         SIG_CANTMASK(p->p_sigmask);
974         return(EJUSTRETURN);
975 }
976
977 /*
978  * Machine dependent boot() routine
979  *
980  * I haven't seen anything to put here yet
981  * Possibly some stuff might be grafted back here from boot()
982  */
983 void
984 cpu_boot(int howto)
985 {
986 }
987
988 /*
989  * Shutdown the CPU as much as possible
990  */
991 void
992 cpu_halt(void)
993 {
994         for (;;)
995                 __asm__ ("hlt");
996 }
997
998 /*
999  * Clear registers on exec
1000  */
1001 void
1002 setregs(p, entry, stack, ps_strings)
1003         struct proc *p;
1004         u_long entry;
1005         u_long stack;
1006         u_long ps_strings;
1007 {
1008         struct trapframe *regs = p->p_md.md_regs;
1009         struct pcb *pcb = &p->p_addr->u_pcb;
1010
1011 #ifdef USER_LDT
1012         /* was i386_user_cleanup() in NetBSD */
1013         if (pcb->pcb_ldt) {
1014                 if (pcb == curpcb) {
1015                         lldt(_default_ldt);
1016                         currentldt = _default_ldt;
1017                 }
1018                 kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
1019                         pcb->pcb_ldt_len * sizeof(union descriptor));
1020                 pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
1021         }
1022 #endif
1023   
1024         bzero((char *)regs, sizeof(struct trapframe));
1025         regs->tf_eip = entry;
1026         regs->tf_esp = stack;
1027         regs->tf_eflags = PSL_USER | (regs->tf_eflags & PSL_T);
1028         regs->tf_ss = _udatasel;
1029         regs->tf_ds = _udatasel;
1030         regs->tf_es = _udatasel;
1031         regs->tf_fs = _udatasel;
1032         regs->tf_cs = _ucodesel;
1033
1034         /* PS_STRINGS value for BSD/OS binaries.  It is 0 for non-BSD/OS. */
1035         regs->tf_ebx = ps_strings;
1036
1037         /* reset %gs as well */
1038         if (pcb == curpcb)
1039                 load_gs(_udatasel);
1040         else
1041                 pcb->pcb_gs = _udatasel;
1042
1043         /*
1044          * Initialize the math emulator (if any) for the current process.
1045          * Actually, just clear the bit that says that the emulator has
1046          * been initialized.  Initialization is delayed until the process
1047          * traps to the emulator (if it is done at all) mainly because
1048          * emulators don't provide an entry point for initialization.
1049          */
1050         p->p_addr->u_pcb.pcb_flags &= ~FP_SOFTFP;
1051
1052         /*
1053          * Arrange to trap the next npx or `fwait' instruction (see npx.c
1054          * for why fwait must be trapped at least if there is an npx or an
1055          * emulator).  This is mainly to handle the case where npx0 is not
1056          * configured, since the npx routines normally set up the trap
1057          * otherwise.  It should be done only at boot time, but doing it
1058          * here allows modifying `npx_exists' for testing the emulator on
1059          * systems with an npx.
1060          */
1061         load_cr0(rcr0() | CR0_MP | CR0_TS);
1062
1063 #if NNPX > 0
1064         /* Initialize the npx (if any) for the current process. */
1065         npxinit(__INITIAL_NPXCW__);
1066 #endif
1067
1068       /*
1069        * XXX - Linux emulator
1070        * Make sure sure edx is 0x0 on entry. Linux binaries depend
1071        * on it.
1072        */
1073       p->p_retval[1] = 0;
1074 }
1075
1076 static int
1077 sysctl_machdep_adjkerntz SYSCTL_HANDLER_ARGS
1078 {
1079         int error;
1080         error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2,
1081                 req);
1082         if (!error && req->newptr)
1083                 resettodr();
1084         return (error);
1085 }
1086
1087 SYSCTL_PROC(_machdep, CPU_ADJKERNTZ, adjkerntz, CTLTYPE_INT|CTLFLAG_RW,
1088         &adjkerntz, 0, sysctl_machdep_adjkerntz, "I", "");
1089
1090 SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set,
1091         CTLFLAG_RW, &disable_rtc_set, 0, "");
1092
1093 SYSCTL_STRUCT(_machdep, CPU_BOOTINFO, bootinfo, 
1094         CTLFLAG_RD, &bootinfo, bootinfo, "");
1095
1096 SYSCTL_INT(_machdep, CPU_WALLCLOCK, wall_cmos_clock,
1097         CTLFLAG_RW, &wall_cmos_clock, 0, "");
1098
1099 /*
1100  * Initialize 386 and configure to run kernel
1101  */
1102
1103 /*
1104  * Initialize segments & interrupt table
1105  */
1106
1107 int _default_ldt;
1108 #ifdef SMP
1109 union descriptor gdt[NGDT * NCPU];      /* global descriptor table */
1110 #else
1111 union descriptor gdt[NGDT];             /* global descriptor table */
1112 #endif
1113 static struct gate_descriptor idt0[NIDT];
1114 struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */
1115 union descriptor ldt[NLDT];             /* local descriptor table */
1116 #ifdef SMP
1117 /* table descriptors - used to load tables by microp */
1118 struct region_descriptor r_gdt, r_idt;
1119 #endif
1120
1121 #ifndef SMP
1122 extern struct segment_descriptor common_tssd, *tss_gdt;
1123 #endif
1124 int private_tss;                        /* flag indicating private tss */
1125
1126 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
1127 extern int has_f00f_bug;
1128 #endif
1129
1130 static struct i386tss dblfault_tss;
1131 static char dblfault_stack[PAGE_SIZE];
1132
1133 extern  struct user *proc0paddr;
1134
1135
1136 /* software prototypes -- in more palatable form */
1137 struct soft_segment_descriptor gdt_segs[] = {
1138 /* GNULL_SEL    0 Null Descriptor */
1139 {       0x0,                    /* segment base address  */
1140         0x0,                    /* length */
1141         0,                      /* segment type */
1142         0,                      /* segment descriptor priority level */
1143         0,                      /* segment descriptor present */
1144         0, 0,
1145         0,                      /* default 32 vs 16 bit size */
1146         0                       /* limit granularity (byte/page units)*/ },
1147 /* GCODE_SEL    1 Code Descriptor for kernel */
1148 {       0x0,                    /* segment base address  */
1149         0xfffff,                /* length - all address space */
1150         SDT_MEMERA,             /* segment type */
1151         0,                      /* segment descriptor priority level */
1152         1,                      /* segment descriptor present */
1153         0, 0,
1154         1,                      /* default 32 vs 16 bit size */
1155         1                       /* limit granularity (byte/page units)*/ },
1156 /* GDATA_SEL    2 Data Descriptor for kernel */
1157 {       0x0,                    /* segment base address  */
1158         0xfffff,                /* length - all address space */
1159         SDT_MEMRWA,             /* segment type */
1160         0,                      /* segment descriptor priority level */
1161         1,                      /* segment descriptor present */
1162         0, 0,
1163         1,                      /* default 32 vs 16 bit size */
1164         1                       /* limit granularity (byte/page units)*/ },
1165 /* GPRIV_SEL    3 SMP Per-Processor Private Data Descriptor */
1166 {       0x0,                    /* segment base address  */
1167         0xfffff,                /* length - all address space */
1168         SDT_MEMRWA,             /* segment type */
1169         0,                      /* segment descriptor priority level */
1170         1,                      /* segment descriptor present */
1171         0, 0,
1172         1,                      /* default 32 vs 16 bit size */
1173         1                       /* limit granularity (byte/page units)*/ },
1174 /* GPROC0_SEL   4 Proc 0 Tss Descriptor */
1175 {
1176         0x0,                    /* segment base address */
1177         sizeof(struct i386tss)-1,/* length - all address space */
1178         SDT_SYS386TSS,          /* segment type */
1179         0,                      /* segment descriptor priority level */
1180         1,                      /* segment descriptor present */
1181         0, 0,
1182         0,                      /* unused - default 32 vs 16 bit size */
1183         0                       /* limit granularity (byte/page units)*/ },
1184 /* GLDT_SEL     5 LDT Descriptor */
1185 {       (int) ldt,              /* segment base address  */
1186         sizeof(ldt)-1,          /* length - all address space */
1187         SDT_SYSLDT,             /* segment type */
1188         SEL_UPL,                /* segment descriptor priority level */
1189         1,                      /* segment descriptor present */
1190         0, 0,
1191         0,                      /* unused - default 32 vs 16 bit size */
1192         0                       /* limit granularity (byte/page units)*/ },
1193 /* GUSERLDT_SEL 6 User LDT Descriptor per process */
1194 {       (int) ldt,              /* segment base address  */
1195         (512 * sizeof(union descriptor)-1),             /* length */
1196         SDT_SYSLDT,             /* segment type */
1197         0,                      /* segment descriptor priority level */
1198         1,                      /* segment descriptor present */
1199         0, 0,
1200         0,                      /* unused - default 32 vs 16 bit size */
1201         0                       /* limit granularity (byte/page units)*/ },
1202 /* GTGATE_SEL   7 Null Descriptor - Placeholder */
1203 {       0x0,                    /* segment base address  */
1204         0x0,                    /* length - all address space */
1205         0,                      /* segment type */
1206         0,                      /* segment descriptor priority level */
1207         0,                      /* segment descriptor present */
1208         0, 0,
1209         0,                      /* default 32 vs 16 bit size */
1210         0                       /* limit granularity (byte/page units)*/ },
1211 /* GBIOSLOWMEM_SEL 8 BIOS access to realmode segment 0x40, must be #8 in GDT */
1212 {       0x400,                  /* segment base address */
1213         0xfffff,                /* length */
1214         SDT_MEMRWA,             /* segment type */
1215         0,                      /* segment descriptor priority level */
1216         1,                      /* segment descriptor present */
1217         0, 0,
1218         1,                      /* default 32 vs 16 bit size */
1219         1                       /* limit granularity (byte/page units)*/ },
1220 /* GPANIC_SEL   9 Panic Tss Descriptor */
1221 {       (int) &dblfault_tss,    /* segment base address  */
1222         sizeof(struct i386tss)-1,/* length - all address space */
1223         SDT_SYS386TSS,          /* segment type */
1224         0,                      /* segment descriptor priority level */
1225         1,                      /* segment descriptor present */
1226         0, 0,
1227         0,                      /* unused - default 32 vs 16 bit size */
1228         0                       /* limit granularity (byte/page units)*/ },
1229 /* GBIOSCODE32_SEL 10 BIOS 32-bit interface (32bit Code) */
1230 {       0,                      /* segment base address (overwritten)  */
1231         0xfffff,                /* length */
1232         SDT_MEMERA,             /* segment type */
1233         0,                      /* segment descriptor priority level */
1234         1,                      /* segment descriptor present */
1235         0, 0,
1236         0,                      /* default 32 vs 16 bit size */
1237         1                       /* limit granularity (byte/page units)*/ },
1238 /* GBIOSCODE16_SEL 11 BIOS 32-bit interface (16bit Code) */
1239 {       0,                      /* segment base address (overwritten)  */
1240         0xfffff,                /* length */
1241         SDT_MEMERA,             /* segment type */
1242         0,                      /* segment descriptor priority level */
1243         1,                      /* segment descriptor present */
1244         0, 0,
1245         0,                      /* default 32 vs 16 bit size */
1246         1                       /* limit granularity (byte/page units)*/ },
1247 /* GBIOSDATA_SEL 12 BIOS 32-bit interface (Data) */
1248 {       0,                      /* segment base address (overwritten) */
1249         0xfffff,                /* length */
1250         SDT_MEMRWA,             /* segment type */
1251         0,                      /* segment descriptor priority level */
1252         1,                      /* segment descriptor present */
1253         0, 0,
1254         1,                      /* default 32 vs 16 bit size */
1255         1                       /* limit granularity (byte/page units)*/ },
1256 /* GBIOSUTIL_SEL 13 BIOS 16-bit interface (Utility) */
1257 {       0,                      /* segment base address (overwritten) */
1258         0xfffff,                /* length */
1259         SDT_MEMRWA,             /* segment type */
1260         0,                      /* segment descriptor priority level */
1261         1,                      /* segment descriptor present */
1262         0, 0,
1263         0,                      /* default 32 vs 16 bit size */
1264         1                       /* limit granularity (byte/page units)*/ },
1265 /* GBIOSARGS_SEL 14 BIOS 16-bit interface (Arguments) */
1266 {       0,                      /* segment base address (overwritten) */
1267         0xfffff,                /* length */
1268         SDT_MEMRWA,             /* segment type */
1269         0,                      /* segment descriptor priority level */
1270         1,                      /* segment descriptor present */
1271         0, 0,
1272         0,                      /* default 32 vs 16 bit size */
1273         1                       /* limit granularity (byte/page units)*/ },
1274 };
1275
1276 static struct soft_segment_descriptor ldt_segs[] = {
1277         /* Null Descriptor - overwritten by call gate */
1278 {       0x0,                    /* segment base address  */
1279         0x0,                    /* length - all address space */
1280         0,                      /* segment type */
1281         0,                      /* segment descriptor priority level */
1282         0,                      /* segment descriptor present */
1283         0, 0,
1284         0,                      /* default 32 vs 16 bit size */
1285         0                       /* limit granularity (byte/page units)*/ },
1286         /* Null Descriptor - overwritten by call gate */
1287 {       0x0,                    /* segment base address  */
1288         0x0,                    /* length - all address space */
1289         0,                      /* segment type */
1290         0,                      /* segment descriptor priority level */
1291         0,                      /* segment descriptor present */
1292         0, 0,
1293         0,                      /* default 32 vs 16 bit size */
1294         0                       /* limit granularity (byte/page units)*/ },
1295         /* Null Descriptor - overwritten by call gate */
1296 {       0x0,                    /* segment base address  */
1297         0x0,                    /* length - all address space */
1298         0,                      /* segment type */
1299         0,                      /* segment descriptor priority level */
1300         0,                      /* segment descriptor present */
1301         0, 0,
1302         0,                      /* default 32 vs 16 bit size */
1303         0                       /* limit granularity (byte/page units)*/ },
1304         /* Code Descriptor for user */
1305 {       0x0,                    /* segment base address  */
1306         0xfffff,                /* length - all address space */
1307         SDT_MEMERA,             /* segment type */
1308         SEL_UPL,                /* segment descriptor priority level */
1309         1,                      /* segment descriptor present */
1310         0, 0,
1311         1,                      /* default 32 vs 16 bit size */
1312         1                       /* limit granularity (byte/page units)*/ },
1313         /* Null Descriptor - overwritten by call gate */
1314 {       0x0,                    /* segment base address  */
1315         0x0,                    /* length - all address space */
1316         0,                      /* segment type */
1317         0,                      /* segment descriptor priority level */
1318         0,                      /* segment descriptor present */
1319         0, 0,
1320         0,                      /* default 32 vs 16 bit size */
1321         0                       /* limit granularity (byte/page units)*/ },
1322         /* Data Descriptor for user */
1323 {       0x0,                    /* segment base address  */
1324         0xfffff,                /* length - all address space */
1325         SDT_MEMRWA,             /* segment type */
1326         SEL_UPL,                /* segment descriptor priority level */
1327         1,                      /* segment descriptor present */
1328         0, 0,
1329         1,                      /* default 32 vs 16 bit size */
1330         1                       /* limit granularity (byte/page units)*/ },
1331 };
1332
1333 void
1334 setidt(idx, func, typ, dpl, selec)
1335         int idx;
1336         inthand_t *func;
1337         int typ;
1338         int dpl;
1339         int selec;
1340 {
1341         struct gate_descriptor *ip;
1342
1343         ip = idt + idx;
1344         ip->gd_looffset = (int)func;
1345         ip->gd_selector = selec;
1346         ip->gd_stkcpy = 0;
1347         ip->gd_xx = 0;
1348         ip->gd_type = typ;
1349         ip->gd_dpl = dpl;
1350         ip->gd_p = 1;
1351         ip->gd_hioffset = ((int)func)>>16 ;
1352 }
1353
1354 #define IDTVEC(name)    __CONCAT(X,name)
1355
1356 extern inthand_t
1357         IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl),
1358         IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm),
1359         IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
1360         IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align),
1361         IDTVEC(syscall), IDTVEC(int0x80_syscall);
1362
1363 void
1364 sdtossd(sd, ssd)
1365         struct segment_descriptor *sd;
1366         struct soft_segment_descriptor *ssd;
1367 {
1368         ssd->ssd_base  = (sd->sd_hibase << 24) | sd->sd_lobase;
1369         ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit;
1370         ssd->ssd_type  = sd->sd_type;
1371         ssd->ssd_dpl   = sd->sd_dpl;
1372         ssd->ssd_p     = sd->sd_p;
1373         ssd->ssd_def32 = sd->sd_def32;
1374         ssd->ssd_gran  = sd->sd_gran;
1375 }
1376
1377 #define PHYSMAP_SIZE    (2 * 8)
1378
1379 /*
1380  * Populate the (physmap) array with base/bound pairs describing the
1381  * available physical memory in the system, then test this memory and
1382  * build the phys_avail array describing the actually-available memory.
1383  *
1384  * If we cannot accurately determine the physical memory map, then use
1385  * value from the 0xE801 call, and failing that, the RTC.
1386  *
1387  * Total memory size may be set by the kernel environment variable
1388  * hw.physmem or the compile-time define MAXMEM.
1389  */
1390 static void
1391 getmemsize_pc98(int first)
1392 {
1393         u_int   biosbasemem, biosextmem;
1394         u_int   pagesinbase, pagesinext;
1395         int     pa_indx;
1396         int     speculative_mprobe;
1397 #if     NNPX > 0
1398         int     msize;
1399 #endif
1400         vm_offset_t     target_page;
1401
1402         pc98_getmemsize();
1403         biosbasemem = 640;                      /* 640KB */
1404         biosextmem = (Maxmem * PAGE_SIZE - 0x100000)/1024;   /* extent memory */
1405
1406 #ifdef SMP
1407         /* make hole for AP bootstrap code */
1408         pagesinbase = mp_bootaddress(biosbasemem) / PAGE_SIZE;
1409 #else
1410         pagesinbase = biosbasemem * 1024 / PAGE_SIZE;
1411 #endif
1412
1413         pagesinext = biosextmem * 1024 / PAGE_SIZE;
1414
1415         /*
1416          * Maxmem isn't the "maximum memory", it's one larger than the
1417          * highest page of the physical address space.  It should be
1418          * called something like "Maxphyspage".
1419          */
1420         Maxmem = pagesinext + 0x100000/PAGE_SIZE;
1421         /*
1422          * Indicate that we wish to do a speculative search for memory beyond
1423          * the end of the reported size if the indicated amount is 64MB (0x4000
1424          * pages) - which is the largest amount that the BIOS/bootblocks can
1425          * currently report. If a specific amount of memory is indicated via
1426          * the MAXMEM option or the npx0 "msize", then don't do the speculative
1427          * memory probe.
1428          */
1429         if (Maxmem >= 0x4000)
1430                 speculative_mprobe = TRUE;
1431         else
1432                 speculative_mprobe = FALSE;
1433
1434 #ifdef MAXMEM
1435         Maxmem = MAXMEM/4;
1436         speculative_mprobe = FALSE;
1437 #endif
1438
1439 #if NNPX > 0
1440         if (resource_int_value("npx", 0, "msize", &msize) == 0) {
1441                 if (msize != 0) {
1442                         Maxmem = msize / 4;
1443                         speculative_mprobe = FALSE;
1444                 }
1445         }
1446 #endif
1447
1448 #ifdef SMP
1449         /* look for the MP hardware - needed for apic addresses */
1450         mp_probe();
1451 #endif
1452
1453         /* call pmap initialization to make new kernel address space */
1454         pmap_bootstrap (first, 0);
1455
1456         /*
1457          * Size up each available chunk of physical memory.
1458          */
1459
1460         /*
1461          * We currently don't bother testing base memory.
1462          * XXX  ...but we probably should.
1463          */
1464         pa_indx = 0;
1465         if (pagesinbase > 1) {
1466                 phys_avail[pa_indx++] = PAGE_SIZE;      /* skip first page of memory */
1467                 phys_avail[pa_indx] = ptoa(pagesinbase);/* memory up to the ISA hole */
1468                 physmem = pagesinbase - 1;
1469         } else {
1470                 /* point at first chunk end */
1471                 pa_indx++;
1472         }
1473
1474         for (target_page = avail_start; target_page < ptoa(Maxmem); target_page += PAGE_SIZE) {
1475                 int tmp, page_bad;
1476
1477                 page_bad = FALSE;
1478                 /* skip system area */
1479                 if (target_page>=ptoa(Maxmem_under16M) &&
1480                                 target_page < ptoa(4096))
1481                         page_bad = TRUE;
1482                 /*
1483                  * map page into kernel: valid, read/write, non-cacheable
1484                  */
1485                 if (pc98_machine_type & M_EPSON_PC98) {
1486                         switch (epson_machine_id) {
1487                         case 0x34:                              /* PC-486HX */
1488                         case 0x35:                              /* PC-486HG */
1489                         case 0x3B:                              /* PC-486HA */
1490                                 *(int *)CMAP1 = PG_V | PG_RW | target_page;
1491                                 break;
1492                         default:
1493 #ifdef WB_CACHE
1494                                 *(int *)CMAP1 = PG_V | PG_RW | target_page;
1495 #else
1496                                 *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
1497 #endif
1498                                 break;
1499                         }
1500                 } else {
1501                 *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
1502                 }
1503                 invltlb();
1504
1505                 tmp = *(int *)CADDR1;
1506                 /*
1507                  * Test for alternating 1's and 0's
1508                  */
1509                 *(volatile int *)CADDR1 = 0xaaaaaaaa;
1510                 if (*(volatile int *)CADDR1 != 0xaaaaaaaa) {
1511                         page_bad = TRUE;
1512                 }
1513                 /*
1514                  * Test for alternating 0's and 1's
1515                  */
1516                 *(volatile int *)CADDR1 = 0x55555555;
1517                 if (*(volatile int *)CADDR1 != 0x55555555) {
1518                         page_bad = TRUE;
1519                 }
1520                 /*
1521                  * Test for all 1's
1522                  */
1523                 *(volatile int *)CADDR1 = 0xffffffff;
1524                 if (*(volatile int *)CADDR1 != 0xffffffff) {
1525                         page_bad = TRUE;
1526                 }
1527                 /*
1528                  * Test for all 0's
1529                  */
1530                 *(volatile int *)CADDR1 = 0x0;
1531                 if (*(volatile int *)CADDR1 != 0x0) {
1532                         /*
1533                          * test of page failed
1534                          */
1535                         page_bad = TRUE;
1536                 }
1537                 /*
1538                  * Restore original value.
1539                  */
1540                 *(int *)CADDR1 = tmp;
1541
1542                 /*
1543                  * Adjust array of valid/good pages.
1544                  */
1545                 if (page_bad == FALSE) {
1546                         /*
1547                          * If this good page is a continuation of the
1548                          * previous set of good pages, then just increase
1549                          * the end pointer. Otherwise start a new chunk.
1550                          * Note that "end" points one higher than end,
1551                          * making the range >= start and < end.
1552                          * If we're also doing a speculative memory
1553                          * test and we at or past the end, bump up Maxmem
1554                          * so that we keep going. The first bad page
1555                          * will terminate the loop.
1556                          */
1557                         if (phys_avail[pa_indx] == target_page) {
1558                                 phys_avail[pa_indx] += PAGE_SIZE;
1559                                 if (speculative_mprobe == TRUE &&
1560                                     phys_avail[pa_indx] >= (64*1024*1024))
1561                                         Maxmem++;
1562                         } else {
1563                                 pa_indx++;
1564                                 if (pa_indx == PHYS_AVAIL_ARRAY_END) {
1565                                         printf("Too many holes in the physical address space, giving up\n");
1566                                         pa_indx--;
1567                                         break;
1568                                 }
1569                                 phys_avail[pa_indx++] = target_page;    /* start */
1570                                 phys_avail[pa_indx] = target_page + PAGE_SIZE;  /* end */
1571                         }
1572                         physmem++;
1573                 }
1574         }
1575
1576         *(int *)CMAP1 = 0;
1577         invltlb();
1578
1579         /*
1580          * XXX
1581          * The last chunk must contain at least one page plus the message
1582          * buffer to avoid complicating other code (message buffer address
1583          * calculation, etc.).
1584          */
1585         while (phys_avail[pa_indx - 1] + PAGE_SIZE +
1586             round_page(MSGBUF_SIZE) >= phys_avail[pa_indx]) {
1587                 physmem -= atop(phys_avail[pa_indx] - phys_avail[pa_indx - 1]);
1588                 phys_avail[pa_indx--] = 0;
1589                 phys_avail[pa_indx--] = 0;
1590         }
1591
1592         Maxmem = atop(phys_avail[pa_indx]);
1593
1594         /* Trim off space for the message buffer. */
1595         phys_avail[pa_indx] -= round_page(MSGBUF_SIZE);
1596
1597         avail_end = phys_avail[pa_indx];
1598 }
1599
1600 #ifndef PC98
1601 static void
1602 getmemsize(int first)
1603 {
1604         int i, physmap_idx, pa_indx;
1605         u_int basemem, extmem;
1606         struct vm86frame vmf;
1607         struct vm86context vmc;
1608         vm_offset_t pa, physmap[PHYSMAP_SIZE];
1609         pt_entry_t pte;
1610         const char *cp;
1611         struct {
1612                 u_int64_t base;
1613                 u_int64_t length;
1614                 u_int32_t type;
1615         } *smap;
1616
1617         bzero(&vmf, sizeof(struct vm86frame));
1618         bzero(physmap, sizeof(physmap));
1619
1620         /*
1621          * Perform "base memory" related probes & setup
1622          */
1623         vm86_intcall(0x12, &vmf);
1624         basemem = vmf.vmf_ax;
1625         if (basemem > 640) {
1626                 printf("Preposterous BIOS basemem of %uK, truncating to 640K\n",
1627                         basemem);
1628                 basemem = 640;
1629         }
1630
1631         /*
1632          * XXX if biosbasemem is now < 640, there is a `hole'
1633          * between the end of base memory and the start of
1634          * ISA memory.  The hole may be empty or it may
1635          * contain BIOS code or data.  Map it read/write so
1636          * that the BIOS can write to it.  (Memory from 0 to
1637          * the physical end of the kernel is mapped read-only
1638          * to begin with and then parts of it are remapped.
1639          * The parts that aren't remapped form holes that
1640          * remain read-only and are unused by the kernel.
1641          * The base memory area is below the physical end of
1642          * the kernel and right now forms a read-only hole.
1643          * The part of it from PAGE_SIZE to
1644          * (trunc_page(biosbasemem * 1024) - 1) will be
1645          * remapped and used by the kernel later.)
1646          *
1647          * This code is similar to the code used in
1648          * pmap_mapdev, but since no memory needs to be
1649          * allocated we simply change the mapping.
1650          */
1651         for (pa = trunc_page(basemem * 1024);
1652              pa < ISA_HOLE_START; pa += PAGE_SIZE) {
1653                 pte = (pt_entry_t)vtopte(pa + KERNBASE);
1654                 *pte = pa | PG_RW | PG_V;
1655         }
1656
1657         /*
1658          * if basemem != 640, map pages r/w into vm86 page table so 
1659          * that the bios can scribble on it.
1660          */
1661         pte = (pt_entry_t)vm86paddr;
1662         for (i = basemem / 4; i < 160; i++)
1663                 pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U;
1664
1665         /*
1666          * map page 1 R/W into the kernel page table so we can use it
1667          * as a buffer.  The kernel will unmap this page later.
1668          */
1669         pte = (pt_entry_t)vtopte(KERNBASE + (1 << PAGE_SHIFT));
1670         *pte = (1 << PAGE_SHIFT) | PG_RW | PG_V;
1671
1672         extmem = (Maxmem * PAGE_SIZE - 0x100000)/1024;   /* extent memory */
1673         /*
1674          * get memory map with INT 15:E820
1675          */
1676 #define SMAPSIZ         sizeof(*smap)
1677 #define SMAP_SIG        0x534D4150                      /* 'SMAP' */
1678
1679         vmc.npages = 0;
1680         smap = (void *)vm86_addpage(&vmc, 1, KERNBASE + (1 << PAGE_SHIFT));
1681         vm86_getptr(&vmc, (vm_offset_t)smap, &vmf.vmf_es, &vmf.vmf_di);
1682
1683         physmap_idx = 0;
1684         vmf.vmf_ebx = 0;
1685         do {
1686                 vmf.vmf_eax = 0xE820;
1687                 vmf.vmf_edx = SMAP_SIG;
1688                 vmf.vmf_ecx = SMAPSIZ;
1689                 i = vm86_datacall(0x15, &vmf, &vmc);
1690                 if (i || vmf.vmf_eax != SMAP_SIG)
1691                         break;
1692                 if (boothowto & RB_VERBOSE)
1693                         printf("SMAP type=%02x base=%08x %08x len=%08x %08x\n",
1694                                 smap->type,
1695                                 *(u_int32_t *)((char *)&smap->base + 4),
1696                                 (u_int32_t)smap->base,
1697                                 *(u_int32_t *)((char *)&smap->length + 4),
1698                                 (u_int32_t)smap->length);
1699
1700                 if (smap->type != 0x01)
1701                         goto next_run;
1702
1703                 if (smap->length == 0)
1704                         goto next_run;
1705
1706                 if (smap->base >= 0xffffffff) {
1707                         printf("%uK of memory above 4GB ignored\n",
1708                             (u_int)(smap->length / 1024));
1709                         goto next_run;
1710                 }
1711
1712                 for (i = 0; i <= physmap_idx; i += 2) {
1713                         if (smap->base < physmap[i + 1]) {
1714                                 if (boothowto & RB_VERBOSE)
1715                                         printf(
1716         "Overlapping or non-montonic memory region, ignoring second region\n");
1717                                 goto next_run;
1718                         }
1719                 }
1720
1721                 if (smap->base == physmap[physmap_idx + 1]) {
1722                         physmap[physmap_idx + 1] += smap->length;
1723                         goto next_run;
1724                 }
1725
1726                 physmap_idx += 2;
1727                 if (physmap_idx == PHYSMAP_SIZE) {
1728                         printf(
1729                 "Too many segments in the physical address map, giving up\n");
1730                         break;
1731                 }
1732                 physmap[physmap_idx] = smap->base;
1733                 physmap[physmap_idx + 1] = smap->base + smap->length;
1734 next_run:
1735         } while (vmf.vmf_ebx != 0);
1736
1737         if (physmap[1] != 0)
1738                 goto physmap_done;
1739
1740         /*
1741          * If we failed above, try memory map with INT 15:E801
1742          */
1743         vmf.vmf_ax = 0xE801;
1744         if (vm86_intcall(0x15, &vmf) == 0) {
1745                 extmem = vmf.vmf_cx + vmf.vmf_dx * 64;
1746         } else {
1747 #if 0
1748                 vmf.vmf_ah = 0x88;
1749                 vm86_intcall(0x15, &vmf);
1750                 extmem = vmf.vmf_ax;
1751 #else
1752                 /*
1753                  * Prefer the RTC value for extended memory.
1754                  */
1755                 extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8);
1756 #endif
1757         }
1758
1759         /*
1760          * Special hack for chipsets that still remap the 384k hole when
1761          * there's 16MB of memory - this really confuses people that
1762          * are trying to use bus mastering ISA controllers with the
1763          * "16MB limit"; they only have 16MB, but the remapping puts
1764          * them beyond the limit.
1765          *
1766          * If extended memory is between 15-16MB (16-17MB phys address range),
1767          *      chop it to 15MB.
1768          */
1769         if ((extmem > 15 * 1024) && (extmem < 16 * 1024))
1770                 extmem = 15 * 1024;
1771
1772         physmap[0] = 0;
1773         physmap[1] = basemem * 1024;
1774         physmap_idx = 2;
1775         physmap[physmap_idx] = 0x100000;
1776         physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
1777
1778 physmap_done:
1779         /*
1780          * Now, physmap contains a map of physical memory.
1781          */
1782
1783 #ifdef SMP
1784         /* make hole for AP bootstrap code */
1785         physmap[1] = mp_bootaddress(physmap[1] / 1024);
1786
1787         /* look for the MP hardware - needed for apic addresses */
1788         mp_probe();
1789 #endif
1790
1791         /*
1792          * Maxmem isn't the "maximum memory", it's one larger than the
1793          * highest page of the physical address space.  It should be
1794          * called something like "Maxphyspage".  We may adjust this 
1795          * based on ``hw.physmem'' and the results of the memory test.
1796          */
1797         Maxmem = atop(physmap[physmap_idx + 1]);
1798
1799 #ifdef MAXMEM
1800         Maxmem = MAXMEM / 4;
1801 #endif
1802
1803         /*
1804          * hw.maxmem is a size in bytes; we also allow k, m, and g suffixes
1805          * for the appropriate modifiers.  This overrides MAXMEM.
1806          */
1807         if ((cp = getenv("hw.physmem")) != NULL) {
1808                 u_int64_t AllowMem, sanity;
1809                 const char *ep;
1810
1811                 sanity = AllowMem = strtouq(cp, &ep, 0);
1812                 if ((ep != cp) && (*ep != 0)) {
1813                         switch(*ep) {
1814                         case 'g':
1815                         case 'G':
1816                                 AllowMem <<= 10;
1817                         case 'm':
1818                         case 'M':
1819                                 AllowMem <<= 10;
1820                         case 'k':
1821                         case 'K':
1822                                 AllowMem <<= 10;
1823                                 break;
1824                         default:
1825                                 AllowMem = sanity = 0;
1826                         }
1827                         if (AllowMem < sanity)
1828                                 AllowMem = 0;
1829                 }
1830                 if (AllowMem == 0)
1831                         printf("Ignoring invalid memory size of '%s'\n", cp);
1832                 else
1833                         Maxmem = atop(AllowMem);
1834         }
1835
1836         if (atop(physmap[physmap_idx + 1]) != Maxmem &&
1837             (boothowto & RB_VERBOSE))
1838                 printf("Physical memory use set to %uK\n", Maxmem * 4);
1839
1840         /*
1841          * If Maxmem has been increased beyond what the system has detected,
1842          * extend the last memory segment to the new limit.
1843          */ 
1844         if (atop(physmap[physmap_idx + 1]) < Maxmem)
1845                 physmap[physmap_idx + 1] = ptoa(Maxmem);
1846
1847         /* call pmap initialization to make new kernel address space */
1848         pmap_bootstrap(first, 0);
1849
1850         /*
1851          * Size up each available chunk of physical memory.
1852          */
1853         physmap[0] = PAGE_SIZE;         /* mask off page 0 */
1854         pa_indx = 0;
1855         phys_avail[pa_indx++] = physmap[0];
1856         phys_avail[pa_indx] = physmap[0];
1857 #if 0
1858         pte = (pt_entry_t)vtopte(KERNBASE);
1859 #else
1860         pte = (pt_entry_t)CMAP1;
1861 #endif
1862
1863         /*
1864          * physmap is in bytes, so when converting to page boundaries,
1865          * round up the start address and round down the end address.
1866          */
1867         for (i = 0; i <= physmap_idx; i += 2) {
1868                 vm_offset_t end;
1869
1870                 end = ptoa(Maxmem);
1871                 if (physmap[i + 1] < end)
1872                         end = trunc_page(physmap[i + 1]);
1873                 for (pa = round_page(physmap[i]); pa < end; pa += PAGE_SIZE) {
1874                         int tmp, page_bad;
1875 #if 0
1876                         int *ptr = 0;
1877 #else
1878                         int *ptr = (int *)CADDR1;
1879 #endif
1880
1881                         /*
1882                          * block out kernel memory as not available.
1883                          */
1884                         if (pa >= 0x100000 && pa < first)
1885                                 continue;
1886         
1887                         page_bad = FALSE;
1888
1889                         /*
1890                          * map page into kernel: valid, read/write,non-cacheable
1891                          */
1892                         *pte = pa | PG_V | PG_RW | PG_N;
1893                         invltlb();
1894
1895                         tmp = *(int *)ptr;
1896                         /*
1897                          * Test for alternating 1's and 0's
1898                          */
1899                         *(volatile int *)ptr = 0xaaaaaaaa;
1900                         if (*(volatile int *)ptr != 0xaaaaaaaa) {
1901                                 page_bad = TRUE;
1902                         }
1903                         /*
1904                          * Test for alternating 0's and 1's
1905                          */
1906                         *(volatile int *)ptr = 0x55555555;
1907                         if (*(volatile int *)ptr != 0x55555555) {
1908                         page_bad = TRUE;
1909                         }
1910                         /*
1911                          * Test for all 1's
1912                          */
1913                         *(volatile int *)ptr = 0xffffffff;
1914                         if (*(volatile int *)ptr != 0xffffffff) {
1915                                 page_bad = TRUE;
1916                         }
1917                         /*
1918                          * Test for all 0's
1919                          */
1920                         *(volatile int *)ptr = 0x0;
1921                         if (*(volatile int *)ptr != 0x0) {
1922                                 page_bad = TRUE;
1923                         }
1924                         /*
1925                          * Restore original value.
1926                          */
1927                         *(int *)ptr = tmp;
1928
1929                         /*
1930                          * Adjust array of valid/good pages.
1931                          */
1932                         if (page_bad == TRUE) {
1933                                 continue;
1934                         }
1935                         /*
1936                          * If this good page is a continuation of the
1937                          * previous set of good pages, then just increase
1938                          * the end pointer. Otherwise start a new chunk.
1939                          * Note that "end" points one higher than end,
1940                          * making the range >= start and < end.
1941                          * If we're also doing a speculative memory
1942                          * test and we at or past the end, bump up Maxmem
1943                          * so that we keep going. The first bad page
1944                          * will terminate the loop.
1945                          */
1946                         if (phys_avail[pa_indx] == pa) {
1947                                 phys_avail[pa_indx] += PAGE_SIZE;
1948                         } else {
1949                                 pa_indx++;
1950                                 if (pa_indx == PHYS_AVAIL_ARRAY_END) {
1951                                         printf("Too many holes in the physical address space, giving up\n");
1952                                         pa_indx--;
1953                                         break;
1954                                 }
1955                                 phys_avail[pa_indx++] = pa;     /* start */
1956                                 phys_avail[pa_indx] = pa + PAGE_SIZE;   /* end */
1957                         }
1958                         physmem++;
1959                 }
1960         }
1961         *pte = 0;
1962         invltlb();
1963
1964         /*
1965          * XXX
1966          * The last chunk must contain at least one page plus the message
1967          * buffer to avoid complicating other code (message buffer address
1968          * calculation, etc.).
1969          */
1970         while (phys_avail[pa_indx - 1] + PAGE_SIZE +
1971             round_page(MSGBUF_SIZE) >= phys_avail[pa_indx]) {
1972                 physmem -= atop(phys_avail[pa_indx] - phys_avail[pa_indx - 1]);
1973                 phys_avail[pa_indx--] = 0;
1974                 phys_avail[pa_indx--] = 0;
1975         }
1976
1977         Maxmem = atop(phys_avail[pa_indx]);
1978
1979         /* Trim off space for the message buffer. */
1980         phys_avail[pa_indx] -= round_page(MSGBUF_SIZE);
1981
1982         avail_end = phys_avail[pa_indx];
1983 }
1984 #endif
1985
1986 void
1987 init386(first)
1988         int first;
1989 {
1990         int x;
1991         struct gate_descriptor *gdp;
1992         int gsel_tss;
1993 #ifndef SMP
1994         /* table descriptors - used to load tables by microp */
1995         struct region_descriptor r_gdt, r_idt;
1996 #endif
1997         int off;
1998
1999         /*
2000          * Prevent lowering of the ipl if we call tsleep() early.
2001          */
2002         safepri = cpl;
2003
2004         proc0.p_addr = proc0paddr;
2005
2006         atdevbase = ISA_HOLE_START + KERNBASE;
2007
2008 #ifdef PC98
2009         /*
2010          * Initialize DMAC
2011          */
2012         pc98_init_dmac();
2013 #endif
2014
2015         if (bootinfo.bi_modulep) {
2016                 preload_metadata = (caddr_t)bootinfo.bi_modulep + KERNBASE;
2017                 preload_bootstrap_relocate(KERNBASE);
2018         }
2019         if (bootinfo.bi_envp)
2020                 kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE;
2021
2022         /*
2023          * make gdt memory segments, the code segment goes up to end of the
2024          * page with etext in it, the data segment goes to the end of
2025          * the address space
2026          */
2027         /*
2028          * XXX text protection is temporarily (?) disabled.  The limit was
2029          * i386_btop(round_page(etext)) - 1.
2030          */
2031         gdt_segs[GCODE_SEL].ssd_limit = i386_btop(0) - 1;
2032         gdt_segs[GDATA_SEL].ssd_limit = i386_btop(0) - 1;
2033 #ifdef SMP
2034         gdt_segs[GPRIV_SEL].ssd_limit =
2035                 i386_btop(sizeof(struct privatespace)) - 1;
2036         gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0];
2037         gdt_segs[GPROC0_SEL].ssd_base =
2038                 (int) &SMP_prvspace[0].globaldata.gd_common_tss;
2039         SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0];
2040 #else
2041         gdt_segs[GPRIV_SEL].ssd_limit = i386_btop(0) - 1;
2042         gdt_segs[GPROC0_SEL].ssd_base = (int) &common_tss;
2043 #endif
2044
2045         for (x = 0; x < NGDT; x++) {
2046 #ifdef BDE_DEBUGGER
2047                 /* avoid overwriting db entries with APM ones */
2048                 if (x >= GAPMCODE32_SEL && x <= GAPMDATA_SEL)
2049                         continue;
2050 #endif
2051                 ssdtosd(&gdt_segs[x], &gdt[x].sd);
2052         }
2053
2054         r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
2055         r_gdt.rd_base =  (int) gdt;
2056         lgdt(&r_gdt);
2057
2058         /* make ldt memory segments */
2059         /*
2060          * The data segment limit must not cover the user area because we
2061          * don't want the user area to be writable in copyout() etc. (page
2062          * level protection is lost in kernel mode on 386's).  Also, we
2063          * don't want the user area to be writable directly (page level
2064          * protection of the user area is not available on 486's with
2065          * CR0_WP set, because there is no user-read/kernel-write mode).
2066          *
2067          * XXX - VM_MAXUSER_ADDRESS is an end address, not a max.  And it
2068          * should be spelled ...MAX_USER...
2069          */
2070 #define VM_END_USER_RW_ADDRESS  VM_MAXUSER_ADDRESS
2071         /*
2072          * The code segment limit has to cover the user area until we move
2073          * the signal trampoline out of the user area.  This is safe because
2074          * the code segment cannot be written to directly.
2075          */
2076 #define VM_END_USER_R_ADDRESS   (VM_END_USER_RW_ADDRESS + UPAGES * PAGE_SIZE)
2077         ldt_segs[LUCODE_SEL].ssd_limit = i386_btop(VM_END_USER_R_ADDRESS) - 1;
2078         ldt_segs[LUDATA_SEL].ssd_limit = i386_btop(VM_END_USER_RW_ADDRESS) - 1;
2079         for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++)
2080                 ssdtosd(&ldt_segs[x], &ldt[x].sd);
2081
2082         _default_ldt = GSEL(GLDT_SEL, SEL_KPL);
2083         lldt(_default_ldt);
2084 #ifdef USER_LDT
2085         currentldt = _default_ldt;
2086 #endif
2087
2088         /* exceptions */
2089         for (x = 0; x < NIDT; x++)
2090                 setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2091         setidt(0, &IDTVEC(div),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2092         setidt(1, &IDTVEC(dbg),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2093         setidt(2, &IDTVEC(nmi),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2094         setidt(3, &IDTVEC(bpt),  SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
2095         setidt(4, &IDTVEC(ofl),  SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
2096         setidt(5, &IDTVEC(bnd),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2097         setidt(6, &IDTVEC(ill),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2098         setidt(7, &IDTVEC(dna),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2099         setidt(8, 0,  SDT_SYSTASKGT, SEL_KPL, GSEL(GPANIC_SEL, SEL_KPL));
2100         setidt(9, &IDTVEC(fpusegm),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2101         setidt(10, &IDTVEC(tss),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2102         setidt(11, &IDTVEC(missing),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2103         setidt(12, &IDTVEC(stk),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2104         setidt(13, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2105         setidt(14, &IDTVEC(page),  SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2106         setidt(15, &IDTVEC(rsvd),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2107         setidt(16, &IDTVEC(fpu),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2108         setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2109         setidt(18, &IDTVEC(mchk),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2110         setidt(0x80, &IDTVEC(int0x80_syscall),
2111                         SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
2112
2113         r_idt.rd_limit = sizeof(idt0) - 1;
2114         r_idt.rd_base = (int) idt;
2115         lidt(&r_idt);
2116
2117         /*
2118          * Initialize the console before we print anything out.
2119          */
2120         cninit();
2121
2122 #include        "isa.h"
2123 #if     NISA >0
2124         isa_defaultirq();
2125 #endif
2126         rand_initialize();
2127
2128 #ifdef DDB
2129         kdb_init();
2130         if (boothowto & RB_KDB)
2131                 Debugger("Boot flags requested debugger");
2132 #endif
2133
2134         finishidentcpu();       /* Final stage of CPU initialization */
2135         setidt(6, &IDTVEC(ill),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2136         setidt(13, &IDTVEC(prot),  SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
2137         initializecpu();        /* Initialize CPU registers */
2138
2139         /* make an initial tss so cpu can get interrupt stack on syscall! */
2140         common_tss.tss_esp0 = (int) proc0.p_addr + UPAGES*PAGE_SIZE - 16;
2141         common_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
2142         gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
2143         private_tss = 0;
2144         tss_gdt = &gdt[GPROC0_SEL].sd;
2145         common_tssd = *tss_gdt;
2146         common_tss.tss_ioopt = (sizeof common_tss) << 16;
2147         ltr(gsel_tss);
2148
2149         dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 =
2150             dblfault_tss.tss_esp2 = (int) &dblfault_stack[sizeof(dblfault_stack)];
2151         dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 =
2152             dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL);
2153         dblfault_tss.tss_cr3 = (int)IdlePTD;
2154         dblfault_tss.tss_eip = (int) dblfault_handler;
2155         dblfault_tss.tss_eflags = PSL_KERNEL;
2156         dblfault_tss.tss_ds = dblfault_tss.tss_es =
2157             dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL);
2158         dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL);
2159         dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL);
2160         dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
2161
2162         vm86_initialize();
2163 #ifdef PC98
2164         getmemsize_pc98(first);
2165 #else
2166         getmemsize(first);
2167 #endif
2168         /* now running on new page tables, configured,and u/iom is accessible */
2169
2170         /* Map the message buffer. */
2171         for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
2172                 pmap_kenter((vm_offset_t)msgbufp + off, avail_end + off);
2173
2174         msgbufinit(msgbufp, MSGBUF_SIZE);
2175
2176         /* make a call gate to reenter kernel with */
2177         gdp = &ldt[LSYS5CALLS_SEL].gd;
2178
2179         x = (int) &IDTVEC(syscall);
2180         gdp->gd_looffset = x++;
2181         gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL);
2182         gdp->gd_stkcpy = 1;
2183         gdp->gd_type = SDT_SYS386CGT;
2184         gdp->gd_dpl = SEL_UPL;
2185         gdp->gd_p = 1;
2186         gdp->gd_hioffset = ((int) &IDTVEC(syscall)) >>16;
2187
2188         /* XXX does this work? */
2189         ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL];
2190         ldt[LSOL26CALLS_SEL] = ldt[LSYS5CALLS_SEL];
2191
2192         /* transfer to user mode */
2193
2194         _ucodesel = LSEL(LUCODE_SEL, SEL_UPL);
2195         _udatasel = LSEL(LUDATA_SEL, SEL_UPL);
2196
2197         /* setup proc 0's pcb */
2198         proc0.p_addr->u_pcb.pcb_flags = 0;
2199         proc0.p_addr->u_pcb.pcb_cr3 = (int)IdlePTD;
2200 #ifdef SMP
2201         proc0.p_addr->u_pcb.pcb_mpnest = 1;
2202 #endif
2203         proc0.p_addr->u_pcb.pcb_ext = 0;
2204 }
2205
2206 #if defined(I586_CPU) && !defined(NO_F00F_HACK)
2207 static void f00f_hack(void *unused);
2208 SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL);
2209
2210 static void
2211 f00f_hack(void *unused) {
2212         struct gate_descriptor *new_idt;
2213 #ifndef SMP
2214         struct region_descriptor r_idt;
2215 #endif
2216         vm_offset_t tmp;
2217
2218         if (!has_f00f_bug)
2219                 return;
2220
2221         printf("Intel Pentium detected, installing workaround for F00F bug\n");
2222
2223         r_idt.rd_limit = sizeof(idt0) - 1;
2224
2225         tmp = kmem_alloc(kernel_map, PAGE_SIZE * 2);
2226         if (tmp == 0)
2227                 panic("kmem_alloc returned 0");
2228         if (((unsigned int)tmp & (PAGE_SIZE-1)) != 0)
2229                 panic("kmem_alloc returned non-page-aligned memory");
2230         /* Put the first seven entries in the lower page */
2231         new_idt = (struct gate_descriptor*)(tmp + PAGE_SIZE - (7*8));
2232         bcopy(idt, new_idt, sizeof(idt0));
2233         r_idt.rd_base = (int)new_idt;
2234         lidt(&r_idt);
2235         idt = new_idt;
2236         if (vm_map_protect(kernel_map, tmp, tmp + PAGE_SIZE,
2237                            VM_PROT_READ, FALSE) != KERN_SUCCESS)
2238                 panic("vm_map_protect failed");
2239         return;
2240 }
2241 #endif /* defined(I586_CPU) && !NO_F00F_HACK */
2242
2243 int
2244 ptrace_set_pc(p, addr)
2245         struct proc *p;
2246         unsigned long addr;
2247 {
2248         p->p_md.md_regs->tf_eip = addr;
2249         return (0);
2250 }
2251
2252 int
2253 ptrace_single_step(p)
2254         struct proc *p;
2255 {
2256         p->p_md.md_regs->tf_eflags |= PSL_T;
2257         return (0);
2258 }
2259
2260 int ptrace_read_u_check(p, addr, len)
2261         struct proc *p;
2262         vm_offset_t addr;
2263         size_t len;
2264 {
2265         vm_offset_t gap;
2266
2267         if ((vm_offset_t) (addr + len) < addr)
2268                 return EPERM;
2269         if ((vm_offset_t) (addr + len) <= sizeof(struct user))
2270                 return 0;
2271
2272         gap = (char *) p->p_md.md_regs - (char *) p->p_addr;
2273         
2274         if ((vm_offset_t) addr < gap)
2275                 return EPERM;
2276         if ((vm_offset_t) (addr + len) <= 
2277             (vm_offset_t) (gap + sizeof(struct trapframe)))
2278                 return 0;
2279         return EPERM;
2280 }
2281
2282 int ptrace_write_u(p, off, data)
2283         struct proc *p;
2284         vm_offset_t off;
2285         long data;
2286 {
2287         struct trapframe frame_copy;
2288         vm_offset_t min;
2289         struct trapframe *tp;
2290
2291         /*
2292          * Privileged kernel state is scattered all over the user area.
2293          * Only allow write access to parts of regs and to fpregs.
2294          */
2295         min = (char *)p->p_md.md_regs - (char *)p->p_addr;
2296         if (off >= min && off <= min + sizeof(struct trapframe) - sizeof(int)) {
2297                 tp = p->p_md.md_regs;
2298                 frame_copy = *tp;
2299                 *(int *)((char *)&frame_copy + (off - min)) = data;
2300                 if (!EFL_SECURE(frame_copy.tf_eflags, tp->tf_eflags) ||
2301                     !CS_SECURE(frame_copy.tf_cs))
2302                         return (EINVAL);
2303                 *(int*)((char *)p->p_addr + off) = data;
2304                 return (0);
2305         }
2306         min = offsetof(struct user, u_pcb) + offsetof(struct pcb, pcb_savefpu);
2307         if (off >= min && off <= min + sizeof(struct save87) - sizeof(int)) {
2308                 *(int*)((char *)p->p_addr + off) = data;
2309                 return (0);
2310         }
2311         return (EFAULT);
2312 }
2313
2314 int
2315 fill_regs(p, regs)
2316         struct proc *p;
2317         struct reg *regs;
2318 {
2319         struct pcb *pcb;
2320         struct trapframe *tp;
2321
2322         tp = p->p_md.md_regs;
2323         regs->r_fs = tp->tf_fs;
2324         regs->r_es = tp->tf_es;
2325         regs->r_ds = tp->tf_ds;
2326         regs->r_edi = tp->tf_edi;
2327         regs->r_esi = tp->tf_esi;
2328         regs->r_ebp = tp->tf_ebp;
2329         regs->r_ebx = tp->tf_ebx;
2330         regs->r_edx = tp->tf_edx;
2331         regs->r_ecx = tp->tf_ecx;
2332         regs->r_eax = tp->tf_eax;
2333         regs->r_eip = tp->tf_eip;
2334         regs->r_cs = tp->tf_cs;
2335         regs->r_eflags = tp->tf_eflags;
2336         regs->r_esp = tp->tf_esp;
2337         regs->r_ss = tp->tf_ss;
2338         pcb = &p->p_addr->u_pcb;
2339         regs->r_gs = pcb->pcb_gs;
2340         return (0);
2341 }
2342
2343 int
2344 set_regs(p, regs)
2345         struct proc *p;
2346         struct reg *regs;
2347 {
2348         struct pcb *pcb;
2349         struct trapframe *tp;
2350
2351         tp = p->p_md.md_regs;
2352         if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) ||
2353             !CS_SECURE(regs->r_cs))
2354                 return (EINVAL);
2355         tp->tf_fs = regs->r_fs;
2356         tp->tf_es = regs->r_es;
2357         tp->tf_ds = regs->r_ds;
2358         tp->tf_edi = regs->r_edi;
2359         tp->tf_esi = regs->r_esi;
2360         tp->tf_ebp = regs->r_ebp;
2361         tp->tf_ebx = regs->r_ebx;
2362         tp->tf_edx = regs->r_edx;
2363         tp->tf_ecx = regs->r_ecx;
2364         tp->tf_eax = regs->r_eax;
2365         tp->tf_eip = regs->r_eip;
2366         tp->tf_cs = regs->r_cs;
2367         tp->tf_eflags = regs->r_eflags;
2368         tp->tf_esp = regs->r_esp;
2369         tp->tf_ss = regs->r_ss;
2370         pcb = &p->p_addr->u_pcb;
2371         pcb->pcb_gs = regs->r_gs;
2372         return (0);
2373 }
2374
2375 int
2376 fill_fpregs(p, fpregs)
2377         struct proc *p;
2378         struct fpreg *fpregs;
2379 {
2380         bcopy(&p->p_addr->u_pcb.pcb_savefpu, fpregs, sizeof *fpregs);
2381         return (0);
2382 }
2383
2384 int
2385 set_fpregs(p, fpregs)
2386         struct proc *p;
2387         struct fpreg *fpregs;
2388 {
2389         bcopy(fpregs, &p->p_addr->u_pcb.pcb_savefpu, sizeof *fpregs);
2390         return (0);
2391 }
2392
2393 int
2394 fill_dbregs(p, dbregs)
2395         struct proc *p;
2396         struct dbreg *dbregs;
2397 {
2398         struct pcb *pcb;
2399
2400         pcb = &p->p_addr->u_pcb;
2401         dbregs->dr0 = pcb->pcb_dr0;
2402         dbregs->dr1 = pcb->pcb_dr1;
2403         dbregs->dr2 = pcb->pcb_dr2;
2404         dbregs->dr3 = pcb->pcb_dr3;
2405         dbregs->dr4 = 0;
2406         dbregs->dr5 = 0;
2407         dbregs->dr6 = pcb->pcb_dr6;
2408         dbregs->dr7 = pcb->pcb_dr7;
2409         return (0);
2410 }
2411
2412 int
2413 set_dbregs(p, dbregs)
2414         struct proc *p;
2415         struct dbreg *dbregs;
2416 {
2417         struct pcb *pcb;
2418
2419         pcb = &p->p_addr->u_pcb;
2420
2421         /*
2422          * Don't let a process set a breakpoint that is not within the
2423          * process's address space.  If a process could do this, it
2424          * could halt the system by setting a breakpoint in the kernel
2425          * (if ddb was enabled).  Thus, we need to check to make sure
2426          * that no breakpoints are being enabled for addresses outside
2427          * process's address space, unless, perhaps, we were called by
2428          * uid 0.
2429          *
2430          * XXX - what about when the watched area of the user's
2431          * address space is written into from within the kernel
2432          * ... wouldn't that still cause a breakpoint to be generated
2433          * from within kernel mode?
2434          */
2435
2436         if (p->p_cred->pc_ucred->cr_uid != 0) {
2437                 if (dbregs->dr7 & 0x3) {
2438                         /* dr0 is enabled */
2439                         if (dbregs->dr0 >= VM_MAXUSER_ADDRESS)
2440                                 return (EINVAL);
2441                 }
2442
2443                 if (dbregs->dr7 & (0x3<<2)) {
2444                         /* dr1 is enabled */
2445                         if (dbregs->dr1 >= VM_MAXUSER_ADDRESS)
2446                                 return (EINVAL);
2447                 }
2448
2449                 if (dbregs->dr7 & (0x3<<4)) {
2450                         /* dr2 is enabled */
2451                         if (dbregs->dr2 >= VM_MAXUSER_ADDRESS)
2452                                 return (EINVAL);
2453                 }
2454
2455                 if (dbregs->dr7 & (0x3<<6)) {
2456                         /* dr3 is enabled */
2457                         if (dbregs->dr3 >= VM_MAXUSER_ADDRESS)
2458                                 return (EINVAL);
2459                 }
2460         }
2461
2462         pcb->pcb_dr0 = dbregs->dr0;
2463         pcb->pcb_dr1 = dbregs->dr1;
2464         pcb->pcb_dr2 = dbregs->dr2;
2465         pcb->pcb_dr3 = dbregs->dr3;
2466         pcb->pcb_dr6 = dbregs->dr6;
2467         pcb->pcb_dr7 = dbregs->dr7;
2468
2469         pcb->pcb_flags |= PCB_DBREGS;
2470
2471         return (0);
2472 }
2473
2474 #ifndef DDB
2475 void
2476 Debugger(const char *msg)
2477 {
2478         printf("Debugger(\"%s\") called.\n", msg);
2479 }
2480 #endif /* no DDB */
2481
2482 #include <sys/disklabel.h>
2483
2484 /*
2485  * Determine the size of the transfer, and make sure it is
2486  * within the boundaries of the partition. Adjust transfer
2487  * if needed, and signal errors or early completion.
2488  */
2489 int
2490 bounds_check_with_label(struct buf *bp, struct disklabel *lp, int wlabel)
2491 {
2492         struct partition *p = lp->d_partitions + dkpart(bp->b_dev);
2493         int labelsect = lp->d_partitions[0].p_offset;
2494         int maxsz = p->p_size,
2495                 sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
2496
2497         /* overwriting disk label ? */
2498         /* XXX should also protect bootstrap in first 8K */
2499         if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect &&
2500 #if LABELSECTOR != 0
2501             bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect &&
2502 #endif
2503             (bp->b_flags & B_READ) == 0 && wlabel == 0) {
2504                 bp->b_error = EROFS;
2505                 goto bad;
2506         }
2507
2508 #if     defined(DOSBBSECTOR) && defined(notyet)
2509         /* overwriting master boot record? */
2510         if (bp->b_blkno + p->p_offset <= DOSBBSECTOR &&
2511             (bp->b_flags & B_READ) == 0 && wlabel == 0) {
2512                 bp->b_error = EROFS;
2513                 goto bad;
2514         }
2515 #endif
2516
2517         /* beyond partition? */
2518         if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) {
2519                 /* if exactly at end of disk, return an EOF */
2520                 if (bp->b_blkno == maxsz) {
2521                         bp->b_resid = bp->b_bcount;
2522                         return(0);
2523                 }
2524                 /* or truncate if part of it fits */
2525                 sz = maxsz - bp->b_blkno;
2526                 if (sz <= 0) {
2527                         bp->b_error = EINVAL;
2528                         goto bad;
2529                 }
2530                 bp->b_bcount = sz << DEV_BSHIFT;
2531         }
2532
2533         bp->b_pblkno = bp->b_blkno + p->p_offset;
2534         return(1);
2535
2536 bad:
2537         bp->b_flags |= B_ERROR;
2538         return(-1);
2539 }
2540
2541 #ifdef DDB
2542
2543 /*
2544  * Provide inb() and outb() as functions.  They are normally only
2545  * available as macros calling inlined functions, thus cannot be
2546  * called inside DDB.
2547  *
2548  * The actual code is stolen from <machine/cpufunc.h>, and de-inlined.
2549  */
2550
2551 #undef inb
2552 #undef outb
2553
2554 /* silence compiler warnings */
2555 u_char inb(u_int);
2556 void outb(u_int, u_char);
2557
2558 u_char
2559 inb(u_int port)
2560 {
2561         u_char  data;
2562         /*
2563          * We use %%dx and not %1 here because i/o is done at %dx and not at
2564          * %edx, while gcc generates inferior code (movw instead of movl)
2565          * if we tell it to load (u_short) port.
2566          */
2567         __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
2568         return (data);
2569 }
2570
2571 void
2572 outb(u_int port, u_char data)
2573 {
2574         u_char  al;
2575         /*
2576          * Use an unnecessary assignment to help gcc's register allocator.
2577          * This make a large difference for gcc-1.40 and a tiny difference
2578          * for gcc-2.6.0.  For gcc-1.40, al had to be ``asm("ax")'' for
2579          * best results.  gcc-2.6.0 can't handle this.
2580          */
2581         al = data;
2582         __asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
2583 }
2584
2585 #endif /* DDB */