machdep.c revision 164936
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 */ 39 40#include <sys/cdefs.h> 41__FBSDID("$FreeBSD: head/sys/i386/i386/machdep.c 164936 2006-12-06 06:34:57Z julian $"); 42 43#include "opt_apic.h" 44#include "opt_atalk.h" 45#include "opt_compat.h" 46#include "opt_cpu.h" 47#include "opt_ddb.h" 48#include "opt_inet.h" 49#include "opt_ipx.h" 50#include "opt_isa.h" 51#include "opt_kstack_pages.h" 52#include "opt_maxmem.h" 53#include "opt_msgbuf.h" 54#include "opt_npx.h" 55#include "opt_perfmon.h" 56#include "opt_xbox.h" 57 58#include <sys/param.h> 59#include <sys/proc.h> 60#include <sys/systm.h> 61#include <sys/bio.h> 62#include <sys/buf.h> 63#include <sys/bus.h> 64#include <sys/callout.h> 65#include <sys/clock.h> 66#include <sys/cons.h> 67#include <sys/cpu.h> 68#include <sys/eventhandler.h> 69#include <sys/exec.h> 70#include <sys/imgact.h> 71#include <sys/kdb.h> 72#include <sys/kernel.h> 73#include <sys/ktr.h> 74#include <sys/linker.h> 75#include <sys/lock.h> 76#include <sys/malloc.h> 77#include <sys/memrange.h> 78#include <sys/msgbuf.h> 79#include <sys/mutex.h> 80#include <sys/pcpu.h> 81#include <sys/ptrace.h> 82#include <sys/reboot.h> 83#include <sys/sched.h> 84#include <sys/signalvar.h> 85#include <sys/sysctl.h> 86#include <sys/sysent.h> 87#include <sys/sysproto.h> 88#include <sys/ucontext.h> 89#include <sys/vmmeter.h> 90 91#include <vm/vm.h> 92#include <vm/vm_extern.h> 93#include <vm/vm_kern.h> 94#include <vm/vm_page.h> 95#include <vm/vm_map.h> 96#include <vm/vm_object.h> 97#include <vm/vm_pager.h> 98#include <vm/vm_param.h> 99 100#ifdef DDB 101#ifndef KDB 102#error KDB must be enabled in order for DDB to work! 103#endif 104#include <ddb/ddb.h> 105#include <ddb/db_sym.h> 106#endif 107 108#include <isa/rtc.h> 109 110#include <net/netisr.h> 111 112#include <machine/bootinfo.h> 113#include <machine/clock.h> 114#include <machine/cpu.h> 115#include <machine/cputypes.h> 116#include <machine/intr_machdep.h> 117#include <machine/md_var.h> 118#include <machine/pc/bios.h> 119#include <machine/pcb.h> 120#include <machine/pcb_ext.h> 121#include <machine/proc.h> 122#include <machine/reg.h> 123#include <machine/sigframe.h> 124#include <machine/specialreg.h> 125#include <machine/vm86.h> 126#ifdef PERFMON 127#include <machine/perfmon.h> 128#endif 129#ifdef SMP 130#include <machine/privatespace.h> 131#include <machine/smp.h> 132#endif 133 134#ifdef DEV_ISA 135#include <i386/isa/icu.h> 136#endif 137 138#ifdef XBOX 139#include <machine/xbox.h> 140 141int arch_i386_is_xbox = 0; 142uint32_t arch_i386_xbox_memsize = 0; 143#endif 144 145/* Sanity check for __curthread() */ 146CTASSERT(offsetof(struct pcpu, pc_curthread) == 0); 147 148extern void init386(int first); 149extern void dblfault_handler(void); 150 151extern void printcpuinfo(void); /* XXX header file */ 152extern void finishidentcpu(void); 153extern void panicifcpuunsupported(void); 154extern void initializecpu(void); 155 156#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL) 157#define EFL_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0) 158 159#if !defined(CPU_DISABLE_SSE) && defined(I686_CPU) 160#define CPU_ENABLE_SSE 161#endif 162 163static void cpu_startup(void *); 164static void fpstate_drop(struct thread *td); 165static void get_fpcontext(struct thread *td, mcontext_t *mcp); 166static int set_fpcontext(struct thread *td, const mcontext_t *mcp); 167#ifdef CPU_ENABLE_SSE 168static void set_fpregs_xmm(struct save87 *, struct savexmm *); 169static void fill_fpregs_xmm(struct savexmm *, struct save87 *); 170#endif /* CPU_ENABLE_SSE */ 171SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 172 173#ifdef DDB 174extern vm_offset_t ksym_start, ksym_end; 175#endif 176 177int _udatasel, _ucodesel; 178u_int basemem; 179 180int cold = 1; 181 182#ifdef COMPAT_43 183static void osendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask); 184#endif 185#ifdef COMPAT_FREEBSD4 186static void freebsd4_sendsig(sig_t catcher, ksiginfo_t *, sigset_t *mask); 187#endif 188 189long Maxmem = 0; 190long realmem = 0; 191 192#define PHYSMAP_SIZE (2 * 16) 193 194vm_paddr_t phys_avail[PHYSMAP_SIZE + 2]; 195vm_paddr_t dump_avail[PHYSMAP_SIZE + 2]; 196 197/* must be 2 less so 0 0 can signal end of chunks */ 198#define PHYS_AVAIL_ARRAY_END ((sizeof(phys_avail) / sizeof(phys_avail[0])) - 2) 199#define DUMP_AVAIL_ARRAY_END ((sizeof(dump_avail) / sizeof(dump_avail[0])) - 2) 200 201struct kva_md_info kmi; 202 203static struct trapframe proc0_tf; 204#ifndef SMP 205static struct pcpu __pcpu; 206#endif 207 208struct mtx icu_lock; 209 210struct mem_range_softc mem_range_softc; 211 212static void 213cpu_startup(dummy) 214 void *dummy; 215{ 216 /* 217 * Good {morning,afternoon,evening,night}. 218 */ 219 startrtclock(); 220 printcpuinfo(); 221 panicifcpuunsupported(); 222#ifdef PERFMON 223 perfmon_init(); 224#endif 225 printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)Maxmem), 226 ptoa((uintmax_t)Maxmem) / 1048576); 227 realmem = Maxmem; 228 /* 229 * Display any holes after the first chunk of extended memory. 230 */ 231 if (bootverbose) { 232 int indx; 233 234 printf("Physical memory chunk(s):\n"); 235 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 236 vm_paddr_t size; 237 238 size = phys_avail[indx + 1] - phys_avail[indx]; 239 printf( 240 "0x%016jx - 0x%016jx, %ju bytes (%ju pages)\n", 241 (uintmax_t)phys_avail[indx], 242 (uintmax_t)phys_avail[indx + 1] - 1, 243 (uintmax_t)size, (uintmax_t)size / PAGE_SIZE); 244 } 245 } 246 247 vm_ksubmap_init(&kmi); 248 249 printf("avail memory = %ju (%ju MB)\n", 250 ptoa((uintmax_t)cnt.v_free_count), 251 ptoa((uintmax_t)cnt.v_free_count) / 1048576); 252 253 /* 254 * Set up buffers, so they can be used to read disk labels. 255 */ 256 bufinit(); 257 vm_pager_bufferinit(); 258 259 cpu_setregs(); 260} 261 262/* 263 * Send an interrupt to process. 264 * 265 * Stack is set up to allow sigcode stored 266 * at top to call routine, followed by kcall 267 * to sigreturn routine below. After sigreturn 268 * resets the signal mask, the stack, and the 269 * frame pointer, it returns to the user 270 * specified pc, psl. 271 */ 272#ifdef COMPAT_43 273static void 274osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 275{ 276 struct osigframe sf, *fp; 277 struct proc *p; 278 struct thread *td; 279 struct sigacts *psp; 280 struct trapframe *regs; 281 int sig; 282 int oonstack; 283 284 td = curthread; 285 p = td->td_proc; 286 PROC_LOCK_ASSERT(p, MA_OWNED); 287 sig = ksi->ksi_signo; 288 psp = p->p_sigacts; 289 mtx_assert(&psp->ps_mtx, MA_OWNED); 290 regs = td->td_frame; 291 oonstack = sigonstack(regs->tf_esp); 292 293 /* Allocate space for the signal handler context. */ 294 if ((td->td_pflags & TDP_ALTSTACK) && !oonstack && 295 SIGISMEMBER(psp->ps_sigonstack, sig)) { 296 fp = (struct osigframe *)(td->td_sigstk.ss_sp + 297 td->td_sigstk.ss_size - sizeof(struct osigframe)); 298#if defined(COMPAT_43) 299 td->td_sigstk.ss_flags |= SS_ONSTACK; 300#endif 301 } else 302 fp = (struct osigframe *)regs->tf_esp - 1; 303 304 /* Translate the signal if appropriate. */ 305 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 306 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 307 308 /* Build the argument list for the signal handler. */ 309 sf.sf_signum = sig; 310 sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc; 311 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 312 /* Signal handler installed with SA_SIGINFO. */ 313 sf.sf_arg2 = (register_t)&fp->sf_siginfo; 314 sf.sf_siginfo.si_signo = sig; 315 sf.sf_siginfo.si_code = ksi->ksi_code; 316 sf.sf_ahu.sf_action = (__osiginfohandler_t *)catcher; 317 } else { 318 /* Old FreeBSD-style arguments. */ 319 sf.sf_arg2 = ksi->ksi_code; 320 sf.sf_addr = (register_t)ksi->ksi_addr; 321 sf.sf_ahu.sf_handler = catcher; 322 } 323 mtx_unlock(&psp->ps_mtx); 324 PROC_UNLOCK(p); 325 326 /* Save most if not all of trap frame. */ 327 sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax; 328 sf.sf_siginfo.si_sc.sc_ebx = regs->tf_ebx; 329 sf.sf_siginfo.si_sc.sc_ecx = regs->tf_ecx; 330 sf.sf_siginfo.si_sc.sc_edx = regs->tf_edx; 331 sf.sf_siginfo.si_sc.sc_esi = regs->tf_esi; 332 sf.sf_siginfo.si_sc.sc_edi = regs->tf_edi; 333 sf.sf_siginfo.si_sc.sc_cs = regs->tf_cs; 334 sf.sf_siginfo.si_sc.sc_ds = regs->tf_ds; 335 sf.sf_siginfo.si_sc.sc_ss = regs->tf_ss; 336 sf.sf_siginfo.si_sc.sc_es = regs->tf_es; 337 sf.sf_siginfo.si_sc.sc_fs = regs->tf_fs; 338 sf.sf_siginfo.si_sc.sc_gs = rgs(); 339 sf.sf_siginfo.si_sc.sc_isp = regs->tf_isp; 340 341 /* Build the signal context to be used by osigreturn(). */ 342 sf.sf_siginfo.si_sc.sc_onstack = (oonstack) ? 1 : 0; 343 SIG2OSIG(*mask, sf.sf_siginfo.si_sc.sc_mask); 344 sf.sf_siginfo.si_sc.sc_sp = regs->tf_esp; 345 sf.sf_siginfo.si_sc.sc_fp = regs->tf_ebp; 346 sf.sf_siginfo.si_sc.sc_pc = regs->tf_eip; 347 sf.sf_siginfo.si_sc.sc_ps = regs->tf_eflags; 348 sf.sf_siginfo.si_sc.sc_trapno = regs->tf_trapno; 349 sf.sf_siginfo.si_sc.sc_err = regs->tf_err; 350 351 /* 352 * If we're a vm86 process, we want to save the segment registers. 353 * We also change eflags to be our emulated eflags, not the actual 354 * eflags. 355 */ 356 if (regs->tf_eflags & PSL_VM) { 357 /* XXX confusing names: `tf' isn't a trapframe; `regs' is. */ 358 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; 359 struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86; 360 361 sf.sf_siginfo.si_sc.sc_gs = tf->tf_vm86_gs; 362 sf.sf_siginfo.si_sc.sc_fs = tf->tf_vm86_fs; 363 sf.sf_siginfo.si_sc.sc_es = tf->tf_vm86_es; 364 sf.sf_siginfo.si_sc.sc_ds = tf->tf_vm86_ds; 365 366 if (vm86->vm86_has_vme == 0) 367 sf.sf_siginfo.si_sc.sc_ps = 368 (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) | 369 (vm86->vm86_eflags & (PSL_VIF | PSL_VIP)); 370 371 /* See sendsig() for comments. */ 372 tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP); 373 } 374 375 /* 376 * Copy the sigframe out to the user's stack. 377 */ 378 if (copyout(&sf, fp, sizeof(*fp)) != 0) { 379#ifdef DEBUG 380 printf("process %ld has trashed its stack\n", (long)p->p_pid); 381#endif 382 PROC_LOCK(p); 383 sigexit(td, SIGILL); 384 } 385 386 regs->tf_esp = (int)fp; 387 regs->tf_eip = PS_STRINGS - szosigcode; 388 regs->tf_eflags &= ~PSL_T; 389 regs->tf_cs = _ucodesel; 390 regs->tf_ds = _udatasel; 391 regs->tf_es = _udatasel; 392 regs->tf_fs = _udatasel; 393 load_gs(_udatasel); 394 regs->tf_ss = _udatasel; 395 PROC_LOCK(p); 396 mtx_lock(&psp->ps_mtx); 397} 398#endif /* COMPAT_43 */ 399 400#ifdef COMPAT_FREEBSD4 401static void 402freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 403{ 404 struct sigframe4 sf, *sfp; 405 struct proc *p; 406 struct thread *td; 407 struct sigacts *psp; 408 struct trapframe *regs; 409 int sig; 410 int oonstack; 411 412 td = curthread; 413 p = td->td_proc; 414 PROC_LOCK_ASSERT(p, MA_OWNED); 415 sig = ksi->ksi_signo; 416 psp = p->p_sigacts; 417 mtx_assert(&psp->ps_mtx, MA_OWNED); 418 regs = td->td_frame; 419 oonstack = sigonstack(regs->tf_esp); 420 421 /* Save user context. */ 422 bzero(&sf, sizeof(sf)); 423 sf.sf_uc.uc_sigmask = *mask; 424 sf.sf_uc.uc_stack = td->td_sigstk; 425 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 426 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 427 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 428 sf.sf_uc.uc_mcontext.mc_gs = rgs(); 429 bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs)); 430 431 /* Allocate space for the signal handler context. */ 432 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 433 SIGISMEMBER(psp->ps_sigonstack, sig)) { 434 sfp = (struct sigframe4 *)(td->td_sigstk.ss_sp + 435 td->td_sigstk.ss_size - sizeof(struct sigframe4)); 436#if defined(COMPAT_43) 437 td->td_sigstk.ss_flags |= SS_ONSTACK; 438#endif 439 } else 440 sfp = (struct sigframe4 *)regs->tf_esp - 1; 441 442 /* Translate the signal if appropriate. */ 443 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 444 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 445 446 /* Build the argument list for the signal handler. */ 447 sf.sf_signum = sig; 448 sf.sf_ucontext = (register_t)&sfp->sf_uc; 449 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 450 /* Signal handler installed with SA_SIGINFO. */ 451 sf.sf_siginfo = (register_t)&sfp->sf_si; 452 sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; 453 454 /* Fill in POSIX parts */ 455 sf.sf_si.si_signo = sig; 456 sf.sf_si.si_code = ksi->ksi_code; 457 sf.sf_si.si_addr = ksi->ksi_addr; 458 } else { 459 /* Old FreeBSD-style arguments. */ 460 sf.sf_siginfo = ksi->ksi_code; 461 sf.sf_addr = (register_t)ksi->ksi_addr; 462 sf.sf_ahu.sf_handler = catcher; 463 } 464 mtx_unlock(&psp->ps_mtx); 465 PROC_UNLOCK(p); 466 467 /* 468 * If we're a vm86 process, we want to save the segment registers. 469 * We also change eflags to be our emulated eflags, not the actual 470 * eflags. 471 */ 472 if (regs->tf_eflags & PSL_VM) { 473 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; 474 struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86; 475 476 sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs; 477 sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs; 478 sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es; 479 sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds; 480 481 if (vm86->vm86_has_vme == 0) 482 sf.sf_uc.uc_mcontext.mc_eflags = 483 (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) | 484 (vm86->vm86_eflags & (PSL_VIF | PSL_VIP)); 485 486 /* 487 * Clear PSL_NT to inhibit T_TSSFLT faults on return from 488 * syscalls made by the signal handler. This just avoids 489 * wasting time for our lazy fixup of such faults. PSL_NT 490 * does nothing in vm86 mode, but vm86 programs can set it 491 * almost legitimately in probes for old cpu types. 492 */ 493 tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP); 494 } 495 496 /* 497 * Copy the sigframe out to the user's stack. 498 */ 499 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 500#ifdef DEBUG 501 printf("process %ld has trashed its stack\n", (long)p->p_pid); 502#endif 503 PROC_LOCK(p); 504 sigexit(td, SIGILL); 505 } 506 507 regs->tf_esp = (int)sfp; 508 regs->tf_eip = PS_STRINGS - szfreebsd4_sigcode; 509 regs->tf_eflags &= ~PSL_T; 510 regs->tf_cs = _ucodesel; 511 regs->tf_ds = _udatasel; 512 regs->tf_es = _udatasel; 513 regs->tf_fs = _udatasel; 514 regs->tf_ss = _udatasel; 515 PROC_LOCK(p); 516 mtx_lock(&psp->ps_mtx); 517} 518#endif /* COMPAT_FREEBSD4 */ 519 520void 521sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 522{ 523 struct sigframe sf, *sfp; 524 struct proc *p; 525 struct thread *td; 526 struct sigacts *psp; 527 char *sp; 528 struct trapframe *regs; 529 int sig; 530 int oonstack; 531 532 td = curthread; 533 p = td->td_proc; 534 PROC_LOCK_ASSERT(p, MA_OWNED); 535 sig = ksi->ksi_signo; 536 psp = p->p_sigacts; 537 mtx_assert(&psp->ps_mtx, MA_OWNED); 538#ifdef COMPAT_FREEBSD4 539 if (SIGISMEMBER(psp->ps_freebsd4, sig)) { 540 freebsd4_sendsig(catcher, ksi, mask); 541 return; 542 } 543#endif 544#ifdef COMPAT_43 545 if (SIGISMEMBER(psp->ps_osigset, sig)) { 546 osendsig(catcher, ksi, mask); 547 return; 548 } 549#endif 550 regs = td->td_frame; 551 oonstack = sigonstack(regs->tf_esp); 552 553 /* Save user context. */ 554 bzero(&sf, sizeof(sf)); 555 sf.sf_uc.uc_sigmask = *mask; 556 sf.sf_uc.uc_stack = td->td_sigstk; 557 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 558 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 559 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 560 sf.sf_uc.uc_mcontext.mc_gs = rgs(); 561 bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs)); 562 sf.sf_uc.uc_mcontext.mc_len = sizeof(sf.sf_uc.uc_mcontext); /* magic */ 563 get_fpcontext(td, &sf.sf_uc.uc_mcontext); 564 fpstate_drop(td); 565 566 /* Allocate space for the signal handler context. */ 567 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 568 SIGISMEMBER(psp->ps_sigonstack, sig)) { 569 sp = td->td_sigstk.ss_sp + 570 td->td_sigstk.ss_size - sizeof(struct sigframe); 571#if defined(COMPAT_43) 572 td->td_sigstk.ss_flags |= SS_ONSTACK; 573#endif 574 } else 575 sp = (char *)regs->tf_esp - sizeof(struct sigframe); 576 /* Align to 16 bytes. */ 577 sfp = (struct sigframe *)((unsigned int)sp & ~0xF); 578 579 /* Translate the signal if appropriate. */ 580 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 581 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 582 583 /* Build the argument list for the signal handler. */ 584 sf.sf_signum = sig; 585 sf.sf_ucontext = (register_t)&sfp->sf_uc; 586 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 587 /* Signal handler installed with SA_SIGINFO. */ 588 sf.sf_siginfo = (register_t)&sfp->sf_si; 589 sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; 590 591 /* Fill in POSIX parts */ 592 sf.sf_si = ksi->ksi_info; 593 sf.sf_si.si_signo = sig; /* maybe a translated signal */ 594 } else { 595 /* Old FreeBSD-style arguments. */ 596 sf.sf_siginfo = ksi->ksi_code; 597 sf.sf_addr = (register_t)ksi->ksi_addr; 598 sf.sf_ahu.sf_handler = catcher; 599 } 600 mtx_unlock(&psp->ps_mtx); 601 PROC_UNLOCK(p); 602 603 /* 604 * If we're a vm86 process, we want to save the segment registers. 605 * We also change eflags to be our emulated eflags, not the actual 606 * eflags. 607 */ 608 if (regs->tf_eflags & PSL_VM) { 609 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; 610 struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86; 611 612 sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs; 613 sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs; 614 sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es; 615 sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds; 616 617 if (vm86->vm86_has_vme == 0) 618 sf.sf_uc.uc_mcontext.mc_eflags = 619 (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) | 620 (vm86->vm86_eflags & (PSL_VIF | PSL_VIP)); 621 622 /* 623 * Clear PSL_NT to inhibit T_TSSFLT faults on return from 624 * syscalls made by the signal handler. This just avoids 625 * wasting time for our lazy fixup of such faults. PSL_NT 626 * does nothing in vm86 mode, but vm86 programs can set it 627 * almost legitimately in probes for old cpu types. 628 */ 629 tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP); 630 } 631 632 /* 633 * Copy the sigframe out to the user's stack. 634 */ 635 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 636#ifdef DEBUG 637 printf("process %ld has trashed its stack\n", (long)p->p_pid); 638#endif 639 PROC_LOCK(p); 640 sigexit(td, SIGILL); 641 } 642 643 regs->tf_esp = (int)sfp; 644 regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); 645 regs->tf_eflags &= ~PSL_T; 646 regs->tf_cs = _ucodesel; 647 regs->tf_ds = _udatasel; 648 regs->tf_es = _udatasel; 649 regs->tf_fs = _udatasel; 650 regs->tf_ss = _udatasel; 651 PROC_LOCK(p); 652 mtx_lock(&psp->ps_mtx); 653} 654 655/* 656 * System call to cleanup state after a signal 657 * has been taken. Reset signal mask and 658 * stack state from context left by sendsig (above). 659 * Return to previous pc and psl as specified by 660 * context left by sendsig. Check carefully to 661 * make sure that the user has not modified the 662 * state to gain improper privileges. 663 * 664 * MPSAFE 665 */ 666#ifdef COMPAT_43 667int 668osigreturn(td, uap) 669 struct thread *td; 670 struct osigreturn_args /* { 671 struct osigcontext *sigcntxp; 672 } */ *uap; 673{ 674 struct osigcontext sc; 675 struct trapframe *regs; 676 struct osigcontext *scp; 677 struct proc *p = td->td_proc; 678 int eflags, error; 679 ksiginfo_t ksi; 680 681 regs = td->td_frame; 682 error = copyin(uap->sigcntxp, &sc, sizeof(sc)); 683 if (error != 0) 684 return (error); 685 scp = ≻ 686 eflags = scp->sc_ps; 687 if (eflags & PSL_VM) { 688 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; 689 struct vm86_kernel *vm86; 690 691 /* 692 * if pcb_ext == 0 or vm86_inited == 0, the user hasn't 693 * set up the vm86 area, and we can't enter vm86 mode. 694 */ 695 if (td->td_pcb->pcb_ext == 0) 696 return (EINVAL); 697 vm86 = &td->td_pcb->pcb_ext->ext_vm86; 698 if (vm86->vm86_inited == 0) 699 return (EINVAL); 700 701 /* Go back to user mode if both flags are set. */ 702 if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) { 703 ksiginfo_init_trap(&ksi); 704 ksi.ksi_signo = SIGBUS; 705 ksi.ksi_code = BUS_OBJERR; 706 ksi.ksi_addr = (void *)regs->tf_eip; 707 trapsignal(td, &ksi); 708 } 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 tf->tf_vm86_ds = scp->sc_ds; 719 tf->tf_vm86_es = scp->sc_es; 720 tf->tf_vm86_fs = scp->sc_fs; 721 tf->tf_vm86_gs = scp->sc_gs; 722 tf->tf_ds = _udatasel; 723 tf->tf_es = _udatasel; 724 tf->tf_fs = _udatasel; 725 } else { 726 /* 727 * Don't allow users to change privileged or reserved flags. 728 */ 729 /* 730 * XXX do allow users to change the privileged flag PSL_RF. 731 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 732 * should sometimes set it there too. tf_eflags is kept in 733 * the signal context during signal handling and there is no 734 * other place to remember it, so the PSL_RF bit may be 735 * corrupted by the signal handler without us knowing. 736 * Corruption of the PSL_RF bit at worst causes one more or 737 * one less debugger trap, so allowing it is fairly harmless. 738 */ 739 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { 740 return (EINVAL); 741 } 742 743 /* 744 * Don't allow users to load a valid privileged %cs. Let the 745 * hardware check for invalid selectors, excess privilege in 746 * other selectors, invalid %eip's and invalid %esp's. 747 */ 748 if (!CS_SECURE(scp->sc_cs)) { 749 ksiginfo_init_trap(&ksi); 750 ksi.ksi_signo = SIGBUS; 751 ksi.ksi_code = BUS_OBJERR; 752 ksi.ksi_trapno = T_PROTFLT; 753 ksi.ksi_addr = (void *)regs->tf_eip; 754 trapsignal(td, &ksi); 755 return (EINVAL); 756 } 757 regs->tf_ds = scp->sc_ds; 758 regs->tf_es = scp->sc_es; 759 regs->tf_fs = scp->sc_fs; 760 } 761 762 /* Restore remaining registers. */ 763 regs->tf_eax = scp->sc_eax; 764 regs->tf_ebx = scp->sc_ebx; 765 regs->tf_ecx = scp->sc_ecx; 766 regs->tf_edx = scp->sc_edx; 767 regs->tf_esi = scp->sc_esi; 768 regs->tf_edi = scp->sc_edi; 769 regs->tf_cs = scp->sc_cs; 770 regs->tf_ss = scp->sc_ss; 771 regs->tf_isp = scp->sc_isp; 772 regs->tf_ebp = scp->sc_fp; 773 regs->tf_esp = scp->sc_sp; 774 regs->tf_eip = scp->sc_pc; 775 regs->tf_eflags = eflags; 776 777 PROC_LOCK(p); 778#if defined(COMPAT_43) 779 if (scp->sc_onstack & 1) 780 td->td_sigstk.ss_flags |= SS_ONSTACK; 781 else 782 td->td_sigstk.ss_flags &= ~SS_ONSTACK; 783#endif 784 SIGSETOLD(td->td_sigmask, scp->sc_mask); 785 SIG_CANTMASK(td->td_sigmask); 786 signotify(td); 787 PROC_UNLOCK(p); 788 return (EJUSTRETURN); 789} 790#endif /* COMPAT_43 */ 791 792#ifdef COMPAT_FREEBSD4 793/* 794 * MPSAFE 795 */ 796int 797freebsd4_sigreturn(td, uap) 798 struct thread *td; 799 struct freebsd4_sigreturn_args /* { 800 const ucontext4 *sigcntxp; 801 } */ *uap; 802{ 803 struct ucontext4 uc; 804 struct proc *p = td->td_proc; 805 struct trapframe *regs; 806 const struct ucontext4 *ucp; 807 int cs, eflags, error; 808 ksiginfo_t ksi; 809 810 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 811 if (error != 0) 812 return (error); 813 ucp = &uc; 814 regs = td->td_frame; 815 eflags = ucp->uc_mcontext.mc_eflags; 816 if (eflags & PSL_VM) { 817 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; 818 struct vm86_kernel *vm86; 819 820 /* 821 * if pcb_ext == 0 or vm86_inited == 0, the user hasn't 822 * set up the vm86 area, and we can't enter vm86 mode. 823 */ 824 if (td->td_pcb->pcb_ext == 0) 825 return (EINVAL); 826 vm86 = &td->td_pcb->pcb_ext->ext_vm86; 827 if (vm86->vm86_inited == 0) 828 return (EINVAL); 829 830 /* Go back to user mode if both flags are set. */ 831 if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) { 832 ksiginfo_init_trap(&ksi); 833 ksi.ksi_signo = SIGBUS; 834 ksi.ksi_code = BUS_OBJERR; 835 ksi.ksi_addr = (void *)regs->tf_eip; 836 trapsignal(td, &ksi); 837 } 838 if (vm86->vm86_has_vme) { 839 eflags = (tf->tf_eflags & ~VME_USERCHANGE) | 840 (eflags & VME_USERCHANGE) | PSL_VM; 841 } else { 842 vm86->vm86_eflags = eflags; /* save VIF, VIP */ 843 eflags = (tf->tf_eflags & ~VM_USERCHANGE) | 844 (eflags & VM_USERCHANGE) | PSL_VM; 845 } 846 bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe)); 847 tf->tf_eflags = eflags; 848 tf->tf_vm86_ds = tf->tf_ds; 849 tf->tf_vm86_es = tf->tf_es; 850 tf->tf_vm86_fs = tf->tf_fs; 851 tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs; 852 tf->tf_ds = _udatasel; 853 tf->tf_es = _udatasel; 854 tf->tf_fs = _udatasel; 855 } else { 856 /* 857 * Don't allow users to change privileged or reserved flags. 858 */ 859 /* 860 * XXX do allow users to change the privileged flag PSL_RF. 861 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 862 * should sometimes set it there too. tf_eflags is kept in 863 * the signal context during signal handling and there is no 864 * other place to remember it, so the PSL_RF bit may be 865 * corrupted by the signal handler without us knowing. 866 * Corruption of the PSL_RF bit at worst causes one more or 867 * one less debugger trap, so allowing it is fairly harmless. 868 */ 869 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { 870 printf("freebsd4_sigreturn: eflags = 0x%x\n", eflags); 871 return (EINVAL); 872 } 873 874 /* 875 * Don't allow users to load a valid privileged %cs. Let the 876 * hardware check for invalid selectors, excess privilege in 877 * other selectors, invalid %eip's and invalid %esp's. 878 */ 879 cs = ucp->uc_mcontext.mc_cs; 880 if (!CS_SECURE(cs)) { 881 printf("freebsd4_sigreturn: cs = 0x%x\n", cs); 882 ksiginfo_init_trap(&ksi); 883 ksi.ksi_signo = SIGBUS; 884 ksi.ksi_code = BUS_OBJERR; 885 ksi.ksi_trapno = T_PROTFLT; 886 ksi.ksi_addr = (void *)regs->tf_eip; 887 trapsignal(td, &ksi); 888 return (EINVAL); 889 } 890 891 bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); 892 } 893 894 PROC_LOCK(p); 895#if defined(COMPAT_43) 896 if (ucp->uc_mcontext.mc_onstack & 1) 897 td->td_sigstk.ss_flags |= SS_ONSTACK; 898 else 899 td->td_sigstk.ss_flags &= ~SS_ONSTACK; 900#endif 901 902 td->td_sigmask = ucp->uc_sigmask; 903 SIG_CANTMASK(td->td_sigmask); 904 signotify(td); 905 PROC_UNLOCK(p); 906 return (EJUSTRETURN); 907} 908#endif /* COMPAT_FREEBSD4 */ 909 910/* 911 * MPSAFE 912 */ 913int 914sigreturn(td, uap) 915 struct thread *td; 916 struct sigreturn_args /* { 917 const struct __ucontext *sigcntxp; 918 } */ *uap; 919{ 920 ucontext_t uc; 921 struct proc *p = td->td_proc; 922 struct trapframe *regs; 923 const ucontext_t *ucp; 924 int cs, eflags, error, ret; 925 ksiginfo_t ksi; 926 927 error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 928 if (error != 0) 929 return (error); 930 ucp = &uc; 931 regs = td->td_frame; 932 eflags = ucp->uc_mcontext.mc_eflags; 933 if (eflags & PSL_VM) { 934 struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs; 935 struct vm86_kernel *vm86; 936 937 /* 938 * if pcb_ext == 0 or vm86_inited == 0, the user hasn't 939 * set up the vm86 area, and we can't enter vm86 mode. 940 */ 941 if (td->td_pcb->pcb_ext == 0) 942 return (EINVAL); 943 vm86 = &td->td_pcb->pcb_ext->ext_vm86; 944 if (vm86->vm86_inited == 0) 945 return (EINVAL); 946 947 /* Go back to user mode if both flags are set. */ 948 if ((eflags & PSL_VIP) && (eflags & PSL_VIF)) { 949 ksiginfo_init_trap(&ksi); 950 ksi.ksi_signo = SIGBUS; 951 ksi.ksi_code = BUS_OBJERR; 952 ksi.ksi_addr = (void *)regs->tf_eip; 953 trapsignal(td, &ksi); 954 } 955 956 if (vm86->vm86_has_vme) { 957 eflags = (tf->tf_eflags & ~VME_USERCHANGE) | 958 (eflags & VME_USERCHANGE) | PSL_VM; 959 } else { 960 vm86->vm86_eflags = eflags; /* save VIF, VIP */ 961 eflags = (tf->tf_eflags & ~VM_USERCHANGE) | 962 (eflags & VM_USERCHANGE) | PSL_VM; 963 } 964 bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe)); 965 tf->tf_eflags = eflags; 966 tf->tf_vm86_ds = tf->tf_ds; 967 tf->tf_vm86_es = tf->tf_es; 968 tf->tf_vm86_fs = tf->tf_fs; 969 tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs; 970 tf->tf_ds = _udatasel; 971 tf->tf_es = _udatasel; 972 tf->tf_fs = _udatasel; 973 } else { 974 /* 975 * Don't allow users to change privileged or reserved flags. 976 */ 977 /* 978 * XXX do allow users to change the privileged flag PSL_RF. 979 * The cpu sets PSL_RF in tf_eflags for faults. Debuggers 980 * should sometimes set it there too. tf_eflags is kept in 981 * the signal context during signal handling and there is no 982 * other place to remember it, so the PSL_RF bit may be 983 * corrupted by the signal handler without us knowing. 984 * Corruption of the PSL_RF bit at worst causes one more or 985 * one less debugger trap, so allowing it is fairly harmless. 986 */ 987 if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) { 988 printf("sigreturn: eflags = 0x%x\n", eflags); 989 return (EINVAL); 990 } 991 992 /* 993 * Don't allow users to load a valid privileged %cs. Let the 994 * hardware check for invalid selectors, excess privilege in 995 * other selectors, invalid %eip's and invalid %esp's. 996 */ 997 cs = ucp->uc_mcontext.mc_cs; 998 if (!CS_SECURE(cs)) { 999 printf("sigreturn: cs = 0x%x\n", cs); 1000 ksiginfo_init_trap(&ksi); 1001 ksi.ksi_signo = SIGBUS; 1002 ksi.ksi_code = BUS_OBJERR; 1003 ksi.ksi_trapno = T_PROTFLT; 1004 ksi.ksi_addr = (void *)regs->tf_eip; 1005 trapsignal(td, &ksi); 1006 return (EINVAL); 1007 } 1008 1009 ret = set_fpcontext(td, &ucp->uc_mcontext); 1010 if (ret != 0) 1011 return (ret); 1012 bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); 1013 } 1014 1015 PROC_LOCK(p); 1016#if defined(COMPAT_43) 1017 if (ucp->uc_mcontext.mc_onstack & 1) 1018 td->td_sigstk.ss_flags |= SS_ONSTACK; 1019 else 1020 td->td_sigstk.ss_flags &= ~SS_ONSTACK; 1021#endif 1022 1023 td->td_sigmask = ucp->uc_sigmask; 1024 SIG_CANTMASK(td->td_sigmask); 1025 signotify(td); 1026 PROC_UNLOCK(p); 1027 return (EJUSTRETURN); 1028} 1029 1030/* 1031 * Machine dependent boot() routine 1032 * 1033 * I haven't seen anything to put here yet 1034 * Possibly some stuff might be grafted back here from boot() 1035 */ 1036void 1037cpu_boot(int howto) 1038{ 1039} 1040 1041/* Get current clock frequency for the given cpu id. */ 1042int 1043cpu_est_clockrate(int cpu_id, uint64_t *rate) 1044{ 1045 register_t reg; 1046 uint64_t tsc1, tsc2; 1047 1048 if (pcpu_find(cpu_id) == NULL || rate == NULL) 1049 return (EINVAL); 1050 if (!tsc_present) 1051 return (EOPNOTSUPP); 1052 1053 /* If we're booting, trust the rate calibrated moments ago. */ 1054 if (cold) { 1055 *rate = tsc_freq; 1056 return (0); 1057 } 1058 1059#ifdef SMP 1060 /* Schedule ourselves on the indicated cpu. */ 1061 mtx_lock_spin(&sched_lock); 1062 sched_bind(curthread, cpu_id); 1063 mtx_unlock_spin(&sched_lock); 1064#endif 1065 1066 /* Calibrate by measuring a short delay. */ 1067 reg = intr_disable(); 1068 tsc1 = rdtsc(); 1069 DELAY(1000); 1070 tsc2 = rdtsc(); 1071 intr_restore(reg); 1072 1073#ifdef SMP 1074 mtx_lock_spin(&sched_lock); 1075 sched_unbind(curthread); 1076 mtx_unlock_spin(&sched_lock); 1077#endif 1078 1079 /* 1080 * Calculate the difference in readings, convert to Mhz, and 1081 * subtract 0.5% of the total. Empirical testing has shown that 1082 * overhead in DELAY() works out to approximately this value. 1083 */ 1084 tsc2 -= tsc1; 1085 *rate = tsc2 * 1000 - tsc2 * 5; 1086 return (0); 1087} 1088 1089/* 1090 * Shutdown the CPU as much as possible 1091 */ 1092void 1093cpu_halt(void) 1094{ 1095 for (;;) 1096 __asm__ ("hlt"); 1097} 1098 1099/* 1100 * Hook to idle the CPU when possible. In the SMP case we default to 1101 * off because a halted cpu will not currently pick up a new thread in the 1102 * run queue until the next timer tick. If turned on this will result in 1103 * approximately a 4.2% loss in real time performance in buildworld tests 1104 * (but improves user and sys times oddly enough), and saves approximately 1105 * 5% in power consumption on an idle machine (tests w/2xCPU 1.1GHz P3). 1106 * 1107 * XXX we need to have a cpu mask of idle cpus and generate an IPI or 1108 * otherwise generate some sort of interrupt to wake up cpus sitting in HLT. 1109 * Then we can have our cake and eat it too. 1110 * 1111 * XXX I'm turning it on for SMP as well by default for now. It seems to 1112 * help lock contention somewhat, and this is critical for HTT. -Peter 1113 */ 1114static int cpu_idle_hlt = 1; 1115SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW, 1116 &cpu_idle_hlt, 0, "Idle loop HLT enable"); 1117 1118static void 1119cpu_idle_default(void) 1120{ 1121 /* 1122 * we must absolutely guarentee that hlt is the 1123 * absolute next instruction after sti or we 1124 * introduce a timing window. 1125 */ 1126 __asm __volatile("sti; hlt"); 1127} 1128 1129/* 1130 * Note that we have to be careful here to avoid a race between checking 1131 * sched_runnable() and actually halting. If we don't do this, we may waste 1132 * the time between calling hlt and the next interrupt even though there 1133 * is a runnable process. 1134 */ 1135void 1136cpu_idle(void) 1137{ 1138 1139#ifdef SMP 1140 if (mp_grab_cpu_hlt()) 1141 return; 1142#endif 1143 1144 if (cpu_idle_hlt) { 1145 disable_intr(); 1146 if (sched_runnable()) 1147 enable_intr(); 1148 else 1149 (*cpu_idle_hook)(); 1150 } 1151} 1152 1153/* Other subsystems (e.g., ACPI) can hook this later. */ 1154void (*cpu_idle_hook)(void) = cpu_idle_default; 1155 1156/* 1157 * Clear registers on exec 1158 */ 1159void 1160exec_setregs(td, entry, stack, ps_strings) 1161 struct thread *td; 1162 u_long entry; 1163 u_long stack; 1164 u_long ps_strings; 1165{ 1166 struct trapframe *regs = td->td_frame; 1167 struct pcb *pcb = td->td_pcb; 1168 1169 /* Reset pc->pcb_gs and %gs before possibly invalidating it. */ 1170 pcb->pcb_gs = _udatasel; 1171 load_gs(_udatasel); 1172 1173 if (td->td_proc->p_md.md_ldt) 1174 user_ldt_free(td); 1175 1176 bzero((char *)regs, sizeof(struct trapframe)); 1177 regs->tf_eip = entry; 1178 regs->tf_esp = stack; 1179 regs->tf_eflags = PSL_USER | (regs->tf_eflags & PSL_T); 1180 regs->tf_ss = _udatasel; 1181 regs->tf_ds = _udatasel; 1182 regs->tf_es = _udatasel; 1183 regs->tf_fs = _udatasel; 1184 regs->tf_cs = _ucodesel; 1185 1186 /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ 1187 regs->tf_ebx = ps_strings; 1188 1189 /* 1190 * Reset the hardware debug registers if they were in use. 1191 * They won't have any meaning for the newly exec'd process. 1192 */ 1193 if (pcb->pcb_flags & PCB_DBREGS) { 1194 pcb->pcb_dr0 = 0; 1195 pcb->pcb_dr1 = 0; 1196 pcb->pcb_dr2 = 0; 1197 pcb->pcb_dr3 = 0; 1198 pcb->pcb_dr6 = 0; 1199 pcb->pcb_dr7 = 0; 1200 if (pcb == PCPU_GET(curpcb)) { 1201 /* 1202 * Clear the debug registers on the running 1203 * CPU, otherwise they will end up affecting 1204 * the next process we switch to. 1205 */ 1206 reset_dbregs(); 1207 } 1208 pcb->pcb_flags &= ~PCB_DBREGS; 1209 } 1210 1211 /* 1212 * Initialize the math emulator (if any) for the current process. 1213 * Actually, just clear the bit that says that the emulator has 1214 * been initialized. Initialization is delayed until the process 1215 * traps to the emulator (if it is done at all) mainly because 1216 * emulators don't provide an entry point for initialization. 1217 */ 1218 td->td_pcb->pcb_flags &= ~FP_SOFTFP; 1219 1220 /* 1221 * Drop the FP state if we hold it, so that the process gets a 1222 * clean FP state if it uses the FPU again. 1223 */ 1224 fpstate_drop(td); 1225 1226 /* 1227 * XXX - Linux emulator 1228 * Make sure sure edx is 0x0 on entry. Linux binaries depend 1229 * on it. 1230 */ 1231 td->td_retval[1] = 0; 1232} 1233 1234void 1235cpu_setregs(void) 1236{ 1237 unsigned int cr0; 1238 1239 cr0 = rcr0(); 1240 1241 /* 1242 * CR0_MP, CR0_NE and CR0_TS are set for NPX (FPU) support: 1243 * 1244 * Prepare to trap all ESC (i.e., NPX) instructions and all WAIT 1245 * instructions. We must set the CR0_MP bit and use the CR0_TS 1246 * bit to control the trap, because setting the CR0_EM bit does 1247 * not cause WAIT instructions to trap. It's important to trap 1248 * WAIT instructions - otherwise the "wait" variants of no-wait 1249 * control instructions would degenerate to the "no-wait" variants 1250 * after FP context switches but work correctly otherwise. It's 1251 * particularly important to trap WAITs when there is no NPX - 1252 * otherwise the "wait" variants would always degenerate. 1253 * 1254 * Try setting CR0_NE to get correct error reporting on 486DX's. 1255 * Setting it should fail or do nothing on lesser processors. 1256 */ 1257 cr0 |= CR0_MP | CR0_NE | CR0_TS | CR0_WP | CR0_AM; 1258 load_cr0(cr0); 1259 load_gs(_udatasel); 1260} 1261 1262u_long bootdev; /* not a struct cdev *- encoding is different */ 1263SYSCTL_ULONG(_machdep, OID_AUTO, guessed_bootdev, 1264 CTLFLAG_RD, &bootdev, 0, "Maybe the Boot device (not in struct cdev *format)"); 1265 1266/* 1267 * Initialize 386 and configure to run kernel 1268 */ 1269 1270/* 1271 * Initialize segments & interrupt table 1272 */ 1273 1274int _default_ldt; 1275union descriptor gdt[NGDT * MAXCPU]; /* global descriptor table */ 1276static struct gate_descriptor idt0[NIDT]; 1277struct gate_descriptor *idt = &idt0[0]; /* interrupt descriptor table */ 1278union descriptor ldt[NLDT]; /* local descriptor table */ 1279struct region_descriptor r_gdt, r_idt; /* table descriptors */ 1280 1281#if defined(I586_CPU) && !defined(NO_F00F_HACK) 1282extern int has_f00f_bug; 1283#endif 1284 1285static struct i386tss dblfault_tss; 1286static char dblfault_stack[PAGE_SIZE]; 1287 1288extern vm_offset_t proc0kstack; 1289 1290 1291/* 1292 * software prototypes -- in more palatable form. 1293 * 1294 * GCODE_SEL through GUDATA_SEL must be in this order for syscall/sysret 1295 * GUFS_SEL and GUGS_SEL must be in this order (swtch.s knows it) 1296 */ 1297struct soft_segment_descriptor gdt_segs[] = { 1298/* GNULL_SEL 0 Null Descriptor */ 1299{ 0x0, /* segment base address */ 1300 0x0, /* length */ 1301 0, /* segment type */ 1302 0, /* segment descriptor priority level */ 1303 0, /* segment descriptor present */ 1304 0, 0, 1305 0, /* default 32 vs 16 bit size */ 1306 0 /* limit granularity (byte/page units)*/ }, 1307/* GPRIV_SEL 1 SMP Per-Processor Private Data Descriptor */ 1308{ 0x0, /* segment base address */ 1309 0xfffff, /* length - all address space */ 1310 SDT_MEMRWA, /* segment type */ 1311 0, /* segment descriptor priority level */ 1312 1, /* segment descriptor present */ 1313 0, 0, 1314 1, /* default 32 vs 16 bit size */ 1315 1 /* limit granularity (byte/page units)*/ }, 1316/* GUFS_SEL 2 %fs Descriptor for user */ 1317{ 0x0, /* segment base address */ 1318 0xfffff, /* length - all address space */ 1319 SDT_MEMRWA, /* segment type */ 1320 SEL_UPL, /* segment descriptor priority level */ 1321 1, /* segment descriptor present */ 1322 0, 0, 1323 1, /* default 32 vs 16 bit size */ 1324 1 /* limit granularity (byte/page units)*/ }, 1325/* GUGS_SEL 3 %gs Descriptor for user */ 1326{ 0x0, /* segment base address */ 1327 0xfffff, /* length - all address space */ 1328 SDT_MEMRWA, /* segment type */ 1329 SEL_UPL, /* segment descriptor priority level */ 1330 1, /* segment descriptor present */ 1331 0, 0, 1332 1, /* default 32 vs 16 bit size */ 1333 1 /* limit granularity (byte/page units)*/ }, 1334/* GCODE_SEL 4 Code Descriptor for kernel */ 1335{ 0x0, /* segment base address */ 1336 0xfffff, /* length - all address space */ 1337 SDT_MEMERA, /* segment type */ 1338 0, /* segment descriptor priority level */ 1339 1, /* segment descriptor present */ 1340 0, 0, 1341 1, /* default 32 vs 16 bit size */ 1342 1 /* limit granularity (byte/page units)*/ }, 1343/* GDATA_SEL 5 Data Descriptor for kernel */ 1344{ 0x0, /* segment base address */ 1345 0xfffff, /* length - all address space */ 1346 SDT_MEMRWA, /* segment type */ 1347 0, /* segment descriptor priority level */ 1348 1, /* segment descriptor present */ 1349 0, 0, 1350 1, /* default 32 vs 16 bit size */ 1351 1 /* limit granularity (byte/page units)*/ }, 1352/* GUCODE_SEL 6 Code Descriptor for user */ 1353{ 0x0, /* segment base address */ 1354 0xfffff, /* length - all address space */ 1355 SDT_MEMERA, /* segment type */ 1356 SEL_UPL, /* segment descriptor priority level */ 1357 1, /* segment descriptor present */ 1358 0, 0, 1359 1, /* default 32 vs 16 bit size */ 1360 1 /* limit granularity (byte/page units)*/ }, 1361/* GUDATA_SEL 7 Data Descriptor for user */ 1362{ 0x0, /* segment base address */ 1363 0xfffff, /* length - all address space */ 1364 SDT_MEMRWA, /* segment type */ 1365 SEL_UPL, /* segment descriptor priority level */ 1366 1, /* segment descriptor present */ 1367 0, 0, 1368 1, /* default 32 vs 16 bit size */ 1369 1 /* limit granularity (byte/page units)*/ }, 1370/* GBIOSLOWMEM_SEL 8 BIOS access to realmode segment 0x40, must be #8 in GDT */ 1371{ 0x400, /* segment base address */ 1372 0xfffff, /* length */ 1373 SDT_MEMRWA, /* segment type */ 1374 0, /* segment descriptor priority level */ 1375 1, /* segment descriptor present */ 1376 0, 0, 1377 1, /* default 32 vs 16 bit size */ 1378 1 /* limit granularity (byte/page units)*/ }, 1379/* GPROC0_SEL 9 Proc 0 Tss Descriptor */ 1380{ 1381 0x0, /* segment base address */ 1382 sizeof(struct i386tss)-1,/* length */ 1383 SDT_SYS386TSS, /* segment type */ 1384 0, /* segment descriptor priority level */ 1385 1, /* segment descriptor present */ 1386 0, 0, 1387 0, /* unused - default 32 vs 16 bit size */ 1388 0 /* limit granularity (byte/page units)*/ }, 1389/* GLDT_SEL 10 LDT Descriptor */ 1390{ (int) ldt, /* segment base address */ 1391 sizeof(ldt)-1, /* length - all address space */ 1392 SDT_SYSLDT, /* segment type */ 1393 SEL_UPL, /* segment descriptor priority level */ 1394 1, /* segment descriptor present */ 1395 0, 0, 1396 0, /* unused - default 32 vs 16 bit size */ 1397 0 /* limit granularity (byte/page units)*/ }, 1398/* GUSERLDT_SEL 11 User LDT Descriptor per process */ 1399{ (int) ldt, /* segment base address */ 1400 (512 * sizeof(union descriptor)-1), /* length */ 1401 SDT_SYSLDT, /* segment type */ 1402 0, /* segment descriptor priority level */ 1403 1, /* segment descriptor present */ 1404 0, 0, 1405 0, /* unused - default 32 vs 16 bit size */ 1406 0 /* limit granularity (byte/page units)*/ }, 1407/* GPANIC_SEL 12 Panic Tss Descriptor */ 1408{ (int) &dblfault_tss, /* segment base address */ 1409 sizeof(struct i386tss)-1,/* length - all address space */ 1410 SDT_SYS386TSS, /* segment type */ 1411 0, /* segment descriptor priority level */ 1412 1, /* segment descriptor present */ 1413 0, 0, 1414 0, /* unused - default 32 vs 16 bit size */ 1415 0 /* limit granularity (byte/page units)*/ }, 1416/* GBIOSCODE32_SEL 13 BIOS 32-bit interface (32bit Code) */ 1417{ 0, /* segment base address (overwritten) */ 1418 0xfffff, /* length */ 1419 SDT_MEMERA, /* segment type */ 1420 0, /* segment descriptor priority level */ 1421 1, /* segment descriptor present */ 1422 0, 0, 1423 0, /* default 32 vs 16 bit size */ 1424 1 /* limit granularity (byte/page units)*/ }, 1425/* GBIOSCODE16_SEL 14 BIOS 32-bit interface (16bit Code) */ 1426{ 0, /* segment base address (overwritten) */ 1427 0xfffff, /* length */ 1428 SDT_MEMERA, /* segment type */ 1429 0, /* segment descriptor priority level */ 1430 1, /* segment descriptor present */ 1431 0, 0, 1432 0, /* default 32 vs 16 bit size */ 1433 1 /* limit granularity (byte/page units)*/ }, 1434/* GBIOSDATA_SEL 15 BIOS 32-bit interface (Data) */ 1435{ 0, /* segment base address (overwritten) */ 1436 0xfffff, /* length */ 1437 SDT_MEMRWA, /* segment type */ 1438 0, /* segment descriptor priority level */ 1439 1, /* segment descriptor present */ 1440 0, 0, 1441 1, /* default 32 vs 16 bit size */ 1442 1 /* limit granularity (byte/page units)*/ }, 1443/* GBIOSUTIL_SEL 16 BIOS 16-bit interface (Utility) */ 1444{ 0, /* segment base address (overwritten) */ 1445 0xfffff, /* length */ 1446 SDT_MEMRWA, /* segment type */ 1447 0, /* segment descriptor priority level */ 1448 1, /* segment descriptor present */ 1449 0, 0, 1450 0, /* default 32 vs 16 bit size */ 1451 1 /* limit granularity (byte/page units)*/ }, 1452/* GBIOSARGS_SEL 17 BIOS 16-bit interface (Arguments) */ 1453{ 0, /* segment base address (overwritten) */ 1454 0xfffff, /* length */ 1455 SDT_MEMRWA, /* segment type */ 1456 0, /* segment descriptor priority level */ 1457 1, /* segment descriptor present */ 1458 0, 0, 1459 0, /* default 32 vs 16 bit size */ 1460 1 /* limit granularity (byte/page units)*/ }, 1461/* GNDIS_SEL 18 NDIS Descriptor */ 1462{ 0x0, /* segment base address */ 1463 0x0, /* length */ 1464 0, /* segment type */ 1465 0, /* segment descriptor priority level */ 1466 0, /* segment descriptor present */ 1467 0, 0, 1468 0, /* default 32 vs 16 bit size */ 1469 0 /* limit granularity (byte/page units)*/ }, 1470}; 1471 1472static struct soft_segment_descriptor ldt_segs[] = { 1473 /* Null Descriptor - overwritten by call gate */ 1474{ 0x0, /* segment base address */ 1475 0x0, /* length - all address space */ 1476 0, /* segment type */ 1477 0, /* segment descriptor priority level */ 1478 0, /* segment descriptor present */ 1479 0, 0, 1480 0, /* default 32 vs 16 bit size */ 1481 0 /* limit granularity (byte/page units)*/ }, 1482 /* Null Descriptor - overwritten by call gate */ 1483{ 0x0, /* segment base address */ 1484 0x0, /* length - all address space */ 1485 0, /* segment type */ 1486 0, /* segment descriptor priority level */ 1487 0, /* segment descriptor present */ 1488 0, 0, 1489 0, /* default 32 vs 16 bit size */ 1490 0 /* limit granularity (byte/page units)*/ }, 1491 /* Null Descriptor - overwritten by call gate */ 1492{ 0x0, /* segment base address */ 1493 0x0, /* length - all address space */ 1494 0, /* segment type */ 1495 0, /* segment descriptor priority level */ 1496 0, /* segment descriptor present */ 1497 0, 0, 1498 0, /* default 32 vs 16 bit size */ 1499 0 /* limit granularity (byte/page units)*/ }, 1500 /* Code Descriptor for user */ 1501{ 0x0, /* segment base address */ 1502 0xfffff, /* length - all address space */ 1503 SDT_MEMERA, /* segment type */ 1504 SEL_UPL, /* segment descriptor priority level */ 1505 1, /* segment descriptor present */ 1506 0, 0, 1507 1, /* default 32 vs 16 bit size */ 1508 1 /* limit granularity (byte/page units)*/ }, 1509 /* Null Descriptor - overwritten by call gate */ 1510{ 0x0, /* segment base address */ 1511 0x0, /* length - all address space */ 1512 0, /* segment type */ 1513 0, /* segment descriptor priority level */ 1514 0, /* segment descriptor present */ 1515 0, 0, 1516 0, /* default 32 vs 16 bit size */ 1517 0 /* limit granularity (byte/page units)*/ }, 1518 /* Data Descriptor for user */ 1519{ 0x0, /* segment base address */ 1520 0xfffff, /* length - all address space */ 1521 SDT_MEMRWA, /* segment type */ 1522 SEL_UPL, /* segment descriptor priority level */ 1523 1, /* segment descriptor present */ 1524 0, 0, 1525 1, /* default 32 vs 16 bit size */ 1526 1 /* limit granularity (byte/page units)*/ }, 1527}; 1528 1529void 1530setidt(idx, func, typ, dpl, selec) 1531 int idx; 1532 inthand_t *func; 1533 int typ; 1534 int dpl; 1535 int selec; 1536{ 1537 struct gate_descriptor *ip; 1538 1539 ip = idt + idx; 1540 ip->gd_looffset = (int)func; 1541 ip->gd_selector = selec; 1542 ip->gd_stkcpy = 0; 1543 ip->gd_xx = 0; 1544 ip->gd_type = typ; 1545 ip->gd_dpl = dpl; 1546 ip->gd_p = 1; 1547 ip->gd_hioffset = ((int)func)>>16 ; 1548} 1549 1550extern inthand_t 1551 IDTVEC(div), IDTVEC(dbg), IDTVEC(nmi), IDTVEC(bpt), IDTVEC(ofl), 1552 IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm), 1553 IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot), 1554 IDTVEC(page), IDTVEC(mchk), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align), 1555 IDTVEC(xmm), IDTVEC(lcall_syscall), IDTVEC(int0x80_syscall); 1556 1557#ifdef DDB 1558/* 1559 * Display the index and function name of any IDT entries that don't use 1560 * the default 'rsvd' entry point. 1561 */ 1562DB_SHOW_COMMAND(idt, db_show_idt) 1563{ 1564 struct gate_descriptor *ip; 1565 int idx; 1566 uintptr_t func; 1567 1568 ip = idt; 1569 for (idx = 0; idx < NIDT && !db_pager_quit; idx++) { 1570 func = (ip->gd_hioffset << 16 | ip->gd_looffset); 1571 if (func != (uintptr_t)&IDTVEC(rsvd)) { 1572 db_printf("%3d\t", idx); 1573 db_printsym(func, DB_STGY_PROC); 1574 db_printf("\n"); 1575 } 1576 ip++; 1577 } 1578} 1579#endif 1580 1581void 1582sdtossd(sd, ssd) 1583 struct segment_descriptor *sd; 1584 struct soft_segment_descriptor *ssd; 1585{ 1586 ssd->ssd_base = (sd->sd_hibase << 24) | sd->sd_lobase; 1587 ssd->ssd_limit = (sd->sd_hilimit << 16) | sd->sd_lolimit; 1588 ssd->ssd_type = sd->sd_type; 1589 ssd->ssd_dpl = sd->sd_dpl; 1590 ssd->ssd_p = sd->sd_p; 1591 ssd->ssd_def32 = sd->sd_def32; 1592 ssd->ssd_gran = sd->sd_gran; 1593} 1594 1595/* 1596 * Populate the (physmap) array with base/bound pairs describing the 1597 * available physical memory in the system, then test this memory and 1598 * build the phys_avail array describing the actually-available memory. 1599 * 1600 * If we cannot accurately determine the physical memory map, then use 1601 * value from the 0xE801 call, and failing that, the RTC. 1602 * 1603 * Total memory size may be set by the kernel environment variable 1604 * hw.physmem or the compile-time define MAXMEM. 1605 * 1606 * XXX first should be vm_paddr_t. 1607 */ 1608static void 1609getmemsize(int first) 1610{ 1611 int i, off, physmap_idx, pa_indx, da_indx; 1612 int hasbrokenint12, has_smap; 1613 u_long physmem_tunable; 1614 u_int extmem; 1615 struct vm86frame vmf; 1616 struct vm86context vmc; 1617 vm_paddr_t pa, physmap[PHYSMAP_SIZE]; 1618 pt_entry_t *pte; 1619 struct bios_smap *smap; 1620 quad_t dcons_addr, dcons_size; 1621 1622 has_smap = 0; 1623#ifdef XBOX 1624 if (arch_i386_is_xbox) { 1625 /* 1626 * We queried the memory size before, so chop off 4MB for 1627 * the framebuffer and inform the OS of this. 1628 */ 1629 physmap[0] = 0; 1630 physmap[1] = (arch_i386_xbox_memsize * 1024 * 1024) - XBOX_FB_SIZE; 1631 physmap_idx = 0; 1632 goto physmap_done; 1633 } 1634#endif 1635 1636 hasbrokenint12 = 0; 1637 TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12); 1638 bzero(&vmf, sizeof(vmf)); 1639 bzero(physmap, sizeof(physmap)); 1640 basemem = 0; 1641 1642 /* 1643 * Some newer BIOSes has broken INT 12H implementation which cause 1644 * kernel panic immediately. In this case, we need to scan SMAP 1645 * with INT 15:E820 first, then determine base memory size. 1646 */ 1647 if (hasbrokenint12) { 1648 goto int15e820; 1649 } 1650 1651 /* 1652 * Perform "base memory" related probes & setup 1653 */ 1654 vm86_intcall(0x12, &vmf); 1655 basemem = vmf.vmf_ax; 1656 if (basemem > 640) { 1657 printf("Preposterous BIOS basemem of %uK, truncating to 640K\n", 1658 basemem); 1659 basemem = 640; 1660 } 1661 1662 /* 1663 * XXX if biosbasemem is now < 640, there is a `hole' 1664 * between the end of base memory and the start of 1665 * ISA memory. The hole may be empty or it may 1666 * contain BIOS code or data. Map it read/write so 1667 * that the BIOS can write to it. (Memory from 0 to 1668 * the physical end of the kernel is mapped read-only 1669 * to begin with and then parts of it are remapped. 1670 * The parts that aren't remapped form holes that 1671 * remain read-only and are unused by the kernel. 1672 * The base memory area is below the physical end of 1673 * the kernel and right now forms a read-only hole. 1674 * The part of it from PAGE_SIZE to 1675 * (trunc_page(biosbasemem * 1024) - 1) will be 1676 * remapped and used by the kernel later.) 1677 * 1678 * This code is similar to the code used in 1679 * pmap_mapdev, but since no memory needs to be 1680 * allocated we simply change the mapping. 1681 */ 1682 for (pa = trunc_page(basemem * 1024); 1683 pa < ISA_HOLE_START; pa += PAGE_SIZE) 1684 pmap_kenter(KERNBASE + pa, pa); 1685 1686 /* 1687 * Map pages between basemem and ISA_HOLE_START, if any, r/w into 1688 * the vm86 page table so that vm86 can scribble on them using 1689 * the vm86 map too. XXX: why 2 ways for this and only 1 way for 1690 * page 0, at least as initialized here? 1691 */ 1692 pte = (pt_entry_t *)vm86paddr; 1693 for (i = basemem / 4; i < 160; i++) 1694 pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U; 1695 1696int15e820: 1697 /* 1698 * map page 1 R/W into the kernel page table so we can use it 1699 * as a buffer. The kernel will unmap this page later. 1700 */ 1701 pmap_kenter(KERNBASE + (1 << PAGE_SHIFT), 1 << PAGE_SHIFT); 1702 1703 /* 1704 * get memory map with INT 15:E820 1705 */ 1706 vmc.npages = 0; 1707 smap = (void *)vm86_addpage(&vmc, 1, KERNBASE + (1 << PAGE_SHIFT)); 1708 vm86_getptr(&vmc, (vm_offset_t)smap, &vmf.vmf_es, &vmf.vmf_di); 1709 1710 physmap_idx = 0; 1711 vmf.vmf_ebx = 0; 1712 do { 1713 vmf.vmf_eax = 0xE820; 1714 vmf.vmf_edx = SMAP_SIG; 1715 vmf.vmf_ecx = sizeof(struct bios_smap); 1716 i = vm86_datacall(0x15, &vmf, &vmc); 1717 if (i || vmf.vmf_eax != SMAP_SIG) 1718 break; 1719 if (boothowto & RB_VERBOSE) 1720 printf("SMAP type=%02x base=%016llx len=%016llx\n", 1721 smap->type, smap->base, smap->length); 1722 has_smap = 1; 1723 1724 if (smap->type != 0x01) 1725 continue; 1726 1727 if (smap->length == 0) 1728 continue; 1729 1730#ifndef PAE 1731 if (smap->base >= 0xffffffff) { 1732 printf("%uK of memory above 4GB ignored\n", 1733 (u_int)(smap->length / 1024)); 1734 continue; 1735 } 1736#endif 1737 1738 for (i = 0; i <= physmap_idx; i += 2) { 1739 if (smap->base < physmap[i + 1]) { 1740 if (boothowto & RB_VERBOSE) 1741 printf( 1742 "Overlapping or non-monotonic memory region, ignoring second region\n"); 1743 continue; 1744 } 1745 } 1746 1747 if (smap->base == physmap[physmap_idx + 1]) { 1748 physmap[physmap_idx + 1] += smap->length; 1749 continue; 1750 } 1751 1752 physmap_idx += 2; 1753 if (physmap_idx == PHYSMAP_SIZE) { 1754 printf( 1755 "Too many segments in the physical address map, giving up\n"); 1756 break; 1757 } 1758 physmap[physmap_idx] = smap->base; 1759 physmap[physmap_idx + 1] = smap->base + smap->length; 1760 } while (vmf.vmf_ebx != 0); 1761 1762 /* 1763 * Perform "base memory" related probes & setup based on SMAP 1764 */ 1765 if (basemem == 0) { 1766 for (i = 0; i <= physmap_idx; i += 2) { 1767 if (physmap[i] == 0x00000000) { 1768 basemem = physmap[i + 1] / 1024; 1769 break; 1770 } 1771 } 1772 1773 /* 1774 * XXX this function is horribly organized and has to the same 1775 * things that it does above here. 1776 */ 1777 if (basemem == 0) 1778 basemem = 640; 1779 if (basemem > 640) { 1780 printf( 1781 "Preposterous BIOS basemem of %uK, truncating to 640K\n", 1782 basemem); 1783 basemem = 640; 1784 } 1785 1786 /* 1787 * Let vm86 scribble on pages between basemem and 1788 * ISA_HOLE_START, as above. 1789 */ 1790 for (pa = trunc_page(basemem * 1024); 1791 pa < ISA_HOLE_START; pa += PAGE_SIZE) 1792 pmap_kenter(KERNBASE + pa, pa); 1793 pte = (pt_entry_t *)vm86paddr; 1794 for (i = basemem / 4; i < 160; i++) 1795 pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U; 1796 } 1797 1798 if (physmap[1] != 0) 1799 goto physmap_done; 1800 1801 /* 1802 * If we failed above, try memory map with INT 15:E801 1803 */ 1804 vmf.vmf_ax = 0xE801; 1805 if (vm86_intcall(0x15, &vmf) == 0) { 1806 extmem = vmf.vmf_cx + vmf.vmf_dx * 64; 1807 } else { 1808#if 0 1809 vmf.vmf_ah = 0x88; 1810 vm86_intcall(0x15, &vmf); 1811 extmem = vmf.vmf_ax; 1812#else 1813 /* 1814 * Prefer the RTC value for extended memory. 1815 */ 1816 extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8); 1817#endif 1818 } 1819 1820 /* 1821 * Special hack for chipsets that still remap the 384k hole when 1822 * there's 16MB of memory - this really confuses people that 1823 * are trying to use bus mastering ISA controllers with the 1824 * "16MB limit"; they only have 16MB, but the remapping puts 1825 * them beyond the limit. 1826 * 1827 * If extended memory is between 15-16MB (16-17MB phys address range), 1828 * chop it to 15MB. 1829 */ 1830 if ((extmem > 15 * 1024) && (extmem < 16 * 1024)) 1831 extmem = 15 * 1024; 1832 1833 physmap[0] = 0; 1834 physmap[1] = basemem * 1024; 1835 physmap_idx = 2; 1836 physmap[physmap_idx] = 0x100000; 1837 physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024; 1838 1839physmap_done: 1840 /* 1841 * Now, physmap contains a map of physical memory. 1842 */ 1843 1844#ifdef SMP 1845 /* make hole for AP bootstrap code */ 1846 physmap[1] = mp_bootaddress(physmap[1]); 1847#endif 1848 1849 /* 1850 * Maxmem isn't the "maximum memory", it's one larger than the 1851 * highest page of the physical address space. It should be 1852 * called something like "Maxphyspage". We may adjust this 1853 * based on ``hw.physmem'' and the results of the memory test. 1854 */ 1855 Maxmem = atop(physmap[physmap_idx + 1]); 1856 1857#ifdef MAXMEM 1858 Maxmem = MAXMEM / 4; 1859#endif 1860 1861 if (TUNABLE_ULONG_FETCH("hw.physmem", &physmem_tunable)) 1862 Maxmem = atop(physmem_tunable); 1863 1864 /* 1865 * If we have an SMAP, don't allow MAXMEM or hw.physmem to extend 1866 * the amount of memory in the system. 1867 */ 1868 if (has_smap && Maxmem > atop(physmap[physmap_idx + 1])) 1869 Maxmem = atop(physmap[physmap_idx + 1]); 1870 1871 if (atop(physmap[physmap_idx + 1]) != Maxmem && 1872 (boothowto & RB_VERBOSE)) 1873 printf("Physical memory use set to %ldK\n", Maxmem * 4); 1874 1875 /* 1876 * If Maxmem has been increased beyond what the system has detected, 1877 * extend the last memory segment to the new limit. 1878 */ 1879 if (atop(physmap[physmap_idx + 1]) < Maxmem) 1880 physmap[physmap_idx + 1] = ptoa((vm_paddr_t)Maxmem); 1881 1882 /* call pmap initialization to make new kernel address space */ 1883 pmap_bootstrap(first, 0); 1884 1885 /* 1886 * Size up each available chunk of physical memory. 1887 */ 1888 physmap[0] = PAGE_SIZE; /* mask off page 0 */ 1889 pa_indx = 0; 1890 da_indx = 1; 1891 phys_avail[pa_indx++] = physmap[0]; 1892 phys_avail[pa_indx] = physmap[0]; 1893 dump_avail[da_indx] = physmap[0]; 1894 pte = CMAP1; 1895 1896 /* 1897 * Get dcons buffer address 1898 */ 1899 if (getenv_quad("dcons.addr", &dcons_addr) == 0 || 1900 getenv_quad("dcons.size", &dcons_size) == 0) 1901 dcons_addr = 0; 1902 1903 /* 1904 * physmap is in bytes, so when converting to page boundaries, 1905 * round up the start address and round down the end address. 1906 */ 1907 for (i = 0; i <= physmap_idx; i += 2) { 1908 vm_paddr_t end; 1909 1910 end = ptoa((vm_paddr_t)Maxmem); 1911 if (physmap[i + 1] < end) 1912 end = trunc_page(physmap[i + 1]); 1913 for (pa = round_page(physmap[i]); pa < end; pa += PAGE_SIZE) { 1914 int tmp, page_bad, full; 1915 int *ptr = (int *)CADDR1; 1916 1917 full = FALSE; 1918 /* 1919 * block out kernel memory as not available. 1920 */ 1921 if (pa >= KERNLOAD && pa < first) 1922 goto do_dump_avail; 1923 1924 /* 1925 * block out dcons buffer 1926 */ 1927 if (dcons_addr > 0 1928 && pa >= trunc_page(dcons_addr) 1929 && pa < dcons_addr + dcons_size) 1930 goto do_dump_avail; 1931 1932 page_bad = FALSE; 1933 1934 /* 1935 * map page into kernel: valid, read/write,non-cacheable 1936 */ 1937 *pte = pa | PG_V | PG_RW | PG_N; 1938 invltlb(); 1939 1940 tmp = *(int *)ptr; 1941 /* 1942 * Test for alternating 1's and 0's 1943 */ 1944 *(volatile int *)ptr = 0xaaaaaaaa; 1945 if (*(volatile int *)ptr != 0xaaaaaaaa) 1946 page_bad = TRUE; 1947 /* 1948 * Test for alternating 0's and 1's 1949 */ 1950 *(volatile int *)ptr = 0x55555555; 1951 if (*(volatile int *)ptr != 0x55555555) 1952 page_bad = TRUE; 1953 /* 1954 * Test for all 1's 1955 */ 1956 *(volatile int *)ptr = 0xffffffff; 1957 if (*(volatile int *)ptr != 0xffffffff) 1958 page_bad = TRUE; 1959 /* 1960 * Test for all 0's 1961 */ 1962 *(volatile int *)ptr = 0x0; 1963 if (*(volatile int *)ptr != 0x0) 1964 page_bad = TRUE; 1965 /* 1966 * Restore original value. 1967 */ 1968 *(int *)ptr = tmp; 1969 1970 /* 1971 * Adjust array of valid/good pages. 1972 */ 1973 if (page_bad == TRUE) 1974 continue; 1975 /* 1976 * If this good page is a continuation of the 1977 * previous set of good pages, then just increase 1978 * the end pointer. Otherwise start a new chunk. 1979 * Note that "end" points one higher than end, 1980 * making the range >= start and < end. 1981 * If we're also doing a speculative memory 1982 * test and we at or past the end, bump up Maxmem 1983 * so that we keep going. The first bad page 1984 * will terminate the loop. 1985 */ 1986 if (phys_avail[pa_indx] == pa) { 1987 phys_avail[pa_indx] += PAGE_SIZE; 1988 } else { 1989 pa_indx++; 1990 if (pa_indx == PHYS_AVAIL_ARRAY_END) { 1991 printf( 1992 "Too many holes in the physical address space, giving up\n"); 1993 pa_indx--; 1994 full = TRUE; 1995 goto do_dump_avail; 1996 } 1997 phys_avail[pa_indx++] = pa; /* start */ 1998 phys_avail[pa_indx] = pa + PAGE_SIZE; /* end */ 1999 } 2000 physmem++; 2001do_dump_avail: 2002 if (dump_avail[da_indx] == pa) { 2003 dump_avail[da_indx] += PAGE_SIZE; 2004 } else { 2005 da_indx++; 2006 if (da_indx == DUMP_AVAIL_ARRAY_END) { 2007 da_indx--; 2008 goto do_next; 2009 } 2010 dump_avail[da_indx++] = pa; /* start */ 2011 dump_avail[da_indx] = pa + PAGE_SIZE; /* end */ 2012 } 2013do_next: 2014 if (full) 2015 break; 2016 } 2017 } 2018 *pte = 0; 2019 invltlb(); 2020 2021 /* 2022 * XXX 2023 * The last chunk must contain at least one page plus the message 2024 * buffer to avoid complicating other code (message buffer address 2025 * calculation, etc.). 2026 */ 2027 while (phys_avail[pa_indx - 1] + PAGE_SIZE + 2028 round_page(MSGBUF_SIZE) >= phys_avail[pa_indx]) { 2029 physmem -= atop(phys_avail[pa_indx] - phys_avail[pa_indx - 1]); 2030 phys_avail[pa_indx--] = 0; 2031 phys_avail[pa_indx--] = 0; 2032 } 2033 2034 Maxmem = atop(phys_avail[pa_indx]); 2035 2036 /* Trim off space for the message buffer. */ 2037 phys_avail[pa_indx] -= round_page(MSGBUF_SIZE); 2038 2039 /* Map the message buffer. */ 2040 for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) 2041 pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] + 2042 off); 2043} 2044 2045void 2046init386(first) 2047 int first; 2048{ 2049 struct gate_descriptor *gdp; 2050 int gsel_tss, metadata_missing, x; 2051 struct pcpu *pc; 2052 2053 thread0.td_kstack = proc0kstack; 2054 thread0.td_pcb = (struct pcb *) 2055 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 2056 2057 /* 2058 * This may be done better later if it gets more high level 2059 * components in it. If so just link td->td_proc here. 2060 */ 2061 proc_linkup(&proc0, &thread0); 2062 2063 metadata_missing = 0; 2064 if (bootinfo.bi_modulep) { 2065 preload_metadata = (caddr_t)bootinfo.bi_modulep + KERNBASE; 2066 preload_bootstrap_relocate(KERNBASE); 2067 } else { 2068 metadata_missing = 1; 2069 } 2070 if (envmode == 1) 2071 kern_envp = static_env; 2072 else if (bootinfo.bi_envp) 2073 kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE; 2074 2075 /* Init basic tunables, hz etc */ 2076 init_param1(); 2077 2078 /* 2079 * Make gdt memory segments. All segments cover the full 4GB 2080 * of address space and permissions are enforced at page level. 2081 */ 2082 gdt_segs[GCODE_SEL].ssd_limit = atop(0 - 1); 2083 gdt_segs[GDATA_SEL].ssd_limit = atop(0 - 1); 2084 gdt_segs[GUCODE_SEL].ssd_limit = atop(0 - 1); 2085 gdt_segs[GUDATA_SEL].ssd_limit = atop(0 - 1); 2086 gdt_segs[GUFS_SEL].ssd_limit = atop(0 - 1); 2087 gdt_segs[GUGS_SEL].ssd_limit = atop(0 - 1); 2088 2089#ifdef SMP 2090 pc = &SMP_prvspace[0].pcpu; 2091#else 2092 pc = &__pcpu; 2093#endif 2094 gdt_segs[GPRIV_SEL].ssd_limit = atop(0 - 1); 2095 gdt_segs[GPRIV_SEL].ssd_base = (int) pc; 2096 gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss; 2097 2098 for (x = 0; x < NGDT; x++) 2099 ssdtosd(&gdt_segs[x], &gdt[x].sd); 2100 2101 r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1; 2102 r_gdt.rd_base = (int) gdt; 2103 lgdt(&r_gdt); 2104 2105 pcpu_init(pc, 0, sizeof(struct pcpu)); 2106 PCPU_SET(prvspace, pc); 2107 PCPU_SET(curthread, &thread0); 2108 PCPU_SET(curpcb, thread0.td_pcb); 2109 2110 /* 2111 * Initialize mutexes. 2112 * 2113 * icu_lock: in order to allow an interrupt to occur in a critical 2114 * section, to set pcpu->ipending (etc...) properly, we 2115 * must be able to get the icu lock, so it can't be 2116 * under witness. 2117 */ 2118 mutex_init(); 2119 mtx_init(&clock_lock, "clk", NULL, MTX_SPIN); 2120 mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS); 2121 2122 /* make ldt memory segments */ 2123 ldt_segs[LUCODE_SEL].ssd_limit = atop(0 - 1); 2124 ldt_segs[LUDATA_SEL].ssd_limit = atop(0 - 1); 2125 for (x = 0; x < sizeof ldt_segs / sizeof ldt_segs[0]; x++) 2126 ssdtosd(&ldt_segs[x], &ldt[x].sd); 2127 2128 _default_ldt = GSEL(GLDT_SEL, SEL_KPL); 2129 lldt(_default_ldt); 2130 PCPU_SET(currentldt, _default_ldt); 2131 2132 /* exceptions */ 2133 for (x = 0; x < NIDT; x++) 2134 setidt(x, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, 2135 GSEL(GCODE_SEL, SEL_KPL)); 2136 setidt(IDT_DE, &IDTVEC(div), SDT_SYS386TGT, SEL_KPL, 2137 GSEL(GCODE_SEL, SEL_KPL)); 2138 setidt(IDT_DB, &IDTVEC(dbg), SDT_SYS386IGT, SEL_KPL, 2139 GSEL(GCODE_SEL, SEL_KPL)); 2140 setidt(IDT_NMI, &IDTVEC(nmi), SDT_SYS386IGT, SEL_KPL, 2141 GSEL(GCODE_SEL, SEL_KPL)); 2142 setidt(IDT_BP, &IDTVEC(bpt), SDT_SYS386IGT, SEL_UPL, 2143 GSEL(GCODE_SEL, SEL_KPL)); 2144 setidt(IDT_OF, &IDTVEC(ofl), SDT_SYS386TGT, SEL_UPL, 2145 GSEL(GCODE_SEL, SEL_KPL)); 2146 setidt(IDT_BR, &IDTVEC(bnd), SDT_SYS386TGT, SEL_KPL, 2147 GSEL(GCODE_SEL, SEL_KPL)); 2148 setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, 2149 GSEL(GCODE_SEL, SEL_KPL)); 2150 setidt(IDT_NM, &IDTVEC(dna), SDT_SYS386TGT, SEL_KPL 2151 , GSEL(GCODE_SEL, SEL_KPL)); 2152 setidt(IDT_DF, 0, SDT_SYSTASKGT, SEL_KPL, GSEL(GPANIC_SEL, SEL_KPL)); 2153 setidt(IDT_FPUGP, &IDTVEC(fpusegm), SDT_SYS386TGT, SEL_KPL, 2154 GSEL(GCODE_SEL, SEL_KPL)); 2155 setidt(IDT_TS, &IDTVEC(tss), SDT_SYS386TGT, SEL_KPL, 2156 GSEL(GCODE_SEL, SEL_KPL)); 2157 setidt(IDT_NP, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, 2158 GSEL(GCODE_SEL, SEL_KPL)); 2159 setidt(IDT_SS, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, 2160 GSEL(GCODE_SEL, SEL_KPL)); 2161 setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, 2162 GSEL(GCODE_SEL, SEL_KPL)); 2163 setidt(IDT_PF, &IDTVEC(page), SDT_SYS386IGT, SEL_KPL, 2164 GSEL(GCODE_SEL, SEL_KPL)); 2165 setidt(IDT_MF, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL, 2166 GSEL(GCODE_SEL, SEL_KPL)); 2167 setidt(IDT_AC, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, 2168 GSEL(GCODE_SEL, SEL_KPL)); 2169 setidt(IDT_MC, &IDTVEC(mchk), SDT_SYS386TGT, SEL_KPL, 2170 GSEL(GCODE_SEL, SEL_KPL)); 2171 setidt(IDT_XF, &IDTVEC(xmm), SDT_SYS386TGT, SEL_KPL, 2172 GSEL(GCODE_SEL, SEL_KPL)); 2173 setidt(IDT_SYSCALL, &IDTVEC(int0x80_syscall), SDT_SYS386TGT, SEL_UPL, 2174 GSEL(GCODE_SEL, SEL_KPL)); 2175 2176 r_idt.rd_limit = sizeof(idt0) - 1; 2177 r_idt.rd_base = (int) idt; 2178 lidt(&r_idt); 2179 2180#ifdef XBOX 2181 /* 2182 * The following code queries the PCI ID of 0:0:0. For the XBOX, 2183 * This should be 0x10de / 0x02a5. 2184 * 2185 * This is exactly what Linux does. 2186 */ 2187 outl(0xcf8, 0x80000000); 2188 if (inl(0xcfc) == 0x02a510de) { 2189 arch_i386_is_xbox = 1; 2190 pic16l_setled(XBOX_LED_GREEN); 2191 2192 /* 2193 * We are an XBOX, but we may have either 64MB or 128MB of 2194 * memory. The PCI host bridge should be programmed for this, 2195 * so we just query it. 2196 */ 2197 outl(0xcf8, 0x80000084); 2198 arch_i386_xbox_memsize = (inl(0xcfc) == 0x7FFFFFF) ? 128 : 64; 2199 } 2200#endif /* XBOX */ 2201 2202 /* 2203 * Initialize the console before we print anything out. 2204 */ 2205 cninit(); 2206 2207 if (metadata_missing) 2208 printf("WARNING: loader(8) metadata is missing!\n"); 2209 2210#ifdef DEV_ISA 2211 elcr_probe(); 2212 atpic_startup(); 2213#endif 2214 2215#ifdef DDB 2216 ksym_start = bootinfo.bi_symtab; 2217 ksym_end = bootinfo.bi_esymtab; 2218#endif 2219 2220 kdb_init(); 2221 2222#ifdef KDB 2223 if (boothowto & RB_KDB) 2224 kdb_enter("Boot flags requested debugger"); 2225#endif 2226 2227 finishidentcpu(); /* Final stage of CPU initialization */ 2228 setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, 2229 GSEL(GCODE_SEL, SEL_KPL)); 2230 setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, 2231 GSEL(GCODE_SEL, SEL_KPL)); 2232 initializecpu(); /* Initialize CPU registers */ 2233 2234 /* make an initial tss so cpu can get interrupt stack on syscall! */ 2235 /* Note: -16 is so we can grow the trapframe if we came from vm86 */ 2236 PCPU_SET(common_tss.tss_esp0, thread0.td_kstack + 2237 KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb) - 16); 2238 PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL)); 2239 gsel_tss = GSEL(GPROC0_SEL, SEL_KPL); 2240 PCPU_SET(tss_gdt, &gdt[GPROC0_SEL].sd); 2241 PCPU_SET(common_tssd, *PCPU_GET(tss_gdt)); 2242 PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16); 2243 ltr(gsel_tss); 2244 2245 /* pointer to selector slot for %fs/%gs */ 2246 PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd); 2247 2248 dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = 2249 dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)]; 2250 dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = 2251 dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); 2252#ifdef PAE 2253 dblfault_tss.tss_cr3 = (int)IdlePDPT; 2254#else 2255 dblfault_tss.tss_cr3 = (int)IdlePTD; 2256#endif 2257 dblfault_tss.tss_eip = (int)dblfault_handler; 2258 dblfault_tss.tss_eflags = PSL_KERNEL; 2259 dblfault_tss.tss_ds = dblfault_tss.tss_es = 2260 dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL); 2261 dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL); 2262 dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); 2263 dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); 2264 2265 vm86_initialize(); 2266 getmemsize(first); 2267 init_param2(physmem); 2268 2269 /* now running on new page tables, configured,and u/iom is accessible */ 2270 2271 msgbufinit(msgbufp, MSGBUF_SIZE); 2272 2273 /* make a call gate to reenter kernel with */ 2274 gdp = &ldt[LSYS5CALLS_SEL].gd; 2275 2276 x = (int) &IDTVEC(lcall_syscall); 2277 gdp->gd_looffset = x; 2278 gdp->gd_selector = GSEL(GCODE_SEL,SEL_KPL); 2279 gdp->gd_stkcpy = 1; 2280 gdp->gd_type = SDT_SYS386CGT; 2281 gdp->gd_dpl = SEL_UPL; 2282 gdp->gd_p = 1; 2283 gdp->gd_hioffset = x >> 16; 2284 2285 /* XXX does this work? */ 2286 /* XXX yes! */ 2287 ldt[LBSDICALLS_SEL] = ldt[LSYS5CALLS_SEL]; 2288 ldt[LSOL26CALLS_SEL] = ldt[LSYS5CALLS_SEL]; 2289 2290 /* transfer to user mode */ 2291 2292 _ucodesel = GSEL(GUCODE_SEL, SEL_UPL); 2293 _udatasel = GSEL(GUDATA_SEL, SEL_UPL); 2294 2295 /* setup proc 0's pcb */ 2296 thread0.td_pcb->pcb_flags = 0; 2297#ifdef PAE 2298 thread0.td_pcb->pcb_cr3 = (int)IdlePDPT; 2299#else 2300 thread0.td_pcb->pcb_cr3 = (int)IdlePTD; 2301#endif 2302 thread0.td_pcb->pcb_ext = 0; 2303 thread0.td_frame = &proc0_tf; 2304} 2305 2306void 2307cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size) 2308{ 2309 2310 pcpu->pc_acpi_id = 0xffffffff; 2311} 2312 2313void 2314spinlock_enter(void) 2315{ 2316 struct thread *td; 2317 2318 td = curthread; 2319 if (td->td_md.md_spinlock_count == 0) 2320 td->td_md.md_saved_flags = intr_disable(); 2321 td->td_md.md_spinlock_count++; 2322 critical_enter(); 2323} 2324 2325void 2326spinlock_exit(void) 2327{ 2328 struct thread *td; 2329 2330 td = curthread; 2331 critical_exit(); 2332 td->td_md.md_spinlock_count--; 2333 if (td->td_md.md_spinlock_count == 0) 2334 intr_restore(td->td_md.md_saved_flags); 2335} 2336 2337#if defined(I586_CPU) && !defined(NO_F00F_HACK) 2338static void f00f_hack(void *unused); 2339SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL) 2340 2341static void 2342f00f_hack(void *unused) 2343{ 2344 struct gate_descriptor *new_idt; 2345 vm_offset_t tmp; 2346 2347 if (!has_f00f_bug) 2348 return; 2349 2350 GIANT_REQUIRED; 2351 2352 printf("Intel Pentium detected, installing workaround for F00F bug\n"); 2353 2354 tmp = kmem_alloc(kernel_map, PAGE_SIZE * 2); 2355 if (tmp == 0) 2356 panic("kmem_alloc returned 0"); 2357 2358 /* Put the problematic entry (#6) at the end of the lower page. */ 2359 new_idt = (struct gate_descriptor*) 2360 (tmp + PAGE_SIZE - 7 * sizeof(struct gate_descriptor)); 2361 bcopy(idt, new_idt, sizeof(idt0)); 2362 r_idt.rd_base = (u_int)new_idt; 2363 lidt(&r_idt); 2364 idt = new_idt; 2365 if (vm_map_protect(kernel_map, tmp, tmp + PAGE_SIZE, 2366 VM_PROT_READ, FALSE) != KERN_SUCCESS) 2367 panic("vm_map_protect failed"); 2368} 2369#endif /* defined(I586_CPU) && !NO_F00F_HACK */ 2370 2371/* 2372 * Construct a PCB from a trapframe. This is called from kdb_trap() where 2373 * we want to start a backtrace from the function that caused us to enter 2374 * the debugger. We have the context in the trapframe, but base the trace 2375 * on the PCB. The PCB doesn't have to be perfect, as long as it contains 2376 * enough for a backtrace. 2377 */ 2378void 2379makectx(struct trapframe *tf, struct pcb *pcb) 2380{ 2381 2382 pcb->pcb_edi = tf->tf_edi; 2383 pcb->pcb_esi = tf->tf_esi; 2384 pcb->pcb_ebp = tf->tf_ebp; 2385 pcb->pcb_ebx = tf->tf_ebx; 2386 pcb->pcb_eip = tf->tf_eip; 2387 pcb->pcb_esp = (ISPL(tf->tf_cs)) ? tf->tf_esp : (int)(tf + 1) - 8; 2388} 2389 2390int 2391ptrace_set_pc(struct thread *td, u_long addr) 2392{ 2393 2394 td->td_frame->tf_eip = addr; 2395 return (0); 2396} 2397 2398int 2399ptrace_single_step(struct thread *td) 2400{ 2401 td->td_frame->tf_eflags |= PSL_T; 2402 return (0); 2403} 2404 2405int 2406ptrace_clear_single_step(struct thread *td) 2407{ 2408 td->td_frame->tf_eflags &= ~PSL_T; 2409 return (0); 2410} 2411 2412int 2413fill_regs(struct thread *td, struct reg *regs) 2414{ 2415 struct pcb *pcb; 2416 struct trapframe *tp; 2417 2418 tp = td->td_frame; 2419 pcb = td->td_pcb; 2420 regs->r_fs = tp->tf_fs; 2421 regs->r_es = tp->tf_es; 2422 regs->r_ds = tp->tf_ds; 2423 regs->r_edi = tp->tf_edi; 2424 regs->r_esi = tp->tf_esi; 2425 regs->r_ebp = tp->tf_ebp; 2426 regs->r_ebx = tp->tf_ebx; 2427 regs->r_edx = tp->tf_edx; 2428 regs->r_ecx = tp->tf_ecx; 2429 regs->r_eax = tp->tf_eax; 2430 regs->r_eip = tp->tf_eip; 2431 regs->r_cs = tp->tf_cs; 2432 regs->r_eflags = tp->tf_eflags; 2433 regs->r_esp = tp->tf_esp; 2434 regs->r_ss = tp->tf_ss; 2435 regs->r_gs = pcb->pcb_gs; 2436 return (0); 2437} 2438 2439int 2440set_regs(struct thread *td, struct reg *regs) 2441{ 2442 struct pcb *pcb; 2443 struct trapframe *tp; 2444 2445 tp = td->td_frame; 2446 if (!EFL_SECURE(regs->r_eflags, tp->tf_eflags) || 2447 !CS_SECURE(regs->r_cs)) 2448 return (EINVAL); 2449 pcb = td->td_pcb; 2450 tp->tf_fs = regs->r_fs; 2451 tp->tf_es = regs->r_es; 2452 tp->tf_ds = regs->r_ds; 2453 tp->tf_edi = regs->r_edi; 2454 tp->tf_esi = regs->r_esi; 2455 tp->tf_ebp = regs->r_ebp; 2456 tp->tf_ebx = regs->r_ebx; 2457 tp->tf_edx = regs->r_edx; 2458 tp->tf_ecx = regs->r_ecx; 2459 tp->tf_eax = regs->r_eax; 2460 tp->tf_eip = regs->r_eip; 2461 tp->tf_cs = regs->r_cs; 2462 tp->tf_eflags = regs->r_eflags; 2463 tp->tf_esp = regs->r_esp; 2464 tp->tf_ss = regs->r_ss; 2465 pcb->pcb_gs = regs->r_gs; 2466 return (0); 2467} 2468 2469#ifdef CPU_ENABLE_SSE 2470static void 2471fill_fpregs_xmm(sv_xmm, sv_87) 2472 struct savexmm *sv_xmm; 2473 struct save87 *sv_87; 2474{ 2475 register struct env87 *penv_87 = &sv_87->sv_env; 2476 register struct envxmm *penv_xmm = &sv_xmm->sv_env; 2477 int i; 2478 2479 bzero(sv_87, sizeof(*sv_87)); 2480 2481 /* FPU control/status */ 2482 penv_87->en_cw = penv_xmm->en_cw; 2483 penv_87->en_sw = penv_xmm->en_sw; 2484 penv_87->en_tw = penv_xmm->en_tw; 2485 penv_87->en_fip = penv_xmm->en_fip; 2486 penv_87->en_fcs = penv_xmm->en_fcs; 2487 penv_87->en_opcode = penv_xmm->en_opcode; 2488 penv_87->en_foo = penv_xmm->en_foo; 2489 penv_87->en_fos = penv_xmm->en_fos; 2490 2491 /* FPU registers */ 2492 for (i = 0; i < 8; ++i) 2493 sv_87->sv_ac[i] = sv_xmm->sv_fp[i].fp_acc; 2494} 2495 2496static void 2497set_fpregs_xmm(sv_87, sv_xmm) 2498 struct save87 *sv_87; 2499 struct savexmm *sv_xmm; 2500{ 2501 register struct env87 *penv_87 = &sv_87->sv_env; 2502 register struct envxmm *penv_xmm = &sv_xmm->sv_env; 2503 int i; 2504 2505 /* FPU control/status */ 2506 penv_xmm->en_cw = penv_87->en_cw; 2507 penv_xmm->en_sw = penv_87->en_sw; 2508 penv_xmm->en_tw = penv_87->en_tw; 2509 penv_xmm->en_fip = penv_87->en_fip; 2510 penv_xmm->en_fcs = penv_87->en_fcs; 2511 penv_xmm->en_opcode = penv_87->en_opcode; 2512 penv_xmm->en_foo = penv_87->en_foo; 2513 penv_xmm->en_fos = penv_87->en_fos; 2514 2515 /* FPU registers */ 2516 for (i = 0; i < 8; ++i) 2517 sv_xmm->sv_fp[i].fp_acc = sv_87->sv_ac[i]; 2518} 2519#endif /* CPU_ENABLE_SSE */ 2520 2521int 2522fill_fpregs(struct thread *td, struct fpreg *fpregs) 2523{ 2524#ifdef CPU_ENABLE_SSE 2525 if (cpu_fxsr) { 2526 fill_fpregs_xmm(&td->td_pcb->pcb_save.sv_xmm, 2527 (struct save87 *)fpregs); 2528 return (0); 2529 } 2530#endif /* CPU_ENABLE_SSE */ 2531 bcopy(&td->td_pcb->pcb_save.sv_87, fpregs, sizeof *fpregs); 2532 return (0); 2533} 2534 2535int 2536set_fpregs(struct thread *td, struct fpreg *fpregs) 2537{ 2538#ifdef CPU_ENABLE_SSE 2539 if (cpu_fxsr) { 2540 set_fpregs_xmm((struct save87 *)fpregs, 2541 &td->td_pcb->pcb_save.sv_xmm); 2542 return (0); 2543 } 2544#endif /* CPU_ENABLE_SSE */ 2545 bcopy(fpregs, &td->td_pcb->pcb_save.sv_87, sizeof *fpregs); 2546 return (0); 2547} 2548 2549/* 2550 * Get machine context. 2551 */ 2552int 2553get_mcontext(struct thread *td, mcontext_t *mcp, int flags) 2554{ 2555 struct trapframe *tp; 2556 2557 tp = td->td_frame; 2558 2559 PROC_LOCK(curthread->td_proc); 2560 mcp->mc_onstack = sigonstack(tp->tf_esp); 2561 PROC_UNLOCK(curthread->td_proc); 2562 mcp->mc_gs = td->td_pcb->pcb_gs; 2563 mcp->mc_fs = tp->tf_fs; 2564 mcp->mc_es = tp->tf_es; 2565 mcp->mc_ds = tp->tf_ds; 2566 mcp->mc_edi = tp->tf_edi; 2567 mcp->mc_esi = tp->tf_esi; 2568 mcp->mc_ebp = tp->tf_ebp; 2569 mcp->mc_isp = tp->tf_isp; 2570 mcp->mc_eflags = tp->tf_eflags; 2571 if (flags & GET_MC_CLEAR_RET) { 2572 mcp->mc_eax = 0; 2573 mcp->mc_edx = 0; 2574 mcp->mc_eflags &= ~PSL_C; 2575 } else { 2576 mcp->mc_eax = tp->tf_eax; 2577 mcp->mc_edx = tp->tf_edx; 2578 } 2579 mcp->mc_ebx = tp->tf_ebx; 2580 mcp->mc_ecx = tp->tf_ecx; 2581 mcp->mc_eip = tp->tf_eip; 2582 mcp->mc_cs = tp->tf_cs; 2583 mcp->mc_esp = tp->tf_esp; 2584 mcp->mc_ss = tp->tf_ss; 2585 mcp->mc_len = sizeof(*mcp); 2586 get_fpcontext(td, mcp); 2587 return (0); 2588} 2589 2590/* 2591 * Set machine context. 2592 * 2593 * However, we don't set any but the user modifiable flags, and we won't 2594 * touch the cs selector. 2595 */ 2596int 2597set_mcontext(struct thread *td, const mcontext_t *mcp) 2598{ 2599 struct trapframe *tp; 2600 int eflags, ret; 2601 2602 tp = td->td_frame; 2603 if (mcp->mc_len != sizeof(*mcp)) 2604 return (EINVAL); 2605 eflags = (mcp->mc_eflags & PSL_USERCHANGE) | 2606 (tp->tf_eflags & ~PSL_USERCHANGE); 2607 if ((ret = set_fpcontext(td, mcp)) == 0) { 2608 tp->tf_fs = mcp->mc_fs; 2609 tp->tf_es = mcp->mc_es; 2610 tp->tf_ds = mcp->mc_ds; 2611 tp->tf_edi = mcp->mc_edi; 2612 tp->tf_esi = mcp->mc_esi; 2613 tp->tf_ebp = mcp->mc_ebp; 2614 tp->tf_ebx = mcp->mc_ebx; 2615 tp->tf_edx = mcp->mc_edx; 2616 tp->tf_ecx = mcp->mc_ecx; 2617 tp->tf_eax = mcp->mc_eax; 2618 tp->tf_eip = mcp->mc_eip; 2619 tp->tf_eflags = eflags; 2620 tp->tf_esp = mcp->mc_esp; 2621 tp->tf_ss = mcp->mc_ss; 2622 td->td_pcb->pcb_gs = mcp->mc_gs; 2623 ret = 0; 2624 } 2625 return (ret); 2626} 2627 2628static void 2629get_fpcontext(struct thread *td, mcontext_t *mcp) 2630{ 2631#ifndef DEV_NPX 2632 mcp->mc_fpformat = _MC_FPFMT_NODEV; 2633 mcp->mc_ownedfp = _MC_FPOWNED_NONE; 2634#else 2635 union savefpu *addr; 2636 2637 /* 2638 * XXX mc_fpstate might be misaligned, since its declaration is not 2639 * unportabilized using __attribute__((aligned(16))) like the 2640 * declaration of struct savemm, and anyway, alignment doesn't work 2641 * for auto variables since we don't use gcc's pessimal stack 2642 * alignment. Work around this by abusing the spare fields after 2643 * mcp->mc_fpstate. 2644 * 2645 * XXX unpessimize most cases by only aligning when fxsave might be 2646 * called, although this requires knowing too much about 2647 * npxgetregs()'s internals. 2648 */ 2649 addr = (union savefpu *)&mcp->mc_fpstate; 2650 if (td == PCPU_GET(fpcurthread) && 2651#ifdef CPU_ENABLE_SSE 2652 cpu_fxsr && 2653#endif 2654 ((uintptr_t)(void *)addr & 0xF)) { 2655 do 2656 addr = (void *)((char *)addr + 4); 2657 while ((uintptr_t)(void *)addr & 0xF); 2658 } 2659 mcp->mc_ownedfp = npxgetregs(td, addr); 2660 if (addr != (union savefpu *)&mcp->mc_fpstate) { 2661 bcopy(addr, &mcp->mc_fpstate, sizeof(mcp->mc_fpstate)); 2662 bzero(&mcp->mc_spare2, sizeof(mcp->mc_spare2)); 2663 } 2664 mcp->mc_fpformat = npxformat(); 2665#endif 2666} 2667 2668static int 2669set_fpcontext(struct thread *td, const mcontext_t *mcp) 2670{ 2671 union savefpu *addr; 2672 2673 if (mcp->mc_fpformat == _MC_FPFMT_NODEV) 2674 return (0); 2675 else if (mcp->mc_fpformat != _MC_FPFMT_387 && 2676 mcp->mc_fpformat != _MC_FPFMT_XMM) 2677 return (EINVAL); 2678 else if (mcp->mc_ownedfp == _MC_FPOWNED_NONE) 2679 /* We don't care what state is left in the FPU or PCB. */ 2680 fpstate_drop(td); 2681 else if (mcp->mc_ownedfp == _MC_FPOWNED_FPU || 2682 mcp->mc_ownedfp == _MC_FPOWNED_PCB) { 2683 /* XXX align as above. */ 2684 addr = (union savefpu *)&mcp->mc_fpstate; 2685 if (td == PCPU_GET(fpcurthread) && 2686#ifdef CPU_ENABLE_SSE 2687 cpu_fxsr && 2688#endif 2689 ((uintptr_t)(void *)addr & 0xF)) { 2690 do 2691 addr = (void *)((char *)addr + 4); 2692 while ((uintptr_t)(void *)addr & 0xF); 2693 bcopy(&mcp->mc_fpstate, addr, sizeof(mcp->mc_fpstate)); 2694 } 2695#ifdef DEV_NPX 2696#ifdef CPU_ENABLE_SSE 2697 if (cpu_fxsr) 2698 addr->sv_xmm.sv_env.en_mxcsr &= cpu_mxcsr_mask; 2699#endif 2700 /* 2701 * XXX we violate the dubious requirement that npxsetregs() 2702 * be called with interrupts disabled. 2703 */ 2704 npxsetregs(td, addr); 2705#endif 2706 /* 2707 * Don't bother putting things back where they were in the 2708 * misaligned case, since we know that the caller won't use 2709 * them again. 2710 */ 2711 } else 2712 return (EINVAL); 2713 return (0); 2714} 2715 2716static void 2717fpstate_drop(struct thread *td) 2718{ 2719 register_t s; 2720 2721 s = intr_disable(); 2722#ifdef DEV_NPX 2723 if (PCPU_GET(fpcurthread) == td) 2724 npxdrop(); 2725#endif 2726 /* 2727 * XXX force a full drop of the npx. The above only drops it if we 2728 * owned it. npxgetregs() has the same bug in the !cpu_fxsr case. 2729 * 2730 * XXX I don't much like npxgetregs()'s semantics of doing a full 2731 * drop. Dropping only to the pcb matches fnsave's behaviour. 2732 * We only need to drop to !PCB_INITDONE in sendsig(). But 2733 * sendsig() is the only caller of npxgetregs()... perhaps we just 2734 * have too many layers. 2735 */ 2736 curthread->td_pcb->pcb_flags &= ~PCB_NPXINITDONE; 2737 intr_restore(s); 2738} 2739 2740int 2741fill_dbregs(struct thread *td, struct dbreg *dbregs) 2742{ 2743 struct pcb *pcb; 2744 2745 if (td == NULL) { 2746 dbregs->dr[0] = rdr0(); 2747 dbregs->dr[1] = rdr1(); 2748 dbregs->dr[2] = rdr2(); 2749 dbregs->dr[3] = rdr3(); 2750 dbregs->dr[4] = rdr4(); 2751 dbregs->dr[5] = rdr5(); 2752 dbregs->dr[6] = rdr6(); 2753 dbregs->dr[7] = rdr7(); 2754 } else { 2755 pcb = td->td_pcb; 2756 dbregs->dr[0] = pcb->pcb_dr0; 2757 dbregs->dr[1] = pcb->pcb_dr1; 2758 dbregs->dr[2] = pcb->pcb_dr2; 2759 dbregs->dr[3] = pcb->pcb_dr3; 2760 dbregs->dr[4] = 0; 2761 dbregs->dr[5] = 0; 2762 dbregs->dr[6] = pcb->pcb_dr6; 2763 dbregs->dr[7] = pcb->pcb_dr7; 2764 } 2765 return (0); 2766} 2767 2768int 2769set_dbregs(struct thread *td, struct dbreg *dbregs) 2770{ 2771 struct pcb *pcb; 2772 int i; 2773 2774 if (td == NULL) { 2775 load_dr0(dbregs->dr[0]); 2776 load_dr1(dbregs->dr[1]); 2777 load_dr2(dbregs->dr[2]); 2778 load_dr3(dbregs->dr[3]); 2779 load_dr4(dbregs->dr[4]); 2780 load_dr5(dbregs->dr[5]); 2781 load_dr6(dbregs->dr[6]); 2782 load_dr7(dbregs->dr[7]); 2783 } else { 2784 /* 2785 * Don't let an illegal value for dr7 get set. Specifically, 2786 * check for undefined settings. Setting these bit patterns 2787 * result in undefined behaviour and can lead to an unexpected 2788 * TRCTRAP. 2789 */ 2790 for (i = 0; i < 4; i++) { 2791 if (DBREG_DR7_ACCESS(dbregs->dr[7], i) == 0x02) 2792 return (EINVAL); 2793 if (DBREG_DR7_LEN(dbregs->dr[7], i) == 0x02) 2794 return (EINVAL); 2795 } 2796 2797 pcb = td->td_pcb; 2798 2799 /* 2800 * Don't let a process set a breakpoint that is not within the 2801 * process's address space. If a process could do this, it 2802 * could halt the system by setting a breakpoint in the kernel 2803 * (if ddb was enabled). Thus, we need to check to make sure 2804 * that no breakpoints are being enabled for addresses outside 2805 * process's address space. 2806 * 2807 * XXX - what about when the watched area of the user's 2808 * address space is written into from within the kernel 2809 * ... wouldn't that still cause a breakpoint to be generated 2810 * from within kernel mode? 2811 */ 2812 2813 if (DBREG_DR7_ENABLED(dbregs->dr[7], 0)) { 2814 /* dr0 is enabled */ 2815 if (dbregs->dr[0] >= VM_MAXUSER_ADDRESS) 2816 return (EINVAL); 2817 } 2818 2819 if (DBREG_DR7_ENABLED(dbregs->dr[7], 1)) { 2820 /* dr1 is enabled */ 2821 if (dbregs->dr[1] >= VM_MAXUSER_ADDRESS) 2822 return (EINVAL); 2823 } 2824 2825 if (DBREG_DR7_ENABLED(dbregs->dr[7], 2)) { 2826 /* dr2 is enabled */ 2827 if (dbregs->dr[2] >= VM_MAXUSER_ADDRESS) 2828 return (EINVAL); 2829 } 2830 2831 if (DBREG_DR7_ENABLED(dbregs->dr[7], 3)) { 2832 /* dr3 is enabled */ 2833 if (dbregs->dr[3] >= VM_MAXUSER_ADDRESS) 2834 return (EINVAL); 2835 } 2836 2837 pcb->pcb_dr0 = dbregs->dr[0]; 2838 pcb->pcb_dr1 = dbregs->dr[1]; 2839 pcb->pcb_dr2 = dbregs->dr[2]; 2840 pcb->pcb_dr3 = dbregs->dr[3]; 2841 pcb->pcb_dr6 = dbregs->dr[6]; 2842 pcb->pcb_dr7 = dbregs->dr[7]; 2843 2844 pcb->pcb_flags |= PCB_DBREGS; 2845 } 2846 2847 return (0); 2848} 2849 2850/* 2851 * Return > 0 if a hardware breakpoint has been hit, and the 2852 * breakpoint was in user space. Return 0, otherwise. 2853 */ 2854int 2855user_dbreg_trap(void) 2856{ 2857 u_int32_t dr7, dr6; /* debug registers dr6 and dr7 */ 2858 u_int32_t bp; /* breakpoint bits extracted from dr6 */ 2859 int nbp; /* number of breakpoints that triggered */ 2860 caddr_t addr[4]; /* breakpoint addresses */ 2861 int i; 2862 2863 dr7 = rdr7(); 2864 if ((dr7 & 0x000000ff) == 0) { 2865 /* 2866 * all GE and LE bits in the dr7 register are zero, 2867 * thus the trap couldn't have been caused by the 2868 * hardware debug registers 2869 */ 2870 return 0; 2871 } 2872 2873 nbp = 0; 2874 dr6 = rdr6(); 2875 bp = dr6 & 0x0000000f; 2876 2877 if (!bp) { 2878 /* 2879 * None of the breakpoint bits are set meaning this 2880 * trap was not caused by any of the debug registers 2881 */ 2882 return 0; 2883 } 2884 2885 /* 2886 * at least one of the breakpoints were hit, check to see 2887 * which ones and if any of them are user space addresses 2888 */ 2889 2890 if (bp & 0x01) { 2891 addr[nbp++] = (caddr_t)rdr0(); 2892 } 2893 if (bp & 0x02) { 2894 addr[nbp++] = (caddr_t)rdr1(); 2895 } 2896 if (bp & 0x04) { 2897 addr[nbp++] = (caddr_t)rdr2(); 2898 } 2899 if (bp & 0x08) { 2900 addr[nbp++] = (caddr_t)rdr3(); 2901 } 2902 2903 for (i = 0; i < nbp; i++) { 2904 if (addr[i] < (caddr_t)VM_MAXUSER_ADDRESS) { 2905 /* 2906 * addr[i] is in user space 2907 */ 2908 return nbp; 2909 } 2910 } 2911 2912 /* 2913 * None of the breakpoints are in user space. 2914 */ 2915 return 0; 2916} 2917 2918#ifndef DEV_APIC 2919#include <machine/apicvar.h> 2920 2921/* 2922 * Provide stub functions so that the MADT APIC enumerator in the acpi 2923 * kernel module will link against a kernel without 'device apic'. 2924 * 2925 * XXX - This is a gross hack. 2926 */ 2927void 2928apic_register_enumerator(struct apic_enumerator *enumerator) 2929{ 2930} 2931 2932void * 2933ioapic_create(uintptr_t addr, int32_t id, int intbase) 2934{ 2935 return (NULL); 2936} 2937 2938int 2939ioapic_disable_pin(void *cookie, u_int pin) 2940{ 2941 return (ENXIO); 2942} 2943 2944int 2945ioapic_get_vector(void *cookie, u_int pin) 2946{ 2947 return (-1); 2948} 2949 2950void 2951ioapic_register(void *cookie) 2952{ 2953} 2954 2955int 2956ioapic_remap_vector(void *cookie, u_int pin, int vector) 2957{ 2958 return (ENXIO); 2959} 2960 2961int 2962ioapic_set_extint(void *cookie, u_int pin) 2963{ 2964 return (ENXIO); 2965} 2966 2967int 2968ioapic_set_nmi(void *cookie, u_int pin) 2969{ 2970 return (ENXIO); 2971} 2972 2973int 2974ioapic_set_polarity(void *cookie, u_int pin, enum intr_polarity pol) 2975{ 2976 return (ENXIO); 2977} 2978 2979int 2980ioapic_set_triggermode(void *cookie, u_int pin, enum intr_trigger trigger) 2981{ 2982 return (ENXIO); 2983} 2984 2985void 2986lapic_create(u_int apic_id, int boot_cpu) 2987{ 2988} 2989 2990void 2991lapic_init(uintptr_t addr) 2992{ 2993} 2994 2995int 2996lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode) 2997{ 2998 return (ENXIO); 2999} 3000 3001int 3002lapic_set_lvt_polarity(u_int apic_id, u_int lvt, enum intr_polarity pol) 3003{ 3004 return (ENXIO); 3005} 3006 3007int 3008lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, enum intr_trigger trigger) 3009{ 3010 return (ENXIO); 3011} 3012#endif 3013 3014#ifdef KDB 3015 3016/* 3017 * Provide inb() and outb() as functions. They are normally only 3018 * available as macros calling inlined functions, thus cannot be 3019 * called from the debugger. 3020 * 3021 * The actual code is stolen from <machine/cpufunc.h>, and de-inlined. 3022 */ 3023 3024#undef inb 3025#undef outb 3026 3027/* silence compiler warnings */ 3028u_char inb(u_int); 3029void outb(u_int, u_char); 3030 3031u_char 3032inb(u_int port) 3033{ 3034 u_char data; 3035 /* 3036 * We use %%dx and not %1 here because i/o is done at %dx and not at 3037 * %edx, while gcc generates inferior code (movw instead of movl) 3038 * if we tell it to load (u_short) port. 3039 */ 3040 __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port)); 3041 return (data); 3042} 3043 3044void 3045outb(u_int port, u_char data) 3046{ 3047 u_char al; 3048 /* 3049 * Use an unnecessary assignment to help gcc's register allocator. 3050 * This make a large difference for gcc-1.40 and a tiny difference 3051 * for gcc-2.6.0. For gcc-1.40, al had to be ``asm("ax")'' for 3052 * best results. gcc-2.6.0 can't handle this. 3053 */ 3054 al = data; 3055 __asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port)); 3056} 3057 3058#endif /* KDB */ 3059