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